From 28a0f02b059b065f7382ef789b0f5cde2d8d4aba Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Fri, 8 Dec 2023 14:43:29 -0800 Subject: [PATCH] [Denali] Move signaling out of the command class. --- sys/denali/ahci/ahci_controller.cpp | 8 ++------ sys/denali/ahci/ahci_port.cpp | 17 ++++++++++++++--- sys/denali/ahci/ahci_port.h | 7 ++++++- sys/denali/ahci/command.cpp | 6 ------ sys/denali/ahci/command.h | 11 +---------- sys/denali/denali_server.cpp | 9 ++++----- 6 files changed, 27 insertions(+), 31 deletions(-) diff --git a/sys/denali/ahci/ahci_controller.cpp b/sys/denali/ahci/ahci_controller.cpp index 67c7079..465b589 100644 --- a/sys/denali/ahci/ahci_controller.cpp +++ b/sys/denali/ahci/ahci_controller.cpp @@ -243,12 +243,8 @@ glcr::ErrorCode AhciController::LoadDevices() { } devices_[i] = new AhciPort(reinterpret_cast(port_addr)); - - if (devices_[i]->IsSata()) { - IdentifyDeviceCommand identify(devices_[i].get()); - devices_[i]->IssueCommand(&identify); - identify.WaitComplete(); - } + // TODO: Maybe continue to the next device if this fails. + RET_ERR(devices_[i]->Identify()); } return glcr::OK; } diff --git a/sys/denali/ahci/ahci_port.cpp b/sys/denali/ahci/ahci_port.cpp index add488e..8c4b754 100644 --- a/sys/denali/ahci/ahci_port.cpp +++ b/sys/denali/ahci/ahci_port.cpp @@ -28,6 +28,7 @@ AhciPort::AhciPort(AhciPortHba* port) : port_struct_(port) { command_tables_ = glcr::ArrayView( reinterpret_cast(command_structures_.vaddr() + 0x500), 32); + 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 = @@ -41,7 +42,17 @@ AhciPort::AhciPort(AhciPortHba* port) : port_struct_(port) { port_struct_->command |= kCommand_Start; } -glcr::ErrorCode AhciPort::IssueCommand(Command* command) { +glcr::ErrorCode AhciPort::Identify() { + if (IsSata()) { + IdentifyDeviceCommand identify(this); + ASSIGN_OR_RETURN(auto* sem, IssueCommand(&identify)); + sem->Wait(); + identify.OnComplete(); + } + return glcr::OK; +} + +glcr::ErrorOr AhciPort::IssueCommand(Command* command) { uint64_t slot; for (slot = 0; slot < 32; slot++) { if (commands_[slot] == nullptr) { @@ -65,7 +76,7 @@ glcr::ErrorCode AhciPort::IssueCommand(Command* command) { commands_issued_ |= (1 << slot); port_struct_->command_issue |= (1 << slot); - return glcr::OK; + return &command_signals_[slot]; } void AhciPort::DumpInfo() { @@ -152,7 +163,7 @@ void AhciPort::HandleIrq() { if (commands_finished & (1 << i)) { commands_issued_ &= ~(1 << i); // FIXME: Pass error codes to the callback. - commands_[i]->SignalComplete(); + command_signals_[i].Signal(); commands_[i] = nullptr; } } diff --git a/sys/denali/ahci/ahci_port.h b/sys/denali/ahci/ahci_port.h index e7e1a75..1a74975 100644 --- a/sys/denali/ahci/ahci_port.h +++ b/sys/denali/ahci/ahci_port.h @@ -1,7 +1,9 @@ #pragma once +#include #include #include +#include #include #include @@ -19,7 +21,9 @@ class AhciPort { bool IsSata() { return port_struct_->signature == 0x101; } bool IsInit() { return port_struct_ != nullptr && command_structures_; } - glcr::ErrorCode IssueCommand(Command* command); + glcr::ErrorCode Identify(); + + glcr::ErrorOr IssueCommand(Command* command); void HandleIrq(); @@ -35,5 +39,6 @@ class AhciPort { 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 8a1d388..57cc96a 100644 --- a/sys/denali/ahci/command.cpp +++ b/sys/denali/ahci/command.cpp @@ -19,12 +19,6 @@ void* memcpy(void* dest, const void* src, uint64_t count) { Command::~Command() {} -void Command::SignalComplete() { - OnComplete(); - callback_semaphore_.Signal(); -} -void Command::WaitComplete() { callback_semaphore_.Wait(); } - void IdentifyDeviceCommand::PopulateFis(uint8_t* command_fis) { HostToDeviceRegisterFis fis __attribute__((aligned(16))){ .fis_type = FIS_TYPE_REG_H2D, diff --git a/sys/denali/ahci/command.h b/sys/denali/ahci/command.h index b9a3c2d..e7c6442 100644 --- a/sys/denali/ahci/command.h +++ b/sys/denali/ahci/command.h @@ -14,15 +14,6 @@ class Command { virtual ~Command(); virtual void PopulateFis(uint8_t* command_fis) = 0; virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) = 0; - void WaitComplete(); - void SignalComplete(); - - virtual void OnComplete() {} - - private: - // TODO: Make this owned by the device so that we don't have to create a new - // one with the kernel every time a command is issued. - mmth::Semaphore callback_semaphore_; }; class IdentifyDeviceCommand : public Command { @@ -31,7 +22,7 @@ class IdentifyDeviceCommand : public Command { virtual void PopulateFis(uint8_t* command_fis) override; virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) override; - virtual void OnComplete() override; + void OnComplete(); private: AhciPort* port_; diff --git a/sys/denali/denali_server.cpp b/sys/denali/denali_server.cpp index db8eb0a..0de18ff 100644 --- a/sys/denali/denali_server.cpp +++ b/sys/denali/denali_server.cpp @@ -21,9 +21,8 @@ glcr::Status DenaliServer::HandleRead(const ReadRequest& req, mmth::OwnedMemoryRegion::ContiguousPhysical(req.size() * 512, &paddr); DmaReadCommand command(req.lba(), req.size(), paddr); - device->IssueCommand(&command); - - command.WaitComplete(); + ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(&command)); + semaphore->Wait(); resp.set_device_id(req.device_id()); resp.set_size(req.size()); @@ -51,8 +50,8 @@ 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); - device->IssueCommand(&command); - command.WaitComplete(); + ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(&command)); + semaphore->Wait(); region_paddr += size * 512; }