[Voyageurs] Create an abstraction for managing TRBs.
This commit is contained in:
parent
2228b5b52e
commit
b41784b938
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
} __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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue