diff --git a/sys/denali/CMakeLists.txt b/sys/denali/CMakeLists.txt index 566ab17..739b625 100644 --- a/sys/denali/CMakeLists.txt +++ b/sys/denali/CMakeLists.txt @@ -1,7 +1,6 @@ add_executable(denali ahci/ahci_controller.cpp ahci/ahci_port.cpp - ahci/command.cpp denali.cpp denali_server.cpp ) diff --git a/sys/denali/ahci/ahci_port.cpp b/sys/denali/ahci/ahci_port.cpp index a179515..e2cc974 100644 --- a/sys/denali/ahci/ahci_port.cpp +++ b/sys/denali/ahci/ahci_port.cpp @@ -63,29 +63,16 @@ glcr::ErrorCode AhciPort::Identify() { return glcr::OK; } -glcr::ErrorOr AhciPort::IssueCommand(const Command& 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; - } - command.PopulateFis(command_tables_[slot].command_fis); - command.PopulatePrdt(command_tables_[slot].prdt); - - command_list_->command_headers[slot].command = - (sizeof(HostToDeviceRegisterFis) / 2) & 0x1F | (1 << 7); - command_list_->command_headers[slot].prd_table_length = 1; - command_list_->command_headers[slot].prd_byte_count = 0; - - commands_issued_ |= (1 << slot); - port_struct_->command_issue |= (1 << slot); - - return &command_signals_[slot]; +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( diff --git a/sys/denali/ahci/ahci_port.h b/sys/denali/ahci/ahci_port.h index 646278e..a5e5f0e 100644 --- a/sys/denali/ahci/ahci_port.h +++ b/sys/denali/ahci/ahci_port.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -23,8 +24,8 @@ class AhciPort { glcr::ErrorCode Identify(); - glcr::ErrorOr IssueCommand(const Command& command); - glcr::ErrorOr IssueCommand(const CommandInfo& command); + glcr::ErrorOr IssueRead(uint64_t lba, uint16_t sector_cnt, + uint64_t paddr); void HandleIrq(); @@ -41,4 +42,6 @@ class AhciPort { glcr::Array command_signals_; uint32_t commands_issued_ = 0; + + glcr::ErrorOr IssueCommand(const CommandInfo& command); }; diff --git a/sys/denali/ahci/command.cpp b/sys/denali/ahci/command.cpp deleted file mode 100644 index e33d804..0000000 --- a/sys/denali/ahci/command.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "ahci/command.h" - -#include - -#include "ahci/ahci.h" - -namespace { - -void* memcpy(void* dest, const void* src, uint64_t count) { - uint8_t* d = (uint8_t*)dest; - const uint8_t* s = (uint8_t*)src; - for (uint64_t i = 0; i < count; i++) { - d[i] = s[i]; - } - return dest; -} - -} // namespace - -Command::~Command() {} - -DmaReadCommand::DmaReadCommand(uint64_t lba, uint64_t sector_cnt, - uint64_t paddr) - : lba_(lba), sector_cnt_(sector_cnt), paddr_(paddr) {} - -DmaReadCommand::~DmaReadCommand() {} - -void DmaReadCommand::PopulateFis(uint8_t* command_fis) const { - HostToDeviceRegisterFis fis{ - .fis_type = FIS_TYPE_REG_H2D, - .pmp_and_c = 0x80, - .command = kDmaReadExt, - .featurel = 0, - - .lba0 = static_cast(lba_ & 0xFF), - .lba1 = static_cast((lba_ >> 8) & 0xFF), - .lba2 = static_cast((lba_ >> 16) & 0xFF), - .device = (1 << 6), // ATA LBA Mode - - .lba3 = static_cast((lba_ >> 24) & 0xFF), - .lba4 = static_cast((lba_ >> 32) & 0xFF), - .lba5 = static_cast((lba_ >> 40) & 0xFF), - .featureh = 0, - - .count = static_cast(sector_cnt_), - .icc = 0, - .control = 0, - - .reserved = 0, - }; - - memcpy(command_fis, &fis, sizeof(fis)); -} - -void DmaReadCommand::PopulatePrdt(PhysicalRegionDescriptor* prdt) const { - prdt[0].region_address = paddr_; - prdt[0].byte_count = sector_cnt_ * 512; -} diff --git a/sys/denali/ahci/command.h b/sys/denali/ahci/command.h index 447c4f4..cf94c1b 100644 --- a/sys/denali/ahci/command.h +++ b/sys/denali/ahci/command.h @@ -1,39 +1,10 @@ #pragma once -#include -#include #include -#include "ahci/ahci.h" - -class AhciPort; - struct CommandInfo { uint8_t command; uint64_t lba; uint16_t sectors; uint64_t paddr; }; - -class Command { - public: - Command() = default; - virtual ~Command(); - virtual void PopulateFis(uint8_t* command_fis) const = 0; - virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) const = 0; -}; - -class DmaReadCommand : public Command { - public: - DmaReadCommand(uint64_t lba, uint64_t sector_cnt, uint64_t dest_paddr); - - virtual ~DmaReadCommand() override; - - void PopulateFis(uint8_t* command_fis) const override; - void PopulatePrdt(PhysicalRegionDescriptor* prdt) const override; - - private: - uint64_t lba_; - uint64_t sector_cnt_; - uint64_t paddr_; -}; diff --git a/sys/denali/denali_server.cpp b/sys/denali/denali_server.cpp index 7945555..ef6d9d4 100644 --- a/sys/denali/denali_server.cpp +++ b/sys/denali/denali_server.cpp @@ -20,8 +20,8 @@ glcr::Status DenaliServer::HandleRead(const ReadRequest& req, mmth::OwnedMemoryRegion region = mmth::OwnedMemoryRegion::ContiguousPhysical(req.size() * 512, &paddr); - DmaReadCommand command(req.lba(), req.size(), paddr); - ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(command)); + ASSIGN_OR_RETURN(auto semaphore, + device->IssueRead(req.lba(), req.size(), paddr)); semaphore->Wait(); resp.set_device_id(req.device_id()); @@ -49,8 +49,8 @@ glcr::Status DenaliServer::HandleReadMany(const ReadManyRequest& req, for (uint64_t i = 0; i < req.lba().size(); i++) { uint64_t lba = req.lba().at(i); uint64_t size = req.sector_cnt().at(i); - DmaReadCommand command(lba, size, region_paddr); - ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(command)); + ASSIGN_OR_RETURN(auto semaphore, + device->IssueRead(lba, size, region_paddr)); semaphore->Wait(); region_paddr += size * 512;