From 440de700f9bee4d69d1f168fd152d074aec6eafa Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Sat, 1 Feb 2025 14:32:05 -0800 Subject: [PATCH] Remove denali cpp executable. --- sys/denali/CMakeLists.txt | 23 --- sys/denali/ahci/ahci.h | 271 ---------------------------- sys/denali/ahci/ahci_controller.cpp | 250 ------------------------- sys/denali/ahci/ahci_controller.h | 47 ----- sys/denali/ahci/ahci_port.cpp | 224 ----------------------- sys/denali/ahci/ahci_port.h | 51 ------ sys/denali/ahci/command.h | 10 - sys/denali/denali.cpp | 37 ---- sys/denali/denali_server.cpp | 59 ------ sys/denali/denali_server.h | 25 --- 10 files changed, 997 deletions(-) delete mode 100644 sys/denali/ahci/ahci.h delete mode 100644 sys/denali/ahci/ahci_controller.cpp delete mode 100644 sys/denali/ahci/ahci_controller.h delete mode 100644 sys/denali/ahci/ahci_port.cpp delete mode 100644 sys/denali/ahci/ahci_port.h delete mode 100644 sys/denali/ahci/command.h delete mode 100644 sys/denali/denali.cpp delete mode 100644 sys/denali/denali_server.cpp delete mode 100644 sys/denali/denali_server.h diff --git a/sys/denali/CMakeLists.txt b/sys/denali/CMakeLists.txt index 739b625..86fd4de 100644 --- a/sys/denali/CMakeLists.txt +++ b/sys/denali/CMakeLists.txt @@ -1,24 +1 @@ -add_executable(denali - ahci/ahci_controller.cpp - ahci/ahci_port.cpp - denali.cpp - denali_server.cpp - ) - - -target_include_directories(denali - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - -target_link_libraries(denali - denali_yunq - glacier - mammoth - yellowstone_yunq - ) - -set_target_properties(denali PROPERTIES - COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}" - LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}" - ) - yunq_gen(lib/denali lib denali) diff --git a/sys/denali/ahci/ahci.h b/sys/denali/ahci/ahci.h deleted file mode 100644 index c927de7..0000000 --- a/sys/denali/ahci/ahci.h +++ /dev/null @@ -1,271 +0,0 @@ -#pragma once - -#include - -struct PciDeviceHeader { - uint16_t vendor_id; - uint16_t device_id; - uint16_t command_reg; - uint16_t status_reg; - uint8_t revision; - uint8_t prog_interface; - uint8_t subclass; - uint8_t class_code; - uint8_t cache_line_size; - uint8_t latency_timer; - uint8_t header_type; - uint8_t bist; - uint32_t bars[5]; - uint32_t abar; - uint32_t reserved0; - uint32_t subsystem_id; - uint32_t expansion_rom; - uint8_t cap_ptr; - uint8_t reserved1[7]; - uint8_t interrupt_line; - uint8_t interrupt_pin; - uint8_t min_grant; - uint8_t max_latency; -} __attribute__((packed)); - -struct PciMsiCap { - uint8_t cap_id; - uint8_t next_offset; - uint8_t message_control; - uint8_t reserved; - uint64_t message_address; - uint16_t message_data; -} __attribute__((packed)); - -const uint32_t kGlobalHostControl_HW_Reset = 1; -const uint32_t kGlobalHostControl_AHCI_Enable = (1 << 31); -const uint32_t kGlobalHostControl_Interrupt_Enable = (1 << 1); - -struct AhciHba { - uint32_t capabilities; - uint32_t global_host_control; - uint32_t interrupt_status; - uint32_t port_implemented; - uint32_t version; - uint32_t ccc_ctl; // 0x14, Command completion coalescing control - uint32_t ccc_pts; // 0x18, Command completion coalescing ports - uint32_t em_loc; // 0x1C, Enclosure management location - uint32_t em_ctl; // 0x20, Enclosure management control - uint32_t capabilities_ext; - uint32_t bohc; // 0x28, BIOS/OS handoff control and status -} __attribute__((packed)); - -const uint32_t kCommand_FIS_Receive_Enable = (1 << 4); -const uint32_t kCommand_Start = 1; - -const uint32_t kInterrupt_D2H_FIS = 1; -const uint32_t kInterrupt_PIO_FIS = (1 << 1); -const uint32_t kInterrupt_DMA_FIS = (1 << 2); -const uint32_t kInterrupt_DeviceBits_FIS = (1 << 3); -const uint32_t kInterrupt_Unknown_FIS = (1 << 4); - -struct AhciPortHba { - uint64_t command_list_base; - uint64_t fis_base; - uint32_t interrupt_status; - uint32_t interrupt_enable; - uint32_t command; - uint32_t reserved; - uint32_t task_file_data; - uint32_t signature; - uint32_t sata_status; - uint32_t sata_control; - uint32_t sata_error; - uint32_t sata_active; - uint32_t command_issue; - uint32_t sata_notification; - uint32_t fis_based_switching_ctl; - uint32_t device_sleep; -} __attribute__((packed)); - -struct CommandHeader { - uint16_t command; - uint16_t prd_table_length; - uint32_t prd_byte_count; - uint64_t command_table_base_addr; - uint64_t reserved1; - uint64_t reserved2; -} __attribute__((packed)); - -struct CommandList { - CommandHeader command_headers[32]; -} __attribute__((packed)); - -struct PhysicalRegionDescriptor { - uint64_t region_address; - uint32_t reserved; - // bit 0 must be one. - // 21:0 is byte count - // 31 is Interrupt on Completion - uint32_t byte_count; -} __attribute__((packed)); - -struct CommandTable { - uint8_t command_fis[64]; - uint8_t atapi_command[16]; - uint8_t reserved[48]; - PhysicalRegionDescriptor prdt[8]; -} __attribute__((packed)); - -typedef enum { - FIS_TYPE_REG_H2D = 0x27, // Register FIS - host to device - FIS_TYPE_REG_D2H = 0x34, // Register FIS - device to host - FIS_TYPE_DMA_ACT = 0x39, // DMA activate FIS - device to host - FIS_TYPE_DMA_SETUP = 0x41, // DMA setup FIS - bidirectional - FIS_TYPE_DATA = 0x46, // Data FIS - bidirectional - FIS_TYPE_BIST = 0x58, // BIST activate FIS - bidirectional - FIS_TYPE_PIO_SETUP = 0x5F, // PIO setup FIS - device to host - FIS_TYPE_DEV_BITS = 0xA1, // Set device bits FIS - device to host -} FIS_TYPE; - -struct DmaFis { - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_DMA_SETUP - - uint8_t pmport : 4; // Port multiplier - uint8_t rsv0 : 1; // Reserved - uint8_t d : 1; // Data transfer direction, 1 - device to host - uint8_t i : 1; // Interrupt bit - uint8_t a : 1; // Auto-activate. Specifies if DMA Activate FIS is needed - - uint8_t rsved[2]; // Reserved - - // DWORD 1&2 - - uint64_t DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer - // in host memory. SATA Spec says host specific and not - // in Spec. Trying AHCI spec might work. - - // DWORD 3 - uint32_t rsvd; // More reserved - - // DWORD 4 - uint32_t DMAbufOffset; // Byte offset into buffer. First 2 bits must be 0 - - // DWORD 5 - uint32_t TransferCount; // Number of bytes to transfer. Bit 0 must be 0 - - // DWORD 6 - uint32_t resvd; // Reserved -} __attribute__((packed)); - -struct PioSetupFis { - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_PIO_SETUP - - uint8_t pmport : 4; // Port multiplier - uint8_t rsv0 : 1; // Reserved - uint8_t d : 1; // Data transfer direction, 1 - device to host - uint8_t i : 1; // Interrupt bit - uint8_t rsv1 : 1; - - uint8_t status; // Status register - uint8_t error; // Error register - - // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register - - // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t rsv2; // Reserved - - // DWORD 3 - uint8_t countl; // Count register, 7:0 - uint8_t counth; // Count register, 15:8 - uint8_t rsv3; // Reserved - uint8_t e_status; // New value of status register - - // DWORD 4 - uint16_t tc; // Transfer count - uint8_t rsv4[2]; // Reserved -} __attribute__((packed)); - -const uint8_t kIdentifyDevice = 0xEC; -const uint8_t kDmaReadExt = 0x25; - -struct HostToDeviceRegisterFis { - uint8_t fis_type; // FIS_TYPE_REG_H2D - uint8_t pmp_and_c; - uint8_t command; // Command register - uint8_t featurel; // Feature register, 7:0 - - // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register - - // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t featureh; // Feature register, 15:8 - - // DWORD 3 - uint16_t count; - uint8_t icc; // Isochronous command completion - uint8_t control; // Control register - - // DWORD 4 - uint32_t reserved; // Reserved -} __attribute__((packed)); - -struct DeviceToHostRegisterFis { - // DWORD 0 - uint8_t fis_type; // FIS_TYPE_REG_D2H - - uint8_t pmport_and_i; - - uint8_t status; // Status register - uint8_t error; // Error register - - // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register - - // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t reserved1; - - // DWORD 3 - uint16_t count; - uint16_t reserved2; - - uint32_t reserved3; -} __attribute__((packed)); - -struct SetDeviceBitsFis { - uint8_t fis_type; - uint8_t pmport_and_i; - uint8_t status; - uint8_t error; - uint32_t reserved; -} __attribute__((packed)); - -struct ReceivedFis { - DmaFis dma_fis; - uint32_t reserved0; - - PioSetupFis pio_set_fis; - uint32_t reserved1[3]; - - DeviceToHostRegisterFis device_to_host_register_fis; - uint32_t reserved2; - - SetDeviceBitsFis set_device_bits_fis; - uint8_t unknown_fis[64]; -} __attribute__((packed)); diff --git a/sys/denali/ahci/ahci_controller.cpp b/sys/denali/ahci/ahci_controller.cpp deleted file mode 100644 index 96fc6e8..0000000 --- a/sys/denali/ahci/ahci_controller.cpp +++ /dev/null @@ -1,250 +0,0 @@ -#include "ahci/ahci_controller.h" - -#include -#include -#include -#include -#include - -namespace { - -const uint64_t kGhc_InteruptEnable = 0x2; - -void interrupt_thread(void* void_driver) { - AhciController* driver = static_cast(void_driver); - - driver->InterruptLoop(); - - crash("Driver returned from interrupt loop", glcr::INTERNAL); -} - -} // namespace - -glcr::ErrorOr> AhciController::Init( - mmth::OwnedMemoryRegion&& pci_region) { - glcr::UniquePtr driver( - new AhciController(glcr::Move(pci_region))); - RET_ERR(driver->LoadHbaRegisters()); - driver->DumpCapabilities(); - RET_ERR(driver->ResetHba()); - RET_ERR(driver->RegisterIrq()); - RET_ERR(driver->LoadPorts()); - // driver->DumpPorts(); - return driver; -} - -glcr::ErrorOr AhciController::GetDevice(uint64_t id) { - if (id >= num_ports_) { - return glcr::INVALID_ARGUMENT; - } - - if (ports_[id].empty()) { - return glcr::NOT_FOUND; - } - - return ports_[id].get(); -} - -void AhciController::DumpCapabilities() { - dbgln("AHCI Capabilities:"); - uint32_t caps = ahci_hba_->capabilities; - - if (caps & 0x20) { - dbgln("External SATA"); - } - if (caps & 0x40) { - dbgln("Enclosure Management"); - } - if (caps & 0x80) { - dbgln("Command Completion Coalescing"); - } - if (caps & 0x2000) { - dbgln("Partial State Capable"); - } - if (caps & 0x4000) { - dbgln("Slumber state capable"); - } - if (caps & 0x8000) { - dbgln("PIO Multiple DRQ Block"); - } - if (caps & 0x1'0000) { - dbgln("FIS-Based Switching"); - } - if (caps & 0x2'0000) { - dbgln("Port Multiplier"); - } - if (caps & 0x4'0000) { - dbgln("AHCI mode only"); - } - dbgln("Speed support: {}", (caps & 0xF0'0000) >> 20); - if (caps & 0x100'0000) { - dbgln("Command list override"); - } - if (caps & 0x200'0000) { - dbgln("Activity LED"); - } - if (caps & 0x400'0000) { - dbgln("Aggresive link power management"); - } - if (caps & 0x800'0000) { - dbgln("Staggered spin up"); - } - if (caps & 0x1000'0000) { - dbgln("Mechanical Switch Presence"); - } - if (caps & 0x2000'0000) { - dbgln("SNotification Register"); - } - if (caps & 0x4000'0000) { - dbgln("Native Command Queueing"); - } - if (caps & 0x8000'0000) { - dbgln("64bit Addressing"); - } - - // Secondary. - caps = ahci_hba_->capabilities_ext; - if (caps & 0x1) { - dbgln("BIOS/OS handoff"); - } - if (caps & 0x2) { - dbgln("NVMHCI Present"); - } - if (caps & 0x4) { - dbgln("Auto partial to slumber tranisitions"); - } - if (caps & 0x8) { - dbgln("Device sleep"); - } - if (caps & 0x10) { - dbgln("Aggressive device sleep management"); - } - - dbgln("Control {x}", ahci_hba_->global_host_control); -} - -void AhciController::DumpPorts() { - for (uint64_t i = 0; i < 6; i++) { - if (ports_[i].empty()) { - continue; - } - - dbgln(""); - dbgln("Port {}:", i); - ports_[i]->DumpInfo(); - } -} - -void AhciController::InterruptLoop() { - dbgln("Starting interrupt loop"); - while (true) { - uint64_t bytes, caps; - check(ZPortRecv(irq_port_cap_, &bytes, nullptr, &caps, nullptr)); - for (uint64_t i = 0; i < num_ports_; i++) { - if (!ports_[i].empty() && (ahci_hba_->interrupt_status & (1 << i))) { - ports_[i]->HandleIrq(); - ahci_hba_->interrupt_status &= ~(1 << i); - } - } - } -} - -glcr::ErrorCode AhciController::LoadCapabilities() { - if (!(pci_device_header_->status_reg & 0x10)) { - dbgln("No caps!"); - return glcr::FAILED_PRECONDITION; - } - volatile uint8_t* base = - reinterpret_cast(pci_device_header_); - uint16_t offset = pci_device_header_->cap_ptr; - do { - volatile uint16_t* cap = - reinterpret_cast(base + offset); - switch (*cap & 0xFF) { - case 0x01: - dbgln("Power Management"); - break; - case 0x05: - dbgln("MSI"); - break; - case 0x12: - dbgln("SATA"); - break; - default: - dbgln("Unrecognized cap"); - break; - } - - offset = (*cap & 0xFF00) >> 8; - } while (offset); - return glcr::OK; -} - -glcr::ErrorCode AhciController::RegisterIrq() { - if (pci_device_header_->interrupt_pin == 0) { - crash("Can't register IRQ without a pin num", glcr::INVALID_ARGUMENT); - } - uint64_t irq_num = 0; - switch (pci_device_header_->interrupt_pin) { - case 1: - irq_num = kZIrqPci1; - break; - case 2: - irq_num = kZIrqPci2; - break; - case 3: - irq_num = kZIrqPci3; - break; - case 4: - irq_num = kZIrqPci4; - break; - } - - RET_ERR(ZIrqRegister(irq_num, &irq_port_cap_)); - irq_thread_ = Thread(interrupt_thread, this); - ahci_hba_->global_host_control |= kGhc_InteruptEnable; - return glcr::OK; -} - -glcr::ErrorCode AhciController::LoadHbaRegisters() { - ahci_region_ = mmth::OwnedMemoryRegion ::DirectPhysical( - pci_device_header_->abar, 0x1100); - ahci_hba_ = reinterpret_cast(ahci_region_.vaddr()); - num_ports_ = (ahci_hba_->capabilities & 0x1F) + 1; - num_commands_ = ((ahci_hba_->capabilities & 0x1F00) >> 8) + 1; - - return glcr::OK; -} - -glcr::ErrorCode AhciController::ResetHba() { - ahci_hba_->global_host_control |= kGlobalHostControl_HW_Reset; - - // TODO: Consider sleeping here. - while (ahci_hba_->global_host_control & kGlobalHostControl_HW_Reset) { - continue; - } - - ahci_hba_->global_host_control |= kGlobalHostControl_AHCI_Enable; - - return static_cast(ZThreadSleep(50)); -} - -glcr::ErrorCode AhciController::LoadPorts() { - for (uint8_t i = 0; i <= num_ports_; i++) { - if (!(ahci_hba_->port_implemented & (1 << i))) { - continue; - } - - uint64_t port_addr = - reinterpret_cast(ahci_hba_) + 0x100 + (0x80 * i); - AhciPortHba* port = reinterpret_cast(port_addr); - if ((port->sata_status & 0x103) != 0x103) { - continue; - } - - ports_[i] = new AhciPort(reinterpret_cast(port_addr)); - // TODO: Maybe continue to the next device if this fails. - RET_ERR(ports_[i]->Identify()); - } - return glcr::OK; -} diff --git a/sys/denali/ahci/ahci_controller.h b/sys/denali/ahci/ahci_controller.h deleted file mode 100644 index fba32ef..0000000 --- a/sys/denali/ahci/ahci_controller.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "ahci/ahci.h" -#include "ahci/ahci_port.h" - -class AhciController { - public: - static glcr::ErrorOr> Init( - mmth::OwnedMemoryRegion&& ahci_phys); - glcr::ErrorCode RegisterIrq(); - - void InterruptLoop(); - - glcr::ErrorOr GetDevice(uint64_t id); - - void DumpCapabilities(); - void DumpPorts(); - - private: - mmth::OwnedMemoryRegion pci_region_; - volatile PciDeviceHeader* pci_device_header_ = nullptr; - mmth::OwnedMemoryRegion ahci_region_; - volatile AhciHba* ahci_hba_ = nullptr; - - glcr::UniquePtr ports_[32]; - - Thread irq_thread_; - uint64_t irq_port_cap_ = 0; - - uint8_t num_ports_; - uint8_t num_commands_; - - glcr::ErrorCode LoadCapabilities(); - glcr::ErrorCode LoadHbaRegisters(); - glcr::ErrorCode ResetHba(); - glcr::ErrorCode LoadPorts(); - - AhciController(mmth::OwnedMemoryRegion&& pci_region) - : pci_region_(glcr::Move(pci_region)), - pci_device_header_( - reinterpret_cast(pci_region_.vaddr())) {} -}; diff --git a/sys/denali/ahci/ahci_port.cpp b/sys/denali/ahci/ahci_port.cpp deleted file mode 100644 index 21c0501..0000000 --- a/sys/denali/ahci/ahci_port.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include "ahci/ahci_port.h" - -#include -#include -#include - -AhciPort::AhciPort(AhciPortHba* port) : port_struct_(port) { - if ((port_struct_->sata_status & 0x103) != 0x103) { - crash("Creating device on port without a device", - glcr::FAILED_PRECONDITION); - } - - // 0x0-0x400 -> Command List - // 0x400-0x500 -> Received FIS - // 0x500-0x2500 -> Command Tables (0x100 each) (Max PRDT Length is 8 for now) - uint64_t paddr; - command_structures_ = - mmth::OwnedMemoryRegion::ContiguousPhysical(0x2500, &paddr); - - command_list_ = reinterpret_cast(command_structures_.vaddr()); - port_struct_->command_list_base = paddr; - - received_fis_ = - reinterpret_cast(command_structures_.vaddr() + 0x400); - port_struct_->fis_base = paddr + 0x400; - port_struct_->command |= kCommand_FIS_Receive_Enable; - - command_tables_ = glcr::ArrayView( - reinterpret_cast(command_structures_.vaddr() + 0x500), 32); - - commands_issued_ = 0; - command_signals_ = glcr::Array(32); - for (uint64_t i = 0; i < 32; i++) { - // This leaves space for 2 prdt entries. - command_list_->command_headers[i].command_table_base_addr = - (paddr + 0x500) + (0x100 * i); - } - port_struct_->interrupt_enable = 0xFFFFFFFF; - // kInterrupt_D2H_FIS | kInterrupt_PIO_FIS | kInterrupt_DMA_FIS | - // kInterrupt_DeviceBits_FIS | kInterrupt_Unknown_FIS; - port_struct_->sata_error = -1; - port_struct_->command |= kCommand_Start; -} - -glcr::ErrorCode AhciPort::Identify() { - if (IsSata()) { - CommandInfo identify{ - .command = kIdentifyDevice, - .lba = 0, - .sectors = 1, - .paddr = 0, - }; - auto region = - mmth::OwnedMemoryRegion::ContiguousPhysical(0x200, &identify.paddr); - ASSIGN_OR_RETURN(auto* sem, IssueCommand(identify)); - sem->Wait(); - uint16_t* ident = reinterpret_cast(region.vaddr()); - if (ident[106] & (1 << 12)) { - sector_size_ = *reinterpret_cast(ident + 117); - } else { - sector_size_ = 512; - } - - if (ident[83] & (1 << 10)) { - lba_count_ = *reinterpret_cast(ident + 100); - } else { - lba_count_ = *reinterpret_cast(ident + 60); - } - dbgln("Sector size: {x}", sector_size_); - dbgln("LBA Count: {x}", lba_count_); - is_init_ = true; - } - return glcr::OK; -} - -glcr::ErrorOr AhciPort::IssueRead(uint64_t lba, - uint16_t sector_cnt, - uint64_t paddr) { - CommandInfo read{ - .command = kDmaReadExt, - .lba = lba, - .sectors = sector_cnt, - .paddr = paddr, - }; - return IssueCommand(read); -} - -glcr::ErrorOr AhciPort::IssueCommand( - const CommandInfo& command) { - uint64_t slot; - for (slot = 0; slot < 32; slot++) { - if (!(commands_issued_ & (1 << slot))) { - break; - } - } - if (slot == 32) { - dbgln("All slots full"); - return glcr::INTERNAL; - } - - auto* fis = reinterpret_cast( - command_tables_[slot].command_fis); - *fis = HostToDeviceRegisterFis{ - .fis_type = FIS_TYPE_REG_H2D, - .pmp_and_c = 0x80, - .command = command.command, - .featurel = 0, - - .lba0 = static_cast(command.lba & 0xFF), - .lba1 = static_cast((command.lba >> 8) & 0xFF), - .lba2 = static_cast((command.lba >> 16) & 0xFF), - .device = (1 << 6), // ATA LBA Mode - - .lba3 = static_cast((command.lba >> 24) & 0xFF), - .lba4 = static_cast((command.lba >> 32) & 0xFF), - .lba5 = static_cast((command.lba >> 40) & 0xFF), - .featureh = 0, - - .count = command.sectors, - .icc = 0, - .control = 0, - - .reserved = 0, - }; - - command_tables_[slot].prdt[0].region_address = command.paddr; - command_tables_[slot].prdt[0].byte_count = 512 * command.sectors; - - command_list_->command_headers[slot].prd_table_length = 1; - command_list_->command_headers[slot].command = - (sizeof(HostToDeviceRegisterFis) / 4) & 0x1F; - // Set prefetch bit. - command_list_->command_headers[slot].command |= (1 << 7); - - // TODO: Synchronization-wise we need to ensure this is set in the same - // critical section as where we select a slot. - commands_issued_ |= (1 << slot); - port_struct_->command_issue |= (1 << slot); - - return &command_signals_[slot]; -} - -void AhciPort::DumpInfo() { - dbgln("Comlist: {x}", port_struct_->command_list_base); - dbgln("FIS: {x}", port_struct_->fis_base); - dbgln("Command: {x}", port_struct_->command); - dbgln("Signature: {x}", port_struct_->signature); - dbgln("SATA status: {x}", port_struct_->sata_status); - dbgln("SATA error: {x}", port_struct_->sata_error); - dbgln("Int status: {x}", port_struct_->interrupt_status); - dbgln("Int enable: {x}", port_struct_->interrupt_enable); -} - -bool CheckFisType(FIS_TYPE expected, uint8_t actual) { - if (expected == actual) { - return true; - } - dbgln("BAD FIS TYPE (exp,act): {x}, {x}", static_cast(expected), - static_cast(actual)); - return false; -} - -void AhciPort::HandleIrq() { - uint32_t int_status = port_struct_->interrupt_status; - port_struct_->interrupt_status = int_status; - - bool has_error = false; - if (int_status & kInterrupt_D2H_FIS) { - volatile DeviceToHostRegisterFis& fis = - received_fis_->device_to_host_register_fis; - if (!CheckFisType(FIS_TYPE_REG_D2H, fis.fis_type)) { - return; - } - // Check is init to avoid showing an error from the COMRESET operation. - if (fis.error && is_init_) { - dbgln("D2H err: {x}", fis.error); - - dbgln("status: {x}", fis.status); - dbgln("Error: {x}", port_struct_->sata_error); - has_error = true; - } - } - if (int_status & kInterrupt_PIO_FIS) { - volatile PioSetupFis& fis = received_fis_->pio_set_fis; - if (!CheckFisType(FIS_TYPE_PIO_SETUP, fis.fis_type)) { - return; - } - if (fis.error) { - dbgln("PIO err: {x}", fis.error); - dbgln("status: {x}", fis.status); - has_error = true; - } - } - if (int_status & kInterrupt_DMA_FIS) { - volatile DmaFis& fis = received_fis_->dma_fis; - if (!CheckFisType(FIS_TYPE_DMA_SETUP, fis.fis_type)) { - return; - } - // TODO: Actually do something with this FIS. - } - if (int_status & kInterrupt_DeviceBits_FIS) { - volatile SetDeviceBitsFis& fis = received_fis_->set_device_bits_fis; - if (!CheckFisType(FIS_TYPE_DEV_BITS, fis.fis_type)) { - return; - } - if (fis.error) { - dbgln("SetDeviceBits err: {x}", fis.error); - dbgln("status: {x}", fis.status); - has_error = true; - } - } - if (int_status & kInterrupt_Unknown_FIS) { - dbgln("Unknown FIS recieved, type: {x}", received_fis_->unknown_fis[0]); - } - uint32_t commands_finished = commands_issued_ & ~port_struct_->command_issue; - - for (uint64_t i = 0; i < 32; i++) { - if (commands_finished & (1 << i)) { - // TODO: Pass error codes to the callback. - command_signals_[i].Signal(); - commands_issued_ &= ~(1 << i); - } - } -} diff --git a/sys/denali/ahci/ahci_port.h b/sys/denali/ahci/ahci_port.h deleted file mode 100644 index fc9b2df..0000000 --- a/sys/denali/ahci/ahci_port.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "ahci/ahci.h" -#include "ahci/command.h" - -class AhciPort { - public: - AhciPort() {} - // Caller retains ownership of the pointer. - AhciPort(AhciPortHba* port_struct); - - void DumpInfo(); - - bool IsSata() { return port_struct_->signature == 0x101; } - bool IsInit() { return is_init_; } - - glcr::ErrorCode Identify(); - - glcr::ErrorOr IssueRead(uint64_t lba, uint16_t sector_cnt, - uint64_t paddr); - - void HandleIrq(); - - AhciPort(const AhciPort&) = delete; - AhciPort& operator=(const AhciPort&) = delete; - - private: - volatile AhciPortHba* port_struct_ = nullptr; - mmth::OwnedMemoryRegion command_structures_; - - volatile CommandList* command_list_ = nullptr; - volatile ReceivedFis* received_fis_ = nullptr; - glcr::ArrayView command_tables_; - - glcr::Array command_signals_; - uint32_t commands_issued_ = 0; - - bool is_init_ = false; - uint64_t lba_count_ = 0; - uint32_t sector_size_ = 0; - - glcr::ErrorOr IssueCommand(const CommandInfo& command); -}; diff --git a/sys/denali/ahci/command.h b/sys/denali/ahci/command.h deleted file mode 100644 index cf94c1b..0000000 --- a/sys/denali/ahci/command.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -struct CommandInfo { - uint8_t command; - uint64_t lba; - uint16_t sectors; - uint64_t paddr; -}; diff --git a/sys/denali/denali.cpp b/sys/denali/denali.cpp deleted file mode 100644 index ba25e9a..0000000 --- a/sys/denali/denali.cpp +++ /dev/null @@ -1,37 +0,0 @@ - -#include -#include -#include -#include - -#include "ahci/ahci_controller.h" -#include "denali_server.h" - -using yellowstone::AhciInfo; -using yellowstone::RegisterEndpointRequest; -using yellowstone::YellowstoneClient; - -uint64_t main(uint64_t init_port_cap) { - check(ParseInitPort(init_port_cap)); - - YellowstoneClient stub(gInitEndpointCap); - AhciInfo ahci; - check(stub.GetAhciInfo(ahci)); - mmth::OwnedMemoryRegion ahci_region = - mmth::OwnedMemoryRegion::FromCapability(ahci.ahci_region()); - ASSIGN_OR_RETURN(auto driver, AhciController::Init(glcr::Move(ahci_region))); - - ASSIGN_OR_RETURN(glcr::UniquePtr server, - DenaliServer::Create(*driver)); - - Thread server_thread = server->RunServer(); - - RegisterEndpointRequest req; - req.set_endpoint_name("denali"); - ASSIGN_OR_RETURN(z_cap_t client_cap, server->CreateClientCap()); - req.set_endpoint_capability(client_cap); - check(stub.RegisterEndpoint(req)); - - check(server_thread.Join()); - return 0; -} diff --git a/sys/denali/denali_server.cpp b/sys/denali/denali_server.cpp deleted file mode 100644 index c245bec..0000000 --- a/sys/denali/denali_server.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "denali_server.h" - -#include -#include -#include -#include - -glcr::ErrorOr> DenaliServer::Create( - AhciController& driver) { - z_cap_t cap; - RET_ERR(ZEndpointCreate(&cap)); - return glcr::UniquePtr(new DenaliServer(cap, driver)); -} - -glcr::Status DenaliServer::HandleRead(const ReadRequest& req, - ReadResponse& resp) { - ASSIGN_OR_RETURN(AhciPort * device, driver_.GetDevice(req.device_id())); - - uint64_t paddr; - mmth::OwnedMemoryRegion region = mmth::OwnedMemoryRegion::ContiguousPhysical( - req.block().size() * 512, &paddr); - - ASSIGN_OR_RETURN( - auto semaphore, - device->IssueRead(req.block().lba(), req.block().size(), paddr)); - semaphore->Wait(); - - resp.set_device_id(req.device_id()); - resp.set_size(req.block().size()); - resp.set_memory(region.DuplicateCap()); - return glcr::Status::Ok(); -} - -glcr::Status DenaliServer::HandleReadMany(const ReadManyRequest& req, - ReadResponse& resp) { - ASSIGN_OR_RETURN(AhciPort * device, driver_.GetDevice(req.device_id())); - - uint64_t sector_cnt = 0; - for (auto& block : req.blocks()) { - sector_cnt += block.size(); - } - uint64_t region_paddr; - mmth::OwnedMemoryRegion region = mmth::OwnedMemoryRegion::ContiguousPhysical( - sector_cnt * 512, ®ion_paddr); - - for (auto& block : req.blocks()) { - ASSIGN_OR_RETURN( - auto semaphore, - device->IssueRead(block.lba(), block.size(), region_paddr)); - semaphore->Wait(); - - region_paddr += block.size() * 512; - } - - resp.set_device_id(req.device_id()); - resp.set_size(sector_cnt); - resp.set_memory(region.DuplicateCap()); - return glcr::Status::Ok(); -} diff --git a/sys/denali/denali_server.h b/sys/denali/denali_server.h deleted file mode 100644 index 4e5b9dc..0000000 --- a/sys/denali/denali_server.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - -#include "ahci/ahci_controller.h" -#include "lib/denali/denali.yunq.server.h" - -class DenaliServer : public DenaliServerBase { - public: - static glcr::ErrorOr> Create( - AhciController& driver); - - glcr::Status HandleRead(const ReadRequest& req, ReadResponse& resp) override; - glcr::Status HandleReadMany(const ReadManyRequest& req, - ReadResponse& resp) override; - - private: - static const uint64_t kBuffSize = 1024; - uint8_t read_buffer_[kBuffSize]; - - AhciController& driver_; - - DenaliServer(z_cap_t endpoint_cap, AhciController& driver) - : DenaliServerBase(endpoint_cap), driver_(driver) {} -};