From 04378cf03492449de6301c72c9f86fb7d3b68c2f Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sun, 21 Sep 2025 12:54:45 -0400 Subject: kern: ahci: Ensure HBA is in AHCI-mode after reset The global host control register (described by section 3.1.2 in the AHCI spec) has an HBA reset bit which resets *everything* to a known state. This means that after the reset, we'll have to indicate to the HBA that we want to speak to it over the AHCI interface. We do it once before the reset if needed, then we do it again after. Signed-off-by: Ian Moffett --- src/sys/io/ic/ahci.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/sys/io/ic/ahci.c b/src/sys/io/ic/ahci.c index 3d0e890..4bec02d 100644 --- a/src/sys/io/ic/ahci.c +++ b/src/sys/io/ic/ahci.c @@ -109,8 +109,17 @@ ahci_hba_reset(struct ahci_hba *hba) uint32_t ghc; int error; - /* Begin the reset */ + /* + * The HBA must be in an AHCI aware state before + * we can follow through with a reset + */ ghc = mmio_read32(&io->ghc); + if (!ISSET(ghc, AHCI_GHC_AE)) { + ghc |= AHCI_GHC_AE; + mmio_write32(&io->ghc, ghc); + } + + /* Now perform the actual reset */ ghc |= AHCI_GHC_HR; mmio_write32(&io->ghc, ghc); @@ -135,11 +144,6 @@ ahci_hba_init(struct ahci_hba *hba) uint32_t ghc; int error; - /* Ensure the host controller is AHCI aware */ - ghc = mmio_read32(&io->ghc); - ghc |= AHCI_GHC_AE; - mmio_write32(&io->ghc, ghc); - /* * We cannot be so certain what state the BIOS or whatever * firmware left the host controller in, therefore the HBA @@ -148,6 +152,17 @@ ahci_hba_init(struct ahci_hba *hba) if ((error = ahci_hba_reset(hba)) < 0) { return error; } + + /* + * Make the HBA AHCI aware, we do this after the reset + * as the reset logic ensures of this before continuing. + * + * We simply do it twice as the reset value is zero and we + * want to ensure it is still AHCI aware after this. + */ + ghc = mmio_read32(&io->ghc); + ghc |= AHCI_GHC_AE; + mmio_write32(&io->ghc, ghc); return 0; } -- cgit v1.2.3