From c5f81952553e972db40283938d46ac2f02cd2a56 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Sat, 24 Feb 2024 14:18:11 -0800 Subject: [PATCH] [Voyageurs] Receive keypress information from the usb keyboard. --- sys/voyageurs/CMakeLists.txt | 1 + sys/voyageurs/xhci/device_slot.cpp | 19 ++++++++++++++---- sys/voyageurs/xhci/device_slot.h | 3 ++- sys/voyageurs/xhci/endpoint.cpp | 31 ++++++++++++++++++++++++++++++ sys/voyageurs/xhci/endpoint.h | 26 +++++++++++++++++++++++++ sys/voyageurs/xhci/xhci_driver.cpp | 2 ++ 6 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 sys/voyageurs/xhci/endpoint.cpp create mode 100644 sys/voyageurs/xhci/endpoint.h diff --git a/sys/voyageurs/CMakeLists.txt b/sys/voyageurs/CMakeLists.txt index 3c74de6..75a852c 100644 --- a/sys/voyageurs/CMakeLists.txt +++ b/sys/voyageurs/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable(voyageurs keyboard/keyboard_driver.cpp xhci/device_slot.cpp + xhci/endpoint.cpp xhci/trb.cpp xhci/trb_ring.cpp xhci/xhci_driver.cpp diff --git a/sys/voyageurs/xhci/device_slot.cpp b/sys/voyageurs/xhci/device_slot.cpp index 413b10b..ba6f29a 100644 --- a/sys/voyageurs/xhci/device_slot.cpp +++ b/sys/voyageurs/xhci/device_slot.cpp @@ -45,6 +45,8 @@ XhciTrb DeviceSlot::CreateAddressDeviceCommand(uint8_t root_port, input_context_->endpoint_contexts[0].tr_dequeue_ptr = control_endpoint_transfer_trb_->PhysicalAddress() | 0x1; + endpoints_ = glcr::Array(32); + return ::CreateAddressDeviceCommand(context_phys_ + kInputSlotContextOffset, slot_index_); } @@ -54,8 +56,19 @@ uint8_t DeviceSlot::State() { } void DeviceSlot::TransferComplete(uint8_t endpoint_index, uint64_t trb_phys) { + if (endpoint_index >= 32) { + dbgln("ERROR: Received transfer for invalid endpoint {x}", endpoint_index); + return; + } + if (endpoint_index != 1) { - crash("Transfer complete on non control endpoint", glcr::UNIMPLEMENTED); + if (!endpoints_[endpoint_index].Enabled()) { + dbgln("ERROR: XHCI received transfer for disabled endpoint {x}", + endpoint_index); + return; + } + endpoints_[endpoint_index].TransferComplete(trb_phys); + return; } if (!control_completion_sempahores_.Contains(trb_phys)) { @@ -80,9 +93,7 @@ mmth::Semaphore DeviceSlot::IssueConfigureDeviceCommand(uint8_t config_value) { input_context_->slot_context.route_speed_entries |= (max_endpoint << 27); // TODO: Dont' hardcode this. - other_endpoint_transfer_trb_ = glcr::MakeUnique(); - input_context_->endpoint_contexts[2].tr_dequeue_ptr = - other_endpoint_transfer_trb_->PhysicalAddress() | 0x1; + endpoints_[3].Initialize(input_context_->endpoint_contexts + 2); xhci_driver_->IssueCommand(CreateConfigureEndpointCommand( context_phys_ + kInputSlotContextOffset, slot_index_)); diff --git a/sys/voyageurs/xhci/device_slot.h b/sys/voyageurs/xhci/device_slot.h index 2e3a1cf..b228ba7 100644 --- a/sys/voyageurs/xhci/device_slot.h +++ b/sys/voyageurs/xhci/device_slot.h @@ -8,6 +8,7 @@ #include #include "xhci/control_command.h" +#include "xhci/endpoint.h" #include "xhci/trb_ring.h" #include "xhci/xhci.h" @@ -59,7 +60,7 @@ class DeviceSlot { mmth::Semaphore configure_device_semaphore_; - glcr::UniquePtr other_endpoint_transfer_trb_; + glcr::Array endpoints_; }; template diff --git a/sys/voyageurs/xhci/endpoint.cpp b/sys/voyageurs/xhci/endpoint.cpp new file mode 100644 index 0000000..a1149f0 --- /dev/null +++ b/sys/voyageurs/xhci/endpoint.cpp @@ -0,0 +1,31 @@ +#include "xhci/endpoint.h" + +#include + +void Endpoint::Initialize(XhciEndpointContext* context) { + enabled_ = true; + context_ = context; + + trb_ring_ = glcr::MakeUnique(); + recv_mem_ = mmth::OwnedMemoryRegion::ContiguousPhysical(0x1000, &recv_phys_); + + context_->tr_dequeue_ptr = trb_ring_->PhysicalAddress() | 1; + + context_->error_and_type = (0x3 << 1) | (0x7 << 3) | (0x8 << 16); + trb_ring_->EnqueueTrb({ + .parameter = recv_phys_, + .status = 8, + .type_and_cycle = 1 | (1 << 2) | (1 << 5) | (1 << 10), + .control = 0, + }); +} + +void Endpoint::TransferComplete(uint64_t trb_phys) { + dbgln("Data: {x}", *(uint64_t*)recv_mem_.vaddr()); + trb_ring_->EnqueueTrb({ + .parameter = recv_phys_, + .status = 8, + .type_and_cycle = 1 | (1 << 2) | (1 << 5) | (1 << 10), + .control = 0, + }); +} diff --git a/sys/voyageurs/xhci/endpoint.h b/sys/voyageurs/xhci/endpoint.h new file mode 100644 index 0000000..25b0a45 --- /dev/null +++ b/sys/voyageurs/xhci/endpoint.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include "xhci/trb_ring.h" +#include "xhci/xhci.h" + +class Endpoint { + public: + Endpoint() {} + + void Initialize(XhciEndpointContext* context); + + bool Enabled() { return enabled_; } + + void TransferComplete(uint64_t trb_phys); + + private: + bool enabled_ = false; + + XhciEndpointContext* context_ = nullptr; + glcr::UniquePtr trb_ring_; + + uint64_t recv_phys_; + mmth::OwnedMemoryRegion recv_mem_; +}; diff --git a/sys/voyageurs/xhci/xhci_driver.cpp b/sys/voyageurs/xhci/xhci_driver.cpp index a37eb64..78f6d70 100644 --- a/sys/voyageurs/xhci/xhci_driver.cpp +++ b/sys/voyageurs/xhci/xhci_driver.cpp @@ -205,6 +205,8 @@ glcr::ErrorCode XhciDriver::ParseMmioStructures() { runtime_ = reinterpret_cast(mmio_regions_.vaddr() + capabilities_->runtime_offset); + dbgln("INTTTT: {x}", (uint64_t)runtime_->interrupters); + doorbells_ = reinterpret_cast(mmio_regions_.vaddr() + capabilities_->doorbell_offset); dbgln("Doorbells: {x}", (uint64_t)doorbells_);