From b41784b93859ffb3c369aebfe00e7a5b3fbe4ba8 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Tue, 13 Feb 2024 19:39:55 -0800 Subject: [PATCH] [Voyageurs] Create an abstraction for managing TRBs. --- sys/voyageurs/CMakeLists.txt | 2 ++ sys/voyageurs/xhci/trb.cpp | 10 ++++++++++ sys/voyageurs/xhci/trb.h | 5 +++++ sys/voyageurs/xhci/trb_ring.cpp | 24 ++++++++++++++++++++++++ sys/voyageurs/xhci/trb_ring.h | 26 ++++++++++++++++++++++++++ sys/voyageurs/xhci/xhci.h | 15 ++++----------- sys/voyageurs/xhci/xhci_driver.cpp | 29 ++++------------------------- sys/voyageurs/xhci/xhci_driver.h | 7 +++---- 8 files changed, 78 insertions(+), 40 deletions(-) create mode 100644 sys/voyageurs/xhci/trb.cpp create mode 100644 sys/voyageurs/xhci/trb.h create mode 100644 sys/voyageurs/xhci/trb_ring.cpp create mode 100644 sys/voyageurs/xhci/trb_ring.h diff --git a/sys/voyageurs/CMakeLists.txt b/sys/voyageurs/CMakeLists.txt index 6dc7fce..8ef1302 100644 --- a/sys/voyageurs/CMakeLists.txt +++ b/sys/voyageurs/CMakeLists.txt @@ -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) diff --git a/sys/voyageurs/xhci/trb.cpp b/sys/voyageurs/xhci/trb.cpp new file mode 100644 index 0000000..f11c093 --- /dev/null +++ b/sys/voyageurs/xhci/trb.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, + }; +} diff --git a/sys/voyageurs/xhci/trb.h b/sys/voyageurs/xhci/trb.h new file mode 100644 index 0000000..333f883 --- /dev/null +++ b/sys/voyageurs/xhci/trb.h @@ -0,0 +1,5 @@ +#pragma once + +#include "xhci/xhci.h" + +XhciTrb CreateLinkTrb(uint64_t physical_address); diff --git a/sys/voyageurs/xhci/trb_ring.cpp b/sys/voyageurs/xhci/trb_ring.cpp new file mode 100644 index 0000000..0e1eb66 --- /dev/null +++ b/sys/voyageurs/xhci/trb_ring.cpp @@ -0,0 +1,24 @@ +#include "xhci/trb_ring.h" + +#include + +#include "xhci/trb.h" + +TrbRing::TrbRing() { + uint64_t number_trbs = 0x1000 / sizeof(XhciTrb); + page_ = mmth::OwnedMemoryRegion::ContiguousPhysical(0x1000, &phys_address_); + trb_list_ = glcr::ArrayView( + reinterpret_cast(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; +} diff --git a/sys/voyageurs/xhci/trb_ring.h b/sys/voyageurs/xhci/trb_ring.h new file mode 100644 index 0000000..8682fdb --- /dev/null +++ b/sys/voyageurs/xhci/trb_ring.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include "xhci/xhci.h" + +class TrbRing { + public: + TrbRing(); + + uint64_t PhysicalAddress() { return phys_address_; } + + protected: + uint64_t phys_address_; + mmth::OwnedMemoryRegion page_; + glcr::ArrayView trb_list_; +}; + +class TrbRingWriter : public TrbRing { + public: + void EnqueueTrb(const XhciTrb& trb); + + private: + uint64_t enqueue_ptr_ = 0; +}; diff --git a/sys/voyageurs/xhci/xhci.h b/sys/voyageurs/xhci/xhci.h index 73b9f03..8a18469 100644 --- a/sys/voyageurs/xhci/xhci.h +++ b/sys/voyageurs/xhci/xhci.h @@ -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 { diff --git a/sys/voyageurs/xhci/xhci_driver.cpp b/sys/voyageurs/xhci/xhci_driver.cpp index eb449d1..f9a87b3 100644 --- a/sys/voyageurs/xhci/xhci_driver.cpp +++ b/sys/voyageurs/xhci/xhci_driver.cpp @@ -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(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(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( 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(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; diff --git a/sys/voyageurs/xhci/xhci_driver.h b/sys/voyageurs/xhci/xhci_driver.h index d263fc9..0d05b01 100644 --- a/sys/voyageurs/xhci/xhci_driver.h +++ b/sys/voyageurs/xhci/xhci_driver.h @@ -4,6 +4,7 @@ #include #include +#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);