[Denali] Move AHCI read to internal method as well.
This commit is contained in:
parent
3e1da2bc90
commit
69ce3028fa
|
@ -1,7 +1,6 @@
|
|||
add_executable(denali
|
||||
ahci/ahci_controller.cpp
|
||||
ahci/ahci_port.cpp
|
||||
ahci/command.cpp
|
||||
denali.cpp
|
||||
denali_server.cpp
|
||||
)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue