[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
|
add_executable(denali
|
||||||
ahci/ahci_controller.cpp
|
ahci/ahci_controller.cpp
|
||||||
ahci/ahci_port.cpp
|
ahci/ahci_port.cpp
|
||||||
ahci/command.cpp
|
|
||||||
denali.cpp
|
denali.cpp
|
||||||
denali_server.cpp
|
denali_server.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -63,29 +63,16 @@ glcr::ErrorCode AhciPort::Identify() {
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorOr<mmth::Semaphore*> AhciPort::IssueCommand(const Command& command) {
|
glcr::ErrorOr<mmth::Semaphore*> AhciPort::IssueRead(uint64_t lba,
|
||||||
uint64_t slot;
|
uint16_t sector_cnt,
|
||||||
for (slot = 0; slot < 32; slot++) {
|
uint64_t paddr) {
|
||||||
if (!(commands_issued_ & (1 << slot))) {
|
CommandInfo read{
|
||||||
break;
|
.command = kDmaReadExt,
|
||||||
}
|
.lba = lba,
|
||||||
}
|
.sectors = sector_cnt,
|
||||||
if (slot == 32) {
|
.paddr = paddr,
|
||||||
dbgln("All slots full");
|
};
|
||||||
return glcr::INTERNAL;
|
return IssueCommand(read);
|
||||||
}
|
|
||||||
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::IssueCommand(
|
glcr::ErrorOr<mmth::Semaphore*> AhciPort::IssueCommand(
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <glacier/container/array_view.h>
|
#include <glacier/container/array_view.h>
|
||||||
#include <glacier/status/error.h>
|
#include <glacier/status/error.h>
|
||||||
#include <glacier/status/error_or.h>
|
#include <glacier/status/error_or.h>
|
||||||
|
#include <mammoth/sync/semaphore.h>
|
||||||
#include <mammoth/util/memory_region.h>
|
#include <mammoth/util/memory_region.h>
|
||||||
#include <ztypes.h>
|
#include <ztypes.h>
|
||||||
|
|
||||||
|
@ -23,8 +24,8 @@ class AhciPort {
|
||||||
|
|
||||||
glcr::ErrorCode Identify();
|
glcr::ErrorCode Identify();
|
||||||
|
|
||||||
glcr::ErrorOr<mmth::Semaphore*> IssueCommand(const Command& command);
|
glcr::ErrorOr<mmth::Semaphore*> IssueRead(uint64_t lba, uint16_t sector_cnt,
|
||||||
glcr::ErrorOr<mmth::Semaphore*> IssueCommand(const CommandInfo& command);
|
uint64_t paddr);
|
||||||
|
|
||||||
void HandleIrq();
|
void HandleIrq();
|
||||||
|
|
||||||
|
@ -41,4 +42,6 @@ class AhciPort {
|
||||||
|
|
||||||
glcr::Array<mmth::Semaphore> command_signals_;
|
glcr::Array<mmth::Semaphore> command_signals_;
|
||||||
uint32_t commands_issued_ = 0;
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <mammoth/sync/semaphore.h>
|
|
||||||
#include <mammoth/util/memory_region.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "ahci/ahci.h"
|
|
||||||
|
|
||||||
class AhciPort;
|
|
||||||
|
|
||||||
struct CommandInfo {
|
struct CommandInfo {
|
||||||
uint8_t command;
|
uint8_t command;
|
||||||
uint64_t lba;
|
uint64_t lba;
|
||||||
uint16_t sectors;
|
uint16_t sectors;
|
||||||
uint64_t paddr;
|
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 region =
|
||||||
mmth::OwnedMemoryRegion::ContiguousPhysical(req.size() * 512, &paddr);
|
mmth::OwnedMemoryRegion::ContiguousPhysical(req.size() * 512, &paddr);
|
||||||
|
|
||||||
DmaReadCommand command(req.lba(), req.size(), paddr);
|
ASSIGN_OR_RETURN(auto semaphore,
|
||||||
ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(command));
|
device->IssueRead(req.lba(), req.size(), paddr));
|
||||||
semaphore->Wait();
|
semaphore->Wait();
|
||||||
|
|
||||||
resp.set_device_id(req.device_id());
|
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++) {
|
for (uint64_t i = 0; i < req.lba().size(); i++) {
|
||||||
uint64_t lba = req.lba().at(i);
|
uint64_t lba = req.lba().at(i);
|
||||||
uint64_t size = req.sector_cnt().at(i);
|
uint64_t size = req.sector_cnt().at(i);
|
||||||
DmaReadCommand command(lba, size, region_paddr);
|
ASSIGN_OR_RETURN(auto semaphore,
|
||||||
ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(command));
|
device->IssueRead(lba, size, region_paddr));
|
||||||
semaphore->Wait();
|
semaphore->Wait();
|
||||||
|
|
||||||
region_paddr += size * 512;
|
region_paddr += size * 512;
|
||||||
|
|
Loading…
Reference in New Issue