From e71017070f7a034478319c52020c959aa287516e Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Fri, 8 Dec 2023 14:48:41 -0800 Subject: [PATCH] [Denali] No longer store Commands on the port. --- lib/mammoth/util/memory_region.h | 10 +++++----- sys/denali/ahci/ahci_port.cpp | 19 ++++++++----------- sys/denali/ahci/ahci_port.h | 3 +-- sys/denali/ahci/command.cpp | 8 ++++---- sys/denali/ahci/command.h | 12 ++++++------ sys/denali/denali_server.cpp | 4 ++-- 6 files changed, 26 insertions(+), 30 deletions(-) diff --git a/lib/mammoth/util/memory_region.h b/lib/mammoth/util/memory_region.h index 97d1cf6..7af7d6c 100644 --- a/lib/mammoth/util/memory_region.h +++ b/lib/mammoth/util/memory_region.h @@ -25,14 +25,14 @@ class OwnedMemoryRegion { static OwnedMemoryRegion ContiguousPhysical(uint64_t size, uint64_t* paddr); static OwnedMemoryRegion DirectPhysical(uint64_t paddr, uint64_t size); - uint64_t vaddr() { return vaddr_; } - uint64_t size() { return size_; } + uint64_t vaddr() const { return vaddr_; } + uint64_t size() const { return size_; } - z_cap_t cap() { return vmmo_cap_; } + z_cap_t cap() const { return vmmo_cap_; } z_cap_t DuplicateCap(); - bool empty() { return vmmo_cap_ != 0; } - explicit operator bool() { return vmmo_cap_ != 0; } + bool empty() const { return vmmo_cap_ == 0; } + explicit operator bool() const { return vmmo_cap_ != 0; } private: OwnedMemoryRegion(uint64_t vmmo_cap, uint64_t vaddr, uint64_t size) diff --git a/sys/denali/ahci/ahci_port.cpp b/sys/denali/ahci/ahci_port.cpp index 8c4b754..fe148d6 100644 --- a/sys/denali/ahci/ahci_port.cpp +++ b/sys/denali/ahci/ahci_port.cpp @@ -28,12 +28,12 @@ AhciPort::AhciPort(AhciPortHba* port) : port_struct_(port) { 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); - commands_[i] = nullptr; } port_struct_->interrupt_enable = 0xFFFFFFFF; // kInterrupt_D2H_FIS | kInterrupt_PIO_FIS | kInterrupt_DMA_FIS | @@ -45,17 +45,17 @@ AhciPort::AhciPort(AhciPortHba* port) : port_struct_(port) { glcr::ErrorCode AhciPort::Identify() { if (IsSata()) { IdentifyDeviceCommand identify(this); - ASSIGN_OR_RETURN(auto* sem, IssueCommand(&identify)); + ASSIGN_OR_RETURN(auto* sem, IssueCommand(identify)); sem->Wait(); identify.OnComplete(); } return glcr::OK; } -glcr::ErrorOr AhciPort::IssueCommand(Command* command) { +glcr::ErrorOr AhciPort::IssueCommand(const Command& command) { uint64_t slot; for (slot = 0; slot < 32; slot++) { - if (commands_[slot] == nullptr) { + if (!(commands_issued_ & (1 << slot))) { break; } } @@ -63,16 +63,14 @@ glcr::ErrorOr AhciPort::IssueCommand(Command* command) { dbgln("All slots full"); return glcr::INTERNAL; } - command->PopulateFis(command_tables_[slot].command_fis); - command->PopulatePrdt(command_tables_[slot].prdt); + 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_[slot] = command; - commands_issued_ |= (1 << slot); port_struct_->command_issue |= (1 << slot); @@ -161,10 +159,9 @@ void AhciPort::HandleIrq() { for (uint64_t i = 0; i < 32; i++) { if (commands_finished & (1 << i)) { - commands_issued_ &= ~(1 << i); - // FIXME: Pass error codes to the callback. + // TODO: Pass error codes to the callback. command_signals_[i].Signal(); - commands_[i] = nullptr; + commands_issued_ &= ~(1 << i); } } } diff --git a/sys/denali/ahci/ahci_port.h b/sys/denali/ahci/ahci_port.h index 1a74975..dc66de6 100644 --- a/sys/denali/ahci/ahci_port.h +++ b/sys/denali/ahci/ahci_port.h @@ -23,7 +23,7 @@ class AhciPort { glcr::ErrorCode Identify(); - glcr::ErrorOr IssueCommand(Command* command); + glcr::ErrorOr IssueCommand(const Command& command); void HandleIrq(); @@ -38,7 +38,6 @@ class AhciPort { volatile ReceivedFis* received_fis_ = nullptr; glcr::ArrayView command_tables_; - Command* commands_[32]; glcr::Array command_signals_; uint32_t commands_issued_ = 0; }; diff --git a/sys/denali/ahci/command.cpp b/sys/denali/ahci/command.cpp index 57cc96a..61a5bb1 100644 --- a/sys/denali/ahci/command.cpp +++ b/sys/denali/ahci/command.cpp @@ -19,7 +19,7 @@ void* memcpy(void* dest, const void* src, uint64_t count) { Command::~Command() {} -void IdentifyDeviceCommand::PopulateFis(uint8_t* command_fis) { +void IdentifyDeviceCommand::PopulateFis(uint8_t* command_fis) const { HostToDeviceRegisterFis fis __attribute__((aligned(16))){ .fis_type = FIS_TYPE_REG_H2D, .pmp_and_c = 0x80, @@ -30,7 +30,7 @@ void IdentifyDeviceCommand::PopulateFis(uint8_t* command_fis) { memcpy(command_fis, &fis, sizeof(fis)); } -void IdentifyDeviceCommand::PopulatePrdt(PhysicalRegionDescriptor* prdt) { +void IdentifyDeviceCommand::PopulatePrdt(PhysicalRegionDescriptor* prdt) const { prdt[0].region_address = paddr_; prdt[0].byte_count = 0x200 - 1; dbgln("paddr: {x}", paddr_); @@ -56,7 +56,7 @@ DmaReadCommand::DmaReadCommand(uint64_t lba, uint64_t sector_cnt, DmaReadCommand::~DmaReadCommand() {} -void DmaReadCommand::PopulateFis(uint8_t* command_fis) { +void DmaReadCommand::PopulateFis(uint8_t* command_fis) const { HostToDeviceRegisterFis fis{ .fis_type = FIS_TYPE_REG_H2D, .pmp_and_c = 0x80, @@ -83,7 +83,7 @@ void DmaReadCommand::PopulateFis(uint8_t* command_fis) { memcpy(command_fis, &fis, sizeof(fis)); } -void DmaReadCommand::PopulatePrdt(PhysicalRegionDescriptor* prdt) { +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 e7c6442..9c1e73f 100644 --- a/sys/denali/ahci/command.h +++ b/sys/denali/ahci/command.h @@ -12,15 +12,15 @@ class Command { public: Command() = default; virtual ~Command(); - virtual void PopulateFis(uint8_t* command_fis) = 0; - virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) = 0; + virtual void PopulateFis(uint8_t* command_fis) const = 0; + virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) const = 0; }; class IdentifyDeviceCommand : public Command { public: IdentifyDeviceCommand(AhciPort* port) : port_(port) {} - virtual void PopulateFis(uint8_t* command_fis) override; - virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) override; + virtual void PopulateFis(uint8_t* command_fis) const override; + virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) const override; void OnComplete(); @@ -37,8 +37,8 @@ class DmaReadCommand : public Command { virtual ~DmaReadCommand() override; - void PopulateFis(uint8_t* command_fis) override; - void PopulatePrdt(PhysicalRegionDescriptor* prdt) override; + void PopulateFis(uint8_t* command_fis) const override; + void PopulatePrdt(PhysicalRegionDescriptor* prdt) const override; private: uint64_t lba_; diff --git a/sys/denali/denali_server.cpp b/sys/denali/denali_server.cpp index 0de18ff..7945555 100644 --- a/sys/denali/denali_server.cpp +++ b/sys/denali/denali_server.cpp @@ -21,7 +21,7 @@ glcr::Status DenaliServer::HandleRead(const ReadRequest& req, 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->IssueCommand(command)); semaphore->Wait(); resp.set_device_id(req.device_id()); @@ -50,7 +50,7 @@ glcr::Status DenaliServer::HandleReadMany(const ReadManyRequest& req, 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->IssueCommand(command)); semaphore->Wait(); region_paddr += size * 512;