diff --git a/sys/denali/ahci/ahci_driver.cpp b/sys/denali/ahci/ahci_driver.cpp index bf2b464..767347c 100644 --- a/sys/denali/ahci/ahci_driver.cpp +++ b/sys/denali/ahci/ahci_driver.cpp @@ -20,18 +20,25 @@ void interrupt_thread(void* void_driver) { crash("Driver returned from interrupt loop", glcr::INTERNAL); } +PciDeviceHeader* LoadPciDeviceHeader(uint64_t ahci_phys) { + MappedMemoryRegion pci_region = + MappedMemoryRegion::DirectPhysical(ahci_phys, kPciSize); + return reinterpret_cast(pci_region.vaddr()); +} + } // namespace -glcr::ErrorCode AhciDriver::Init() { - RET_ERR(LoadPciDeviceHeader()); - // RET_ERR(LoadCapabilities()); - RET_ERR(RegisterIrq()); - RET_ERR(LoadHbaRegisters()); - ahci_hba_->global_host_control |= kGhc_InteruptEnable; - RET_ERR(LoadDevices()); - // DumpCapabilities(); - // DumpPorts(); - return glcr::OK; +glcr::ErrorOr> AhciDriver::Init( + uint64_t ahci_phys) { + PciDeviceHeader* header = LoadPciDeviceHeader(ahci_phys); + glcr::UniquePtr driver(new AhciDriver(header)); + // RET_ERR(driver.LoadCapabilities()); + RET_ERR(driver->LoadHbaRegisters()); + RET_ERR(driver->LoadDevices()); + RET_ERR(driver->RegisterIrq()); + // driver.DumpCapabilities(); + // driver.DumpPorts(); + return driver; } glcr::ErrorOr AhciDriver::GetDevice(uint64_t id) { @@ -153,12 +160,6 @@ void AhciDriver::InterruptLoop() { } } -glcr::ErrorCode AhciDriver::LoadPciDeviceHeader() { - pci_region_ = MappedMemoryRegion::DirectPhysical(ahci_phys_, kPciSize); - pci_device_header_ = reinterpret_cast(pci_region_.vaddr()); - return glcr::OK; -} - glcr::ErrorCode AhciDriver::LoadCapabilities() { if (!(pci_device_header_->status_reg & 0x10)) { dbgln("No caps!"); @@ -195,6 +196,7 @@ glcr::ErrorCode AhciDriver::RegisterIrq() { uint64_t irq_num = Z_IRQ_PCI_BASE + pci_device_header_->interrupt_pin - 1; RET_ERR(ZIrqRegister(irq_num, &irq_port_cap_)); irq_thread_ = Thread(interrupt_thread, this); + ahci_hba_->global_host_control |= kGhc_InteruptEnable; return glcr::OK; } diff --git a/sys/denali/ahci/ahci_driver.h b/sys/denali/ahci/ahci_driver.h index 922f2ba..936f6dd 100644 --- a/sys/denali/ahci/ahci_driver.h +++ b/sys/denali/ahci/ahci_driver.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -9,8 +10,8 @@ class AhciDriver { public: - AhciDriver(uint64_t ahci_phys) : ahci_phys_(ahci_phys) {} - glcr::ErrorCode Init(); + static glcr::ErrorOr> Init(uint64_t ahci_phys); + glcr::ErrorCode RegisterIrq(); void InterruptLoop(); @@ -20,8 +21,6 @@ class AhciDriver { void DumpPorts(); private: - uint64_t ahci_phys_; - MappedMemoryRegion pci_region_; PciDeviceHeader* pci_device_header_ = nullptr; MappedMemoryRegion ahci_region_; AhciHba* ahci_hba_ = nullptr; @@ -35,9 +34,10 @@ class AhciDriver { uint64_t num_ports_; uint64_t num_commands_; - glcr::ErrorCode LoadPciDeviceHeader(); glcr::ErrorCode LoadCapabilities(); - glcr::ErrorCode RegisterIrq(); glcr::ErrorCode LoadHbaRegisters(); glcr::ErrorCode LoadDevices(); + + AhciDriver(PciDeviceHeader* device_header) + : pci_device_header_(device_header) {} }; diff --git a/sys/denali/denali.cpp b/sys/denali/denali.cpp index 164eff1..f3e75f7 100644 --- a/sys/denali/denali.cpp +++ b/sys/denali/denali.cpp @@ -24,8 +24,7 @@ uint64_t main(uint64_t init_port_cap) { } uint64_t ahci_addr = resp_or.value().ahci_phys_offset; - AhciDriver driver(ahci_addr); - RET_ERR(driver.Init()); + ASSIGN_OR_RETURN(auto driver, AhciDriver::Init(ahci_addr)); YellowstoneGetReq req{ .type = kYellowstoneGetRegistration, @@ -46,7 +45,7 @@ uint64_t main(uint64_t init_port_cap) { endpoint->CreateClient()); notify.WriteMessage("denali", client->GetCap()); - DenaliServer server(glcr::Move(endpoint), driver); + DenaliServer server(glcr::Move(endpoint), *driver); RET_ERR(server.RunServer()); // FIXME: Add thread join. return 0;