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.
}
}
+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
#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
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');
#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
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: