From af2b981c4cc6f8e4b7050f0401dc225606836ca0 Mon Sep 17 00:00:00 2001 From: Minep Date: Wed, 29 Jun 2022 00:15:35 +0100 Subject: [PATCH] feat: AHCI probing --- lunaix-os/hal/ahci.c | 55 ++++++++++++++++++++++++++++ lunaix-os/hal/pci.c | 11 ++++++ lunaix-os/includes/hal/ahci.h | 46 ++++++++++++++++++++++- lunaix-os/kernel/demos/signal_demo.c | 4 -- lunaix-os/kernel/mm/kalloc.c | 1 - lunaix-os/kernel/proc0.c | 2 + 6 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 lunaix-os/hal/ahci.c diff --git a/lunaix-os/hal/ahci.c b/lunaix-os/hal/ahci.c new file mode 100644 index 0000000..fa87fd3 --- /dev/null +++ b/lunaix-os/hal/ahci.c @@ -0,0 +1,55 @@ +/** + * @file ahci.c + * @author Lunaixsky (zelong56@gmail.com) + * @brief A software implementation of Serial ATA AHCI 1.3.1 Specification + * @version 0.1 + * @date 2022-06-28 + * + * @copyright Copyright (c) 2022 + * + */ +#include +#include +#include +#include +#include + +LOG_MODULE("AHCI") + +static struct ahci_hba hba; + +void +ahci_init() +{ + struct pci_device* ahci_dev = pci_get_device_by_class(0x10601); + assert_msg(ahci_dev, "AHCI: Not found."); + + uintptr_t bar6, size; + size = pci_bar_sizing(ahci_dev, &bar6, 6); + assert_msg(bar6 && PCI_BAR_MMIO(bar6), "AHCI: BAR#6 is not MMIO."); + + hba.base = (hba_reg_t*)ioremap(PCI_BAR_ADDR_MM(bar6), size); + + // Enable AHCI, Enable interrupt generation. + hba.base[HBA_RGHC] |= 0x80000002; + + // As per section 3.1.1, this is 0 based value. + hba.ports_num = (hba.base[HBA_RCAP] & 0x1f) + 1; + hba.version = hba.base[HBA_RVER]; + + kprintf(KINFO "Version: %x; Ports: %d\n", hba.version, hba.ports_num); + + hba_reg_t pmap = hba.base[HBA_RPI]; + for (size_t i = 0; i < 32; i++, pmap = pmap >> 1) { + if (!(pmap & 0x1)) { + continue; + } + hba.ports[i] = (hba_reg_t*)(&hba.base[HBA_RPBASE] + i); + kprintf("\t Port#%d, clb: %p, fis: %p\n", + i + 1, + hba.ports[i][HBA_RPxCLB], + hba.ports[i][HBA_RPxFB]); + + // TODO: (?) Rebasing each port's command list and FIS + } +} \ No newline at end of file diff --git a/lunaix-os/hal/pci.c b/lunaix-os/hal/pci.c index 32299cd..c3771d5 100644 --- a/lunaix-os/hal/pci.c +++ b/lunaix-os/hal/pci.c @@ -1,3 +1,13 @@ +/** + * @file pci.c + * @author Lunaixsky (zelong56@gmail.com) + * @brief A software implementation of PCI Local Bus Specification Revision 3.0 + * @version 0.1 + * @date 2022-06-28 + * + * @copyright Copyright (c) 2022 + * + */ #include #include #include @@ -156,6 +166,7 @@ pci_bar_sizing(struct pci_device* dev, uint32_t* bar_out, uint32_t bar_num) sized = PCI_BAR_ADDR_MM(sized); } *bar_out = bar; + pci_write_cspace(dev->cspace_base, PCI_REG_BAR(bar_num), bar); return ~sized + 1; } diff --git a/lunaix-os/includes/hal/ahci.h b/lunaix-os/includes/hal/ahci.h index fc457eb..438fa5c 100644 --- a/lunaix-os/includes/hal/ahci.h +++ b/lunaix-os/includes/hal/ahci.h @@ -1,5 +1,49 @@ #ifndef __LUNAIX_AHCI_H #define __LUNAIX_AHCI_H -// TODO: AHCI Drivers + +/* + * Macro naming rule: + * HBA_R[xxx] + * HBA Register [xxx] + * e.g. HBA_RPxCLB is Register PxCLB + * + * All registers offset are 0 based index of a DWORD array + */ + +#define HBA_RCAP 0 +#define HBA_RGHC 1 +#define HBA_RIS 2 +#define HBA_RPI 3 +#define HBA_RVER 4 + +#define HBA_RPBASE (0x40) +#define HBA_RPxCLB 0 +#define HBA_RPxFB 2 +#define HBA_RPxIS 4 +#define HBA_RPxIE 5 +#define HBA_RPxCMD 6 +#define HBA_RPxTFD 8 +#define HBA_RPxSIG 9 +#define HBA_RPxSSTS 10 +#define HBA_RPxSCTL 11 +#define HBA_RPxSERR 12 +#define HBA_RPxSACT 13 +#define HBA_RPxCI 14 +#define HBA_RPxSNTF 15 +#define HBA_RPxFBS 16 + +typedef unsigned int hba_reg_t; + +struct ahci_hba +{ + volatile hba_reg_t* base; + unsigned int ports_num; + unsigned int port_map; + unsigned int version; + hba_reg_t* ports[32]; +}; + +void +ahci_init(); #endif /* __LUNAIX_AHCI_H */ diff --git a/lunaix-os/kernel/demos/signal_demo.c b/lunaix-os/kernel/demos/signal_demo.c index e5f9533..616a38e 100644 --- a/lunaix-os/kernel/demos/signal_demo.c +++ b/lunaix-os/kernel/demos/signal_demo.c @@ -28,10 +28,6 @@ sigalrm_handler(int signum) kprintf(KWARN "I, pid %d, have received an alarm!\n", pid); } -// FIXME: Race condition with signal (though rare!) -// For some reason, there is a chance that iret in soft_iret path -// get unhappy when return from signal handler. Investigation is needed! - void __USER__ _signal_demo_main() { diff --git a/lunaix-os/kernel/mm/kalloc.c b/lunaix-os/kernel/mm/kalloc.c index ba00b09..6b5b878 100644 --- a/lunaix-os/kernel/mm/kalloc.c +++ b/lunaix-os/kernel/mm/kalloc.c @@ -59,7 +59,6 @@ lx_grow_heap(heap_context_t* heap, size_t sz); Note: the brk always point to the beginning of epilogue. */ -// FIXME: This should be per-process but not global! static heap_context_t kheap; int diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index 582dfdd..d195679 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -121,6 +122,7 @@ init_platform() clock_init(); ps2_kbd_init(); pci_init(); + ahci_init(); pci_print_device(); syscall_install(); -- 2.27.0