From ecfe1a7eae0ca9177aca104398e6838e1025af21 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Tue, 18 Nov 2025 23:28:45 +0100 Subject: [PATCH] Detect ATA driver via PCI --- kernel/kmain.c | 2 +- kernel/pci/ide.c | 44 +++++++++++++++++++++++++++ kernel/pci/ide.h | 8 +++++ kernel/pci/pci.c | 5 ++-- kernel/pci/pci.h | 1 + kernel/storedev/atasd.c | 61 -------------------------------------- kernel/storedev/atasd.h | 3 +- kernel/storedev/storedev.c | 2 -- 8 files changed, 58 insertions(+), 68 deletions(-) create mode 100644 kernel/pci/ide.c create mode 100644 kernel/pci/ide.h diff --git a/kernel/kmain.c b/kernel/kmain.c index 18b65d7..df7bac3 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -49,11 +49,11 @@ void kmain(void) { pmm_init(); vmm_init(); intr_init(); - pci_init(); randcrypto_init(); ipc_mbusinit(); dev_init(); storedev_init(); + pci_init(); diskpart_init(); baseimg_init(); vfs_init(); diff --git a/kernel/pci/ide.c b/kernel/pci/ide.c new file mode 100644 index 0000000..8c4ab99 --- /dev/null +++ b/kernel/pci/ide.c @@ -0,0 +1,44 @@ +#include +#include +#include "pci/pci.h" +#include "pci/ide.h" +#include "storedev/atasd.h" +#include "storedev/storedev.h" +#include "util/util.h" +#include "kprintf.h" + +#define ATA_MASTER 0x00 +#define ATA_SLAVE 0x01 + +#define ATA_PROBE(STRING, IOBASE, CTRLBASE, S_OR_M) \ + ps = ata_probesize_bytes((IOBASE), (CTRLBASE), (S_OR_M)); \ + if (ps > 0) { \ + AtaSdInitExtra extra = { \ + .devno = (S_OR_M), \ + .capacity = ps, \ + .iobase = (IOBASE), \ + .ctrlbase = (CTRLBASE), \ + }; \ + storedev_create(STOREDEV_ATASD, (STRING), (void *)&extra); \ + } + +void pci_ide_init(PciDevInfo *devinfo) { + LOG("pci", "init ATA drive\n"); + + uint16_t iobase, ctrlbase; + uint64_t ps; + + if (!(devinfo->progintf & 0x1)) { + iobase = 0x1F0; + ctrlbase = 0x3F6; + } + ATA_PROBE("atasd0m", iobase, ctrlbase, ATA_MASTER) + ATA_PROBE("atasd0s", iobase, ctrlbase, ATA_SLAVE) + + if (!(devinfo->progintf & 0x4)) { + iobase = 0x170; + ctrlbase = 0x376; + } + ATA_PROBE("atasd1m", iobase, ctrlbase, ATA_MASTER) + ATA_PROBE("atasd1s", iobase, ctrlbase, ATA_SLAVE) +} diff --git a/kernel/pci/ide.h b/kernel/pci/ide.h new file mode 100644 index 0000000..db13f9c --- /dev/null +++ b/kernel/pci/ide.h @@ -0,0 +1,8 @@ +#ifndef PCI_IDE_H_ +#define PCI_IDE_H_ + +#include "pci/pci.h" + +void pci_ide_init(PciDevInfo *devinfo); + +#endif // PCI_IDE_H_ diff --git a/kernel/pci/pci.c b/kernel/pci/pci.c index d851c11..39b794a 100644 --- a/kernel/pci/pci.c +++ b/kernel/pci/pci.c @@ -5,6 +5,7 @@ #include "io/io.h" #include "std/string.h" #include "util/util.h" +#include "pci/ide.h" #include "kprintf.h" uint8_t pci_read8(uint32_t id, uint32_t reg) { @@ -76,6 +77,7 @@ void pci_getbar(PciBar *bar, uint32_t id, uint32_t idx) { } static PciMatch PCI_MATCHES[] = { + { 0x8086, 0x7010, &pci_ide_init }, }; void pci_visit(uint32_t bus, uint32_t dev, uint32_t fn) { @@ -103,8 +105,7 @@ void pci_visit(uint32_t bus, uint32_t dev, uint32_t fn) { pci_classname(devinfo.classcode, devinfo.subclass, devinfo.progintf)); for (size_t i = 0; i < LEN(PCI_MATCHES); i++) { - if ((PCI_MATCHES[i].k1 == devinfo.vendorid && PCI_MATCHES[i].k2 == devinfo.deviceid) - || (PCI_MATCHES[i].k1 == devinfo.classcode && PCI_MATCHES[i].k2 == devinfo.subclass)) { + if (PCI_MATCHES[i].k1 == devinfo.vendorid && PCI_MATCHES[i].k2 == devinfo.deviceid) { PCI_MATCHES[i].initfn(&devinfo); } } diff --git a/kernel/pci/pci.h b/kernel/pci/pci.h index 1393859..0f58180 100644 --- a/kernel/pci/pci.h +++ b/kernel/pci/pci.h @@ -82,6 +82,7 @@ uint32_t pci_read32(uint32_t id, uint32_t reg); void pci_write8(uint32_t id, uint32_t reg, uint8_t v); void pci_write16(uint32_t id, uint32_t reg, uint16_t v); void pci_write32(uint32_t id, uint32_t reg, uint32_t v); +void pci_getbar(PciBar *bar, uint32_t id, uint32_t idx); void pci_init(void); diff --git a/kernel/storedev/atasd.c b/kernel/storedev/atasd.c index 24c1489..6134866 100644 --- a/kernel/storedev/atasd.c +++ b/kernel/storedev/atasd.c @@ -106,67 +106,6 @@ uint64_t ata_probesize_bytes(uint16_t iobase, uint16_t ctrlbase, int devno) { } } -void ata_probe(void) { - uint64_t probesize; - - probesize = ata_probesize_bytes(0x1F0, 0x3F6, ATA_MASTER); - if (probesize > 0) { - - char hs[20]; - LOG("ata", "found ATA primary bus master, size = %s\n", human_size(probesize, hs, sizeof(hs))); - - AtaSdInitExtra extra = { - .devno = ATA_MASTER, - .capacity = probesize, - .iobase = 0x1F0, - .ctrlbase = 0x3F6, - }; - storedev_create(STOREDEV_ATASD, "atasd0m", (void *)&extra); - } - - probesize = ata_probesize_bytes(0x1F0, 0x3F6, ATA_SLAVE); - if (probesize > 0) { - char hs[20]; - LOG("ata", "found ATA primary bus slave, size = %s\n", human_size(probesize, hs, sizeof(hs))); - - AtaSdInitExtra extra = { - .devno = ATA_SLAVE, - .capacity = probesize, - .iobase = 0x1F0, - .ctrlbase = 0x3F6, - }; - storedev_create(STOREDEV_ATASD, "atasd0s", (void *)&extra); - } - - probesize = ata_probesize_bytes(0x170, 0x376, ATA_MASTER); - if (probesize > 0) { - char hs[20]; - LOG("ata", "found ATA secondary bus master, size = %s\n", human_size(probesize, hs, sizeof(hs))); - - AtaSdInitExtra extra = { - .devno = ATA_MASTER, - .capacity = probesize, - .iobase = 0x170, - .ctrlbase = 0x376, - }; - storedev_create(STOREDEV_ATASD, "atasd1m", (void *)&extra); - } - - probesize = ata_probesize_bytes(0x170, 0x376, ATA_SLAVE); - if (probesize > 0) { - char hs[20]; - LOG("ata", "found ATA secondary bus slave, size = %s\n", human_size(probesize, hs, sizeof(hs))); - - AtaSdInitExtra extra = { - .devno = ATA_SLAVE, - .capacity = probesize, - .iobase = 0x170, - .ctrlbase = 0x376, - }; - storedev_create(STOREDEV_ATASD, "atasd1s", (void *)&extra); - } -} - void ata_setup(uint16_t iobase, uint16_t ctrlbase, int devno, uint16_t sectors, uint64_t lba) { io_out8(ctrlbase, 0x02); diff --git a/kernel/storedev/atasd.h b/kernel/storedev/atasd.h index 864c6e5..6052991 100644 --- a/kernel/storedev/atasd.h +++ b/kernel/storedev/atasd.h @@ -28,7 +28,6 @@ int32_t atasd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, int32_t atasd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size); int32_t atasd_cleanup(struct StoreDev *sd); size_t atasd_capacity(struct StoreDev *sd); - -void ata_probe(void); +uint64_t ata_probesize_bytes(uint16_t iobase, uint16_t ctrlbase, int devno); #endif // STOREDEV_ATASD_H_ diff --git a/kernel/storedev/storedev.c b/kernel/storedev/storedev.c index f9284b7..ddaf124 100644 --- a/kernel/storedev/storedev.c +++ b/kernel/storedev/storedev.c @@ -21,8 +21,6 @@ void storedev_init(void) { STOREDEV_LIST.head = NULL; LOG("storedev", "init\n"); - - ata_probe(); } int32_t storedev_dev_read(Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) {