Support ISA ATA devices for qemu's "-M isapc" mode.
authorKevin O'Connor <kevin@koconnor.net>
Sat, 5 Dec 2009 16:25:09 +0000 (11:25 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 5 Dec 2009 16:25:09 +0000 (11:25 -0500)
Add probing for ISA ATA devices when no pci devices found.
Also, add defines for common ATA ports.
Also, make sure irq and pci_bdf are defined for both pci ata controllers.

src/ata.c
src/ata.h
src/disk.c
src/ioport.h
src/pciinit.c

index 94538303191ab29b80e1c34269cca7299e0ef69e..cf54d0f305aee376107ab85c6a8d420023c79314 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -753,53 +753,64 @@ ata_detect(void *data)
     }
 }
 
+static void
+init_controller(struct ata_channel_s *atachannel
+                , int bdf, int irq, u32 port1, u32 port2)
+{
+    SET_GLOBAL(atachannel->irq, irq);
+    SET_GLOBAL(atachannel->pci_bdf, bdf);
+    SET_GLOBAL(atachannel->iobase1, port1);
+    SET_GLOBAL(atachannel->iobase2, port2);
+    dprintf(1, "ATA controller %d at %x/%x (irq %d dev %x)\n"
+            , atachannel - ATA_channels, port1, port2, irq, bdf);
+    run_thread(ata_detect, atachannel);
+}
+
 static void
 ata_init()
 {
     // Scan PCI bus for ATA adapters
-    int count=0;
+    int count=0, pcicount=0;
     int bdf, max;
     foreachpci(bdf, max) {
+        pcicount++;
         if (pci_config_readw(bdf, PCI_CLASS_DEVICE) != PCI_CLASS_STORAGE_IDE)
             continue;
         if (count >= ARRAY_SIZE(ATA_channels))
             break;
 
         u8 irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
-        SET_GLOBAL(ATA_channels[count].irq, irq);
-        SET_GLOBAL(ATA_channels[count].pci_bdf, bdf);
-
         u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
         u32 port1, port2;
-
         if (prog_if & 1) {
             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_0) & ~3;
             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_1) & ~3;
         } else {
-            port1 = 0x1f0;
-            port2 = 0x3f0;
+            port1 = PORT_ATA1_CMD_BASE;
+            port2 = PORT_ATA1_CTRL_BASE;
         }
-        SET_GLOBAL(ATA_channels[count].iobase1, port1);
-        SET_GLOBAL(ATA_channels[count].iobase2, port2);
-        dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n"
-                , count, port1, port2, bdf, prog_if);
-        run_thread(ata_detect, &ATA_channels[count]);
+        init_controller(&ATA_channels[count], bdf, irq, port1, port2);
         count++;
 
         if (prog_if & 4) {
             port1 = pci_config_readl(bdf, PCI_BASE_ADDRESS_2) & ~3;
             port2 = pci_config_readl(bdf, PCI_BASE_ADDRESS_3) & ~3;
         } else {
-            port1 = 0x170;
-            port2 = 0x370;
+            port1 = PORT_ATA2_CMD_BASE;
+            port2 = PORT_ATA2_CTRL_BASE;
         }
-        dprintf(1, "ATA controller %d at %x/%x (dev %x prog_if %x)\n"
-                , count, port1, port2, bdf, prog_if);
-        SET_GLOBAL(ATA_channels[count].iobase1, port1);
-        SET_GLOBAL(ATA_channels[count].iobase2, port2);
-        run_thread(ata_detect, &ATA_channels[count]);
+        init_controller(&ATA_channels[count], bdf, irq, port1, port2);
         count++;
     }
+
+    if (!CONFIG_COREBOOT && !pcicount && ARRAY_SIZE(ATA_channels) >= 2) {
+        // No PCI devices found - probably a QEMU "-M isapc" machine.
+        // Try using ISA ports for ATA controllers.
+        init_controller(&ATA_channels[0]
+                        , -1, 14, PORT_ATA1_CMD_BASE, PORT_ATA1_CTRL_BASE);
+        init_controller(&ATA_channels[1]
+                        , -1, 15, PORT_ATA2_CMD_BASE, PORT_ATA2_CTRL_BASE);
+    }
 }
 
 void
index 65d67b0b4282ecf9db2a1159c3ced84e53e63f38..406c284363430e5ec490c43f4d65839060962548 100644 (file)
--- a/src/ata.h
+++ b/src/ata.h
@@ -5,10 +5,10 @@
 #include "config.h" // CONFIG_MAX_ATA_INTERFACES
 
 struct ata_channel_s {
-    u16 iobase1;      // IO Base 1
-    u16 iobase2;      // IO Base 2
-    u16 pci_bdf;
-    u8  irq;          // IRQ
+    u16 iobase1;
+    u16 iobase2;
+    u8  irq;
+    int pci_bdf;
 };
 
 // ata.c
index 30b6e7be9bc1d236dca6df5ec84ebc5cfb32c0ab..ef4866f99d7dc0fa9cb90c9caec204edb39782b9 100644 (file)
@@ -602,15 +602,25 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
     SET_INT13DPT(regs, reserved1, 0);
     SET_INT13DPT(regs, reserved2, 0);
 
-    SET_INT13DPT(regs, host_bus[0], 'P');
-    SET_INT13DPT(regs, host_bus[1], 'C');
-    SET_INT13DPT(regs, host_bus[2], 'I');
-    SET_INT13DPT(regs, host_bus[3], 0);
-
-    u32 bdf = GET_GLOBAL(ATA_channels[channel].pci_bdf);
-    u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8)
-                | (pci_bdf_to_fn(bdf) << 16));
-    SET_INT13DPT(regs, iface_path, path);
+    int bdf = GET_GLOBAL(ATA_channels[channel].pci_bdf);
+    if (bdf != -1) {
+        SET_INT13DPT(regs, host_bus[0], 'P');
+        SET_INT13DPT(regs, host_bus[1], 'C');
+        SET_INT13DPT(regs, host_bus[2], 'I');
+        SET_INT13DPT(regs, host_bus[3], 0);
+
+        u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8)
+                    | (pci_bdf_to_fn(bdf) << 16));
+        SET_INT13DPT(regs, iface_path, path);
+    } else {
+        // ISA
+        SET_INT13DPT(regs, host_bus[0], 'I');
+        SET_INT13DPT(regs, host_bus[1], 'S');
+        SET_INT13DPT(regs, host_bus[2], 'A');
+        SET_INT13DPT(regs, host_bus[3], 0);
+
+        SET_INT13DPT(regs, iface_path, iobase1);
+    }
 
     SET_INT13DPT(regs, iface_type[0], 'A');
     SET_INT13DPT(regs, iface_type[1], 'T');
index f22b665635bea7ddc1869e184902887d3930b9f7..f31e377b6177df996073f2291d8ba29c48c4499c 100644 (file)
 #define PORT_DMA2_MODE_REG     0x00d6
 #define PORT_DMA2_MASTER_CLEAR 0x00da
 #define PORT_MATH_CLEAR        0x00f0
+#define PORT_ATA2_CMD_BASE     0x0170
+#define PORT_ATA1_CMD_BASE     0x01f0
 #define PORT_LPT2              0x0278
 #define PORT_SERIAL4           0x02e8
 #define PORT_SERIAL2           0x02f8
+#define PORT_ATA2_CTRL_BASE    0x0370
 #define PORT_LPT1              0x0378
 #define PORT_SERIAL3           0x03e8
+#define PORT_ATA1_CTRL_BASE    0x03f0
 #define PORT_FD_DOR            0x03f2
 #define PORT_FD_STATUS         0x03f4
 #define PORT_FD_DATA           0x03f5
index fe7575c62deac5ab5cc31dc553b6a75fc1ddeb7a..9fa2c6b6c606c97d406763d54b72ffd09878771c 100644 (file)
@@ -98,10 +98,10 @@ static void pci_bios_init_device(u16 bdf)
             goto default_map;
         } else {
             /* IDE: we map it as in ISA mode */
-            pci_set_io_region_addr(bdf, 0, 0x1f0);
-            pci_set_io_region_addr(bdf, 1, 0x3f4);
-            pci_set_io_region_addr(bdf, 2, 0x170);
-            pci_set_io_region_addr(bdf, 3, 0x374);
+            pci_set_io_region_addr(bdf, 0, PORT_ATA1_CMD_BASE);
+            pci_set_io_region_addr(bdf, 1, PORT_ATA1_CTRL_BASE + 4);
+            pci_set_io_region_addr(bdf, 2, PORT_ATA2_CMD_BASE);
+            pci_set_io_region_addr(bdf, 3, PORT_ATA2_CTRL_BASE + 4);
         }
         break;
     case PCI_CLASS_SYSTEM_PIC: