[Denali] Move AHCI read to internal method as well.

This commit is contained in:
Drew Galbraith 2023-12-08 15:11:56 -08:00
parent 3e1da2bc90
commit 69ce3028fa
6 changed files with 19 additions and 117 deletions

View File

@ -1,7 +1,6 @@
add_executable(denali
ahci/ahci_controller.cpp
ahci/ahci_port.cpp
ahci/command.cpp
denali.cpp
denali_server.cpp
)

View File

@ -63,29 +63,16 @@ glcr::ErrorCode AhciPort::Identify() {
return glcr::OK;
}
glcr::ErrorOr<mmth::Semaphore*> 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<mmth::Semaphore*> 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<mmth::Semaphore*> AhciPort::IssueCommand(

View File

@ -4,6 +4,7 @@
#include <glacier/container/array_view.h>
#include <glacier/status/error.h>
#include <glacier/status/error_or.h>
#include <mammoth/sync/semaphore.h>
#include <mammoth/util/memory_region.h>
#include <ztypes.h>
@ -23,8 +24,8 @@ class AhciPort {
glcr::ErrorCode Identify();
glcr::ErrorOr<mmth::Semaphore*> IssueCommand(const Command& command);
glcr::ErrorOr<mmth::Semaphore*> IssueCommand(const CommandInfo& command);
glcr::ErrorOr<mmth::Semaphore*> IssueRead(uint64_t lba, uint16_t sector_cnt,
uint64_t paddr);
void HandleIrq();
@ -41,4 +42,6 @@ class AhciPort {
glcr::Array<mmth::Semaphore> command_signals_;
uint32_t commands_issued_ = 0;
glcr::ErrorOr<mmth::Semaphore*> IssueCommand(const CommandInfo& command);
};

View File

@ -1,58 +0,0 @@
#include "ahci/command.h"
#include <mammoth/util/debug.h>
#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<uint8_t>(lba_ & 0xFF),
.lba1 = static_cast<uint8_t>((lba_ >> 8) & 0xFF),
.lba2 = static_cast<uint8_t>((lba_ >> 16) & 0xFF),
.device = (1 << 6), // ATA LBA Mode
.lba3 = static_cast<uint8_t>((lba_ >> 24) & 0xFF),
.lba4 = static_cast<uint8_t>((lba_ >> 32) & 0xFF),
.lba5 = static_cast<uint8_t>((lba_ >> 40) & 0xFF),
.featureh = 0,
.count = static_cast<uint16_t>(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;
}

View File

@ -1,39 +1,10 @@
#pragma once
#include <mammoth/sync/semaphore.h>
#include <mammoth/util/memory_region.h>
#include <stdint.h>
#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_;
};

View File

@ -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;