This ensures that we safely receive the IRQ even if the floppy controller
manages to be faster than our code and sends the IRQ before our code enters
floppy_wait_irq(). Although unlikely, this is possible to happen on emulators
(which emulate floppy operations extremely fast) as well as real hardware
(during reset).

Signed-off-by: Nikolay Nikolov <[email protected]>
---
 src/hw/floppy.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/hw/floppy.c b/src/hw/floppy.c
index 1120d63..c85615b 100644
--- a/src/hw/floppy.c
+++ b/src/hw/floppy.c
@@ -230,7 +230,6 @@ floppy_clear_irq_flag(void)
 static int
 floppy_wait_irq(void)
 {
-    floppy_clear_irq_flag();
     u8 frs;
     u32 end = timer_calc(FLOPPY_IRQ_TIMEOUT);
     for (;;) {
@@ -267,6 +266,9 @@ static int
 floppy_pio(int command, u8 *param)
 {
     dprintf(9, "Floppy pio command %x\n", command);
+    // Clear the IRQ flag before issuing the command.
+    if (command & FCF_WAITIRQ)
+        floppy_clear_irq_flag();
     // Send command and parameters to controller.
     u32 end = timer_calc(FLOPPY_PIO_TIMEOUT);
     int send = (command >> 8) & 0xf;
@@ -341,6 +343,8 @@ floppy_enable_controller(void)
     floppy_dor_mask(FLOPPY_DOR_RESET, FLOPPY_DOR_IRQ);
     // Real hardware needs a 4 microsecond delay
     usleep(4);
+    // Clear the IRQ flag right before leaving the reset state.
+    floppy_clear_irq_flag();
     // Set the reset bit (normal operation) and keep 'enable IRQ and DMA' on
     floppy_dor_mask(0, FLOPPY_DOR_IRQ | FLOPPY_DOR_RESET);
     int ret = floppy_wait_irq();
-- 
2.14.3


_______________________________________________
SeaBIOS mailing list
[email protected]
https://mail.coreboot.org/mailman/listinfo/seabios

Reply via email to