diff options
author | Caelus <neptune@osmora.org> | 2025-02-19 16:03:44 +0000 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-02-19 13:25:28 -0500 |
commit | 370903704167c779e4cc9043e947c2d14f37bad4 (patch) | |
tree | dd029efe4ba05fbed28cc24d687179641d09a730 /sys/dev | |
parent | 48b350afdf0cb19a7b2c227ae68713090f1e2c8e (diff) |
kernel: ahci: Map ABAR and perform HBA reset
Signed-off-by: Ian Moffett <ian@osmora.org>
Signed-off-by: Caelus <neptune@osmora.org>
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/ahci.c | 44 |
1 files changed, 44 insertions, 0 deletions
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 <sys/errno.h> #include <sys/syslog.h> #include <dev/pci/pci.h> +#include <dev/ic/ahcivar.h> +#include <sys/mmio.h> #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; } |