summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorCaelus <neptune@osmora.org>2025-02-19 16:03:44 +0000
committerIan Moffett <ian@osmora.org>2025-02-19 13:25:28 -0500
commit370903704167c779e4cc9043e947c2d14f37bad4 (patch)
treedd029efe4ba05fbed28cc24d687179641d09a730 /sys/dev/ic
parent48b350afdf0cb19a7b2c227ae68713090f1e2c8e (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/ic')
-rw-r--r--sys/dev/ic/ahci.c44
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;
}