[Denali] No longer store Commands on the port.
This commit is contained in:
parent
28a0f02b05
commit
e71017070f
|
@ -25,14 +25,14 @@ class OwnedMemoryRegion {
|
||||||
static OwnedMemoryRegion ContiguousPhysical(uint64_t size, uint64_t* paddr);
|
static OwnedMemoryRegion ContiguousPhysical(uint64_t size, uint64_t* paddr);
|
||||||
static OwnedMemoryRegion DirectPhysical(uint64_t paddr, uint64_t size);
|
static OwnedMemoryRegion DirectPhysical(uint64_t paddr, uint64_t size);
|
||||||
|
|
||||||
uint64_t vaddr() { return vaddr_; }
|
uint64_t vaddr() const { return vaddr_; }
|
||||||
uint64_t size() { return size_; }
|
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();
|
z_cap_t DuplicateCap();
|
||||||
|
|
||||||
bool empty() { return vmmo_cap_ != 0; }
|
bool empty() const { return vmmo_cap_ == 0; }
|
||||||
explicit operator bool() { return vmmo_cap_ != 0; }
|
explicit operator bool() const { return vmmo_cap_ != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OwnedMemoryRegion(uint64_t vmmo_cap, uint64_t vaddr, uint64_t size)
|
OwnedMemoryRegion(uint64_t vmmo_cap, uint64_t vaddr, uint64_t size)
|
||||||
|
|
|
@ -28,12 +28,12 @@ AhciPort::AhciPort(AhciPortHba* port) : port_struct_(port) {
|
||||||
command_tables_ = glcr::ArrayView(
|
command_tables_ = glcr::ArrayView(
|
||||||
reinterpret_cast<CommandTable*>(command_structures_.vaddr() + 0x500), 32);
|
reinterpret_cast<CommandTable*>(command_structures_.vaddr() + 0x500), 32);
|
||||||
|
|
||||||
|
commands_issued_ = 0;
|
||||||
command_signals_ = glcr::Array<mmth::Semaphore>(32);
|
command_signals_ = glcr::Array<mmth::Semaphore>(32);
|
||||||
for (uint64_t i = 0; i < 32; i++) {
|
for (uint64_t i = 0; i < 32; i++) {
|
||||||
// This leaves space for 2 prdt entries.
|
// This leaves space for 2 prdt entries.
|
||||||
command_list_->command_headers[i].command_table_base_addr =
|
command_list_->command_headers[i].command_table_base_addr =
|
||||||
(paddr + 0x500) + (0x100 * i);
|
(paddr + 0x500) + (0x100 * i);
|
||||||
commands_[i] = nullptr;
|
|
||||||
}
|
}
|
||||||
port_struct_->interrupt_enable = 0xFFFFFFFF;
|
port_struct_->interrupt_enable = 0xFFFFFFFF;
|
||||||
// kInterrupt_D2H_FIS | kInterrupt_PIO_FIS | kInterrupt_DMA_FIS |
|
// kInterrupt_D2H_FIS | kInterrupt_PIO_FIS | kInterrupt_DMA_FIS |
|
||||||
|
@ -45,17 +45,17 @@ AhciPort::AhciPort(AhciPortHba* port) : port_struct_(port) {
|
||||||
glcr::ErrorCode AhciPort::Identify() {
|
glcr::ErrorCode AhciPort::Identify() {
|
||||||
if (IsSata()) {
|
if (IsSata()) {
|
||||||
IdentifyDeviceCommand identify(this);
|
IdentifyDeviceCommand identify(this);
|
||||||
ASSIGN_OR_RETURN(auto* sem, IssueCommand(&identify));
|
ASSIGN_OR_RETURN(auto* sem, IssueCommand(identify));
|
||||||
sem->Wait();
|
sem->Wait();
|
||||||
identify.OnComplete();
|
identify.OnComplete();
|
||||||
}
|
}
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorOr<mmth::Semaphore*> AhciPort::IssueCommand(Command* command) {
|
glcr::ErrorOr<mmth::Semaphore*> AhciPort::IssueCommand(const Command& command) {
|
||||||
uint64_t slot;
|
uint64_t slot;
|
||||||
for (slot = 0; slot < 32; slot++) {
|
for (slot = 0; slot < 32; slot++) {
|
||||||
if (commands_[slot] == nullptr) {
|
if (!(commands_issued_ & (1 << slot))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,16 +63,14 @@ glcr::ErrorOr<mmth::Semaphore*> AhciPort::IssueCommand(Command* command) {
|
||||||
dbgln("All slots full");
|
dbgln("All slots full");
|
||||||
return glcr::INTERNAL;
|
return glcr::INTERNAL;
|
||||||
}
|
}
|
||||||
command->PopulateFis(command_tables_[slot].command_fis);
|
command.PopulateFis(command_tables_[slot].command_fis);
|
||||||
command->PopulatePrdt(command_tables_[slot].prdt);
|
command.PopulatePrdt(command_tables_[slot].prdt);
|
||||||
|
|
||||||
command_list_->command_headers[slot].command =
|
command_list_->command_headers[slot].command =
|
||||||
(sizeof(HostToDeviceRegisterFis) / 2) & 0x1F | (1 << 7);
|
(sizeof(HostToDeviceRegisterFis) / 2) & 0x1F | (1 << 7);
|
||||||
command_list_->command_headers[slot].prd_table_length = 1;
|
command_list_->command_headers[slot].prd_table_length = 1;
|
||||||
command_list_->command_headers[slot].prd_byte_count = 0;
|
command_list_->command_headers[slot].prd_byte_count = 0;
|
||||||
|
|
||||||
commands_[slot] = command;
|
|
||||||
|
|
||||||
commands_issued_ |= (1 << slot);
|
commands_issued_ |= (1 << slot);
|
||||||
port_struct_->command_issue |= (1 << slot);
|
port_struct_->command_issue |= (1 << slot);
|
||||||
|
|
||||||
|
@ -161,10 +159,9 @@ void AhciPort::HandleIrq() {
|
||||||
|
|
||||||
for (uint64_t i = 0; i < 32; i++) {
|
for (uint64_t i = 0; i < 32; i++) {
|
||||||
if (commands_finished & (1 << i)) {
|
if (commands_finished & (1 << i)) {
|
||||||
commands_issued_ &= ~(1 << i);
|
// TODO: Pass error codes to the callback.
|
||||||
// FIXME: Pass error codes to the callback.
|
|
||||||
command_signals_[i].Signal();
|
command_signals_[i].Signal();
|
||||||
commands_[i] = nullptr;
|
commands_issued_ &= ~(1 << i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ class AhciPort {
|
||||||
|
|
||||||
glcr::ErrorCode Identify();
|
glcr::ErrorCode Identify();
|
||||||
|
|
||||||
glcr::ErrorOr<mmth::Semaphore*> IssueCommand(Command* command);
|
glcr::ErrorOr<mmth::Semaphore*> IssueCommand(const Command& command);
|
||||||
|
|
||||||
void HandleIrq();
|
void HandleIrq();
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ class AhciPort {
|
||||||
volatile ReceivedFis* received_fis_ = nullptr;
|
volatile ReceivedFis* received_fis_ = nullptr;
|
||||||
glcr::ArrayView<CommandTable> command_tables_;
|
glcr::ArrayView<CommandTable> command_tables_;
|
||||||
|
|
||||||
Command* commands_[32];
|
|
||||||
glcr::Array<mmth::Semaphore> command_signals_;
|
glcr::Array<mmth::Semaphore> command_signals_;
|
||||||
uint32_t commands_issued_ = 0;
|
uint32_t commands_issued_ = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,7 +19,7 @@ void* memcpy(void* dest, const void* src, uint64_t count) {
|
||||||
|
|
||||||
Command::~Command() {}
|
Command::~Command() {}
|
||||||
|
|
||||||
void IdentifyDeviceCommand::PopulateFis(uint8_t* command_fis) {
|
void IdentifyDeviceCommand::PopulateFis(uint8_t* command_fis) const {
|
||||||
HostToDeviceRegisterFis fis __attribute__((aligned(16))){
|
HostToDeviceRegisterFis fis __attribute__((aligned(16))){
|
||||||
.fis_type = FIS_TYPE_REG_H2D,
|
.fis_type = FIS_TYPE_REG_H2D,
|
||||||
.pmp_and_c = 0x80,
|
.pmp_and_c = 0x80,
|
||||||
|
@ -30,7 +30,7 @@ void IdentifyDeviceCommand::PopulateFis(uint8_t* command_fis) {
|
||||||
memcpy(command_fis, &fis, sizeof(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].region_address = paddr_;
|
||||||
prdt[0].byte_count = 0x200 - 1;
|
prdt[0].byte_count = 0x200 - 1;
|
||||||
dbgln("paddr: {x}", paddr_);
|
dbgln("paddr: {x}", paddr_);
|
||||||
|
@ -56,7 +56,7 @@ DmaReadCommand::DmaReadCommand(uint64_t lba, uint64_t sector_cnt,
|
||||||
|
|
||||||
DmaReadCommand::~DmaReadCommand() {}
|
DmaReadCommand::~DmaReadCommand() {}
|
||||||
|
|
||||||
void DmaReadCommand::PopulateFis(uint8_t* command_fis) {
|
void DmaReadCommand::PopulateFis(uint8_t* command_fis) const {
|
||||||
HostToDeviceRegisterFis fis{
|
HostToDeviceRegisterFis fis{
|
||||||
.fis_type = FIS_TYPE_REG_H2D,
|
.fis_type = FIS_TYPE_REG_H2D,
|
||||||
.pmp_and_c = 0x80,
|
.pmp_and_c = 0x80,
|
||||||
|
@ -83,7 +83,7 @@ void DmaReadCommand::PopulateFis(uint8_t* command_fis) {
|
||||||
memcpy(command_fis, &fis, sizeof(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].region_address = paddr_;
|
||||||
prdt[0].byte_count = sector_cnt_ * 512;
|
prdt[0].byte_count = sector_cnt_ * 512;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,15 +12,15 @@ class Command {
|
||||||
public:
|
public:
|
||||||
Command() = default;
|
Command() = default;
|
||||||
virtual ~Command();
|
virtual ~Command();
|
||||||
virtual void PopulateFis(uint8_t* command_fis) = 0;
|
virtual void PopulateFis(uint8_t* command_fis) const = 0;
|
||||||
virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) = 0;
|
virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IdentifyDeviceCommand : public Command {
|
class IdentifyDeviceCommand : public Command {
|
||||||
public:
|
public:
|
||||||
IdentifyDeviceCommand(AhciPort* port) : port_(port) {}
|
IdentifyDeviceCommand(AhciPort* port) : port_(port) {}
|
||||||
virtual void PopulateFis(uint8_t* command_fis) override;
|
virtual void PopulateFis(uint8_t* command_fis) const override;
|
||||||
virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) override;
|
virtual void PopulatePrdt(PhysicalRegionDescriptor* prdt) const override;
|
||||||
|
|
||||||
void OnComplete();
|
void OnComplete();
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ class DmaReadCommand : public Command {
|
||||||
|
|
||||||
virtual ~DmaReadCommand() override;
|
virtual ~DmaReadCommand() override;
|
||||||
|
|
||||||
void PopulateFis(uint8_t* command_fis) override;
|
void PopulateFis(uint8_t* command_fis) const override;
|
||||||
void PopulatePrdt(PhysicalRegionDescriptor* prdt) override;
|
void PopulatePrdt(PhysicalRegionDescriptor* prdt) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t lba_;
|
uint64_t lba_;
|
||||||
|
|
|
@ -21,7 +21,7 @@ glcr::Status DenaliServer::HandleRead(const ReadRequest& req,
|
||||||
mmth::OwnedMemoryRegion::ContiguousPhysical(req.size() * 512, &paddr);
|
mmth::OwnedMemoryRegion::ContiguousPhysical(req.size() * 512, &paddr);
|
||||||
|
|
||||||
DmaReadCommand command(req.lba(), req.size(), 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();
|
semaphore->Wait();
|
||||||
|
|
||||||
resp.set_device_id(req.device_id());
|
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 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);
|
DmaReadCommand command(lba, size, region_paddr);
|
||||||
ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(&command));
|
ASSIGN_OR_RETURN(auto semaphore, device->IssueCommand(command));
|
||||||
semaphore->Wait();
|
semaphore->Wait();
|
||||||
|
|
||||||
region_paddr += size * 512;
|
region_paddr += size * 512;
|
||||||
|
|
Loading…
Reference in New Issue