[Voyageurs] Create an abstraction for managing TRBs.

This commit is contained in:
Drew Galbraith 2024-02-13 19:39:55 -08:00
parent 2228b5b52e
commit b41784b938
8 changed files with 78 additions and 40 deletions

View File

@ -1,5 +1,7 @@
add_executable(voyageurs
keyboard/keyboard_driver.cpp
xhci/trb.cpp
xhci/trb_ring.cpp
xhci/xhci_driver.cpp
voyageurs_server.cpp
voyageurs.cpp)

View File

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

5
sys/voyageurs/xhci/trb.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include "xhci/xhci.h"
XhciTrb CreateLinkTrb(uint64_t physical_address);

View File

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

View File

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

View File

@ -106,18 +106,11 @@ struct XhciDeviceContext {
XhciEndpointContext endpoint_contexts[31];
} __attribute__((packed));
struct XhciCommandTrb {
uint64_t reserved1;
uint32_t reserved2;
struct XhciTrb {
uint64_t parameter;
uint32_t status;
uint16_t type_and_cycle;
uint16_t slot_type;
} __attribute__((packed));
struct XhciLinkTrb {
uint64_t link_address;
uint32_t interrupter_target;
uint16_t type_and_cycle;
uint16_t reserved;
uint16_t control;
} __attribute__((packed));
struct XhciEventRingSegmentTableEntry {

View File

@ -116,22 +116,7 @@ glcr::ErrorCode XhciDriver::ResetController() {
}
glcr::ErrorCode XhciDriver::InitiateCommandRing() {
uint64_t command_ring_phys;
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;
operational_->command_ring_control = command_ring_.PhysicalAddress();
return glcr::OK;
}
@ -165,15 +150,9 @@ glcr::ErrorCode XhciDriver::InitiateEventRingSegmentTable() {
event_ring_segment_table_ = reinterpret_cast<XhciEventRingSegmentTableEntry*>(
event_ring_segment_table_mem_.vaddr());
uint64_t ers_phys;
event_ring_segment_mem_ =
mmth::OwnedMemoryRegion::ContiguousPhysical(0x1000, &ers_phys);
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;
uint64_t ers_size = 0x1000 / sizeof(XhciTrb);
event_ring_segment_table_[0].ring_segment_base =
event_ring_.PhysicalAddress();
event_ring_segment_table_[0].ring_segment_size = ers_size & 0xFFFF;
runtime_->interrupters[0].event_ring_segment_table_base_address = erst_phys;

View File

@ -4,6 +4,7 @@
#include <mammoth/util/memory_region.h>
#include <yellowstone/yellowstone.yunq.client.h>
#include "xhci/trb_ring.h"
#include "xhci/xhci.h"
class XhciDriver {
@ -26,8 +27,7 @@ class XhciDriver {
// TODO: Doorbell Array.
// Host Memory Regions.
mmth::OwnedMemoryRegion command_ring_mem_;
XhciCommandTrb* command_trb_;
TrbRingWriter command_ring_;
mmth::OwnedMemoryRegion device_context_base_array_mem_;
uint64_t* device_context_base_array_;
@ -35,8 +35,7 @@ class XhciDriver {
mmth::OwnedMemoryRegion event_ring_segment_table_mem_;
XhciEventRingSegmentTableEntry* event_ring_segment_table_;
mmth::OwnedMemoryRegion event_ring_segment_mem_;
XhciCommandTrb* event_ring_segment_;
TrbRing event_ring_;
XhciDriver(mmth::OwnedMemoryRegion&& pci_space);