From 37ec117abc74dcbcdd349030b135ad1c3601b7e2 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Tue, 10 Mar 2026 21:56:48 +0100 Subject: [PATCH] Better PCI IDE init with fallback to IO bars --- kernel/device/pci.h | 38 ++++++++++++++++++++----------- kernel/device/pci_ide.c | 50 +++++++++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/kernel/device/pci.h b/kernel/device/pci.h index 3950171..a8bc7b2 100644 --- a/kernel/device/pci.h +++ b/kernel/device/pci.h @@ -7,19 +7,31 @@ #define PCI_CONFIG_ADDR 0xCF8 #define PCI_CONFIG_DATA 0xCFC -#define PCI_VENDOR_ID 0x00 -#define PCI_DEVICE_ID 0x02 -#define PCI_COMMAND 0x04 -#define PCI_STATUS 0x06 -#define PCI_REVISION_ID 0x08 -#define PCI_PROG_IF 0x09 -#define PCI_SUBCLASS 0x0A -#define PCI_CLASS 0x0B -#define PCI_CACHELINE 0x0C -#define PCI_LATENCY 0x0D -#define PCI_HEADER_TYPE 0x0E -#define PCI_BIST 0x0F -#define PCI_BAR0 0x10 +#define PCI_VENDOR_ID 0x00 +#define PCI_DEVICE_ID 0x02 +#define PCI_COMMAND 0x04 +#define PCI_STATUS 0x06 +#define PCI_REVISION_ID 0x08 +#define PCI_PROG_IF 0x09 +#define PCI_SUBCLASS 0x0A +#define PCI_CLASS 0x0B +#define PCI_CACHELINE 0x0C +#define PCI_LATENCY 0x0D +#define PCI_HEADER_TYPE 0x0E +#define PCI_BIST 0x0F +#define PCI_BAR0 0x10 +#define PCI_BAR1 0x14 +#define PCI_BAR2 0x18 +#define PCI_BAR3 0x1C +#define PCI_BAR4 0x20 +#define PCI_BAR5 0x24 +#define PCI_INTERRUPT 0x3C +#define PCI_SECONDARY_BUS 0x09 + +#define PCI_BAR_IO 0x01 +#define PCI_BAR_MEM32 0x02 +#define PCI_BAR_MEM64 0x04 +#define PCI_BAR_PREFETCH 0x08 struct pci_vendor { uint16_t id; diff --git a/kernel/device/pci_ide.c b/kernel/device/pci_ide.c index 10b6cb4..5b417e7 100644 --- a/kernel/device/pci_ide.c +++ b/kernel/device/pci_ide.c @@ -57,35 +57,47 @@ bool pci_ide_init (struct pci_info pci_info) { struct ide_probe probe; uint8_t progif = pci_read8 (pci_info.bus, pci_info.slot, pci_info.func, PCI_PROG_IF); - DEBUG ("progif: %s\n", progif_msg[progif]); - switch (progif) { - case 0x80: - ide_probe (0x1F0, 0x3F6, 0, &probe); + uint16_t pcmd, pctrl, scmd, sctrl; - if ((probe.flags & IDE_PROBE_AVAIL)) - ide_make_device (probe); + if ((progif & 0x01)) { + pcmd = (uint16_t)(pci_read32 (pci_info.bus, pci_info.slot, pci_info.func, PCI_BAR0) & 0xFFFC); + pctrl = (uint16_t)(pci_read32 (pci_info.bus, pci_info.slot, pci_info.func, PCI_BAR1) & 0xFFFC); - ide_probe (0x1F0, 0x3F6, 1, &probe); + if (pctrl) + pctrl += 2; + } else { + pcmd = 0x1F0; + pctrl = 0x3F6; + } - if ((probe.flags & IDE_PROBE_AVAIL)) - ide_make_device (probe); + if ((progif & 0x04)) { + scmd = (uint16_t)(pci_read32 (pci_info.bus, pci_info.slot, pci_info.func, PCI_BAR2) & 0xFFFC); + sctrl = (uint16_t)(pci_read32 (pci_info.bus, pci_info.slot, pci_info.func, PCI_BAR3) & 0xFFFC); - ide_probe (0x170, 0x376, 0, &probe); + if (sctrl) + sctrl += 2; + } else { + scmd = 0x170; + sctrl = 0x376; + } - if ((probe.flags & IDE_PROBE_AVAIL)) - ide_make_device (probe); + uint16_t channels[2][2] = {{pcmd, pctrl}, {scmd, sctrl}}; - ide_probe (0x170, 0x376, 1, &probe); + for (size_t i = 0; i < lengthof (channels); i++) { + uint16_t cmd = channels[i][0]; + uint16_t ctrl = channels[i][1]; - if ((probe.flags & IDE_PROBE_AVAIL)) - ide_make_device (probe); + if (cmd == 0) + continue; - break; - default: - DEBUG ("PCI unsupported progif=%02x\n", progif); - return false; + for (size_t dev = 0; dev < 2; dev++) { + ide_probe (cmd, ctrl, dev, &probe); + + if ((probe.flags & IDE_PROBE_AVAIL)) + ide_make_device (probe); + } } return true;