From 370903704167c779e4cc9043e947c2d14f37bad4 Mon Sep 17 00:00:00 2001 From: Caelus Date: Wed, 19 Feb 2025 16:03:44 +0000 Subject: kernel: ahci: Map ABAR and perform HBA reset Signed-off-by: Ian Moffett Signed-off-by: Caelus --- sys/dev/ic/ahci.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'sys/dev/ic/ahci.c') diff --git a/sys/dev/ic/ahci.c b/sys/dev/ic/ahci.c index d3d303b..bafa872 100644 --- a/sys/dev/ic/ahci.c +++ b/sys/dev/ic/ahci.c @@ -32,16 +32,41 @@ #include #include #include +#include +#include #define pr_trace(fmt, ...) kprintf("ahci: " fmt, ##__VA_ARGS__) #define pr_error(...) pr_trace(__VA_ARGS__) static struct pci_device *ahci_dev; +/* + * Poll for at most 1 second, to see if GHC.HR is 0. + * + * @memspace: A pointer the HBA MMIO space. + */ +static int +poll_ghc_hr(struct hba_memspace *memspace) +{ + int count; + + for (count = 0; count < 10000000; count++) { + if ((mmio_read32(&(memspace->ghc)) & 1) == 0) { + return 0; + } + } + + return 1; +} + static int ahci_init(void) { struct pci_lookup lookup; + int status; + struct ahci_hba hba; + + void *abar_vap = NULL; lookup.pci_class = 0x01; lookup.pci_subclass = 0x06; @@ -60,6 +85,25 @@ ahci_init(void) ahci_dev->bus, ahci_dev->device_id, ahci_dev->func, ahci_dev->slot); + /* + * Map the AHCI Base Address Register (ABAR) from the + * ahci_dev struct, so that we can perform MMIO and then issue + * a hard reset. + */ + + if ((status = pci_map_bar(ahci_dev, 5, &abar_vap)) != 0) { + return status; + } + + hba.io = (struct hba_memspace*) abar_vap; + mmio_write32(&(hba.io->ghc), mmio_read32(&(hba.io->ghc)) | 1); + + if (poll_ghc_hr(hba.io) != 0) { + return 1; + } + + pr_trace("Successfully performed a hard reset.\n"); + return 0; } -- cgit v1.2.3