[Voyageurs] Create an abstraction for managing TRBs.
This commit is contained in:
parent
2228b5b52e
commit
b41784b938
|
@ -1,5 +1,7 @@
|
||||||
add_executable(voyageurs
|
add_executable(voyageurs
|
||||||
keyboard/keyboard_driver.cpp
|
keyboard/keyboard_driver.cpp
|
||||||
|
xhci/trb.cpp
|
||||||
|
xhci/trb_ring.cpp
|
||||||
xhci/xhci_driver.cpp
|
xhci/xhci_driver.cpp
|
||||||
voyageurs_server.cpp
|
voyageurs_server.cpp
|
||||||
voyageurs.cpp)
|
voyageurs.cpp)
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "xhci/trb.h"
|
||||||
|
|
||||||
|
XhciTrb CreateLinkTrb(uint64_t physical_address) {
|
||||||
|
return {
|
||||||
|
.parameter = physical_address,
|
||||||
|
.status = 0,
|
||||||
|
.type_and_cycle = 6 << 10,
|
||||||
|
.control = 0,
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xhci/xhci.h"
|
||||||
|
|
||||||
|
XhciTrb CreateLinkTrb(uint64_t physical_address);
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "xhci/trb_ring.h"
|
||||||
|
|
||||||
|
#include <mammoth/util/debug.h>
|
||||||
|
|
||||||
|
#include "xhci/trb.h"
|
||||||
|
|
||||||
|
TrbRing::TrbRing() {
|
||||||
|
uint64_t number_trbs = 0x1000 / sizeof(XhciTrb);
|
||||||
|
page_ = mmth::OwnedMemoryRegion::ContiguousPhysical(0x1000, &phys_address_);
|
||||||
|
trb_list_ = glcr::ArrayView<XhciTrb>(
|
||||||
|
reinterpret_cast<XhciTrb*>(page_.vaddr()), number_trbs);
|
||||||
|
|
||||||
|
// Point the end of the command ring back to the start.
|
||||||
|
trb_list_[trb_list_.size() - 1] = CreateLinkTrb(phys_address_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrbRingWriter::EnqueueTrb(const XhciTrb& trb) {
|
||||||
|
uint64_t ptr = enqueue_ptr_++;
|
||||||
|
if (enqueue_ptr_ == trb_list_.size()) {
|
||||||
|
crash("Not implemented: queue wrapping", glcr::UNIMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
trb_list_[ptr] = trb;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/container/array_view.h>
|
||||||
|
#include <mammoth/util/memory_region.h>
|
||||||
|
|
||||||
|
#include "xhci/xhci.h"
|
||||||
|
|
||||||
|
class TrbRing {
|
||||||
|
public:
|
||||||
|
TrbRing();
|
||||||
|
|
||||||
|
uint64_t PhysicalAddress() { return phys_address_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint64_t phys_address_;
|
||||||
|
mmth::OwnedMemoryRegion page_;
|
||||||
|
glcr::ArrayView<XhciTrb> trb_list_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TrbRingWriter : public TrbRing {
|
||||||
|
public:
|
||||||
|
void EnqueueTrb(const XhciTrb& trb);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint64_t enqueue_ptr_ = 0;
|
||||||
|
};
|
|
@ -106,18 +106,11 @@ struct XhciDeviceContext {
|
||||||
XhciEndpointContext endpoint_contexts[31];
|
XhciEndpointContext endpoint_contexts[31];
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct XhciCommandTrb {
|
struct XhciTrb {
|
||||||
uint64_t reserved1;
|
uint64_t parameter;
|
||||||
uint32_t reserved2;
|
uint32_t status;
|
||||||
uint16_t type_and_cycle;
|
uint16_t type_and_cycle;
|
||||||
uint16_t slot_type;
|
uint16_t control;
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct XhciLinkTrb {
|
|
||||||
uint64_t link_address;
|
|
||||||
uint32_t interrupter_target;
|
|
||||||
uint16_t type_and_cycle;
|
|
||||||
uint16_t reserved;
|
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct XhciEventRingSegmentTableEntry {
|
struct XhciEventRingSegmentTableEntry {
|
||||||
|
|
|
@ -116,22 +116,7 @@ glcr::ErrorCode XhciDriver::ResetController() {
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorCode XhciDriver::InitiateCommandRing() {
|
glcr::ErrorCode XhciDriver::InitiateCommandRing() {
|
||||||
uint64_t command_ring_phys;
|
operational_->command_ring_control = command_ring_.PhysicalAddress();
|
||||||
command_ring_mem_ =
|
|
||||||
mmth::OwnedMemoryRegion::ContiguousPhysical(0x1000, &command_ring_phys);
|
|
||||||
command_trb_ = reinterpret_cast<XhciCommandTrb*>(command_ring_mem_.vaddr());
|
|
||||||
|
|
||||||
uint64_t number_trbs = 0x1000 / sizeof(XhciCommandTrb);
|
|
||||||
|
|
||||||
// Point the end of the command ring back to the start.
|
|
||||||
auto* link_trb =
|
|
||||||
reinterpret_cast<XhciLinkTrb*>(command_trb_ + number_trbs - 1);
|
|
||||||
link_trb->link_address = command_ring_phys;
|
|
||||||
// TODO: Cleaner interface for specifying a command type.
|
|
||||||
link_trb->type_and_cycle = 0x6 << 10;
|
|
||||||
|
|
||||||
operational_->command_ring_control = command_ring_phys;
|
|
||||||
|
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,15 +150,9 @@ glcr::ErrorCode XhciDriver::InitiateEventRingSegmentTable() {
|
||||||
event_ring_segment_table_ = reinterpret_cast<XhciEventRingSegmentTableEntry*>(
|
event_ring_segment_table_ = reinterpret_cast<XhciEventRingSegmentTableEntry*>(
|
||||||
event_ring_segment_table_mem_.vaddr());
|
event_ring_segment_table_mem_.vaddr());
|
||||||
|
|
||||||
uint64_t ers_phys;
|
uint64_t ers_size = 0x1000 / sizeof(XhciTrb);
|
||||||
event_ring_segment_mem_ =
|
event_ring_segment_table_[0].ring_segment_base =
|
||||||
mmth::OwnedMemoryRegion::ContiguousPhysical(0x1000, &ers_phys);
|
event_ring_.PhysicalAddress();
|
||||||
uint64_t ers_size = 0x1000 / sizeof(XhciCommandTrb);
|
|
||||||
|
|
||||||
event_ring_segment_ =
|
|
||||||
reinterpret_cast<XhciCommandTrb*>(event_ring_segment_mem_.vaddr());
|
|
||||||
|
|
||||||
event_ring_segment_table_[0].ring_segment_base = ers_phys;
|
|
||||||
event_ring_segment_table_[0].ring_segment_size = ers_size & 0xFFFF;
|
event_ring_segment_table_[0].ring_segment_size = ers_size & 0xFFFF;
|
||||||
|
|
||||||
runtime_->interrupters[0].event_ring_segment_table_base_address = erst_phys;
|
runtime_->interrupters[0].event_ring_segment_table_base_address = erst_phys;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <mammoth/util/memory_region.h>
|
#include <mammoth/util/memory_region.h>
|
||||||
#include <yellowstone/yellowstone.yunq.client.h>
|
#include <yellowstone/yellowstone.yunq.client.h>
|
||||||
|
|
||||||
|
#include "xhci/trb_ring.h"
|
||||||
#include "xhci/xhci.h"
|
#include "xhci/xhci.h"
|
||||||
|
|
||||||
class XhciDriver {
|
class XhciDriver {
|
||||||
|
@ -26,8 +27,7 @@ class XhciDriver {
|
||||||
// TODO: Doorbell Array.
|
// TODO: Doorbell Array.
|
||||||
|
|
||||||
// Host Memory Regions.
|
// Host Memory Regions.
|
||||||
mmth::OwnedMemoryRegion command_ring_mem_;
|
TrbRingWriter command_ring_;
|
||||||
XhciCommandTrb* command_trb_;
|
|
||||||
|
|
||||||
mmth::OwnedMemoryRegion device_context_base_array_mem_;
|
mmth::OwnedMemoryRegion device_context_base_array_mem_;
|
||||||
uint64_t* device_context_base_array_;
|
uint64_t* device_context_base_array_;
|
||||||
|
@ -35,8 +35,7 @@ class XhciDriver {
|
||||||
mmth::OwnedMemoryRegion event_ring_segment_table_mem_;
|
mmth::OwnedMemoryRegion event_ring_segment_table_mem_;
|
||||||
XhciEventRingSegmentTableEntry* event_ring_segment_table_;
|
XhciEventRingSegmentTableEntry* event_ring_segment_table_;
|
||||||
|
|
||||||
mmth::OwnedMemoryRegion event_ring_segment_mem_;
|
TrbRing event_ring_;
|
||||||
XhciCommandTrb* event_ring_segment_;
|
|
||||||
|
|
||||||
XhciDriver(mmth::OwnedMemoryRegion&& pci_space);
|
XhciDriver(mmth::OwnedMemoryRegion&& pci_space);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue