Compare commits
5 Commits
b0b7e2faff
...
e6b232851e
Author | SHA1 | Date |
---|---|---|
|
e6b232851e | |
|
c5f8195255 | |
|
2cc9c89051 | |
|
af69415d4d | |
|
39b6d32d86 |
|
@ -1,6 +1,7 @@
|
||||||
add_executable(voyageurs
|
add_executable(voyageurs
|
||||||
keyboard/keyboard_driver.cpp
|
keyboard/keyboard_driver.cpp
|
||||||
xhci/device_slot.cpp
|
xhci/device_slot.cpp
|
||||||
|
xhci/endpoint.cpp
|
||||||
xhci/trb.cpp
|
xhci/trb.cpp
|
||||||
xhci/trb_ring.cpp
|
xhci/trb_ring.cpp
|
||||||
xhci/xhci_driver.cpp
|
xhci/xhci_driver.cpp
|
||||||
|
|
|
@ -21,7 +21,7 @@ class ReadControlCommand {
|
||||||
uint64_t value = RequestConstants<Output>::Value() << 16;
|
uint64_t value = RequestConstants<Output>::Value() << 16;
|
||||||
// TODO: May need to be non-0 for string descriptors.
|
// TODO: May need to be non-0 for string descriptors.
|
||||||
uint64_t index = (uint64_t)0 << 32;
|
uint64_t index = (uint64_t)0 << 32;
|
||||||
uint64_t length = sizeof(Output) << 48;
|
uint64_t length = (uint64_t)0x1000 << 48;
|
||||||
return {
|
return {
|
||||||
.parameter = request_type | request | value | index | length,
|
.parameter = request_type | request | value | index | length,
|
||||||
.status = 8,
|
.status = 8,
|
||||||
|
@ -34,7 +34,7 @@ class ReadControlCommand {
|
||||||
XhciTrb DataTrb() {
|
XhciTrb DataTrb() {
|
||||||
return {
|
return {
|
||||||
.parameter = output_phys_,
|
.parameter = output_phys_,
|
||||||
.status = sizeof(Output),
|
.status = 0x1000,
|
||||||
.type_and_cycle = 1 | (1 << 5) | (3 << 10),
|
.type_and_cycle = 1 | (1 << 5) | (3 << 10),
|
||||||
.control = 1,
|
.control = 1,
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,3 +34,44 @@ class RequestConstants<DeviceDescriptor> {
|
||||||
static uint8_t Request() { return 0x6; };
|
static uint8_t Request() { return 0x6; };
|
||||||
static uint16_t Value() { return 0x100; };
|
static uint16_t Value() { return 0x100; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ConfigurationDescriptor {
|
||||||
|
uint8_t length;
|
||||||
|
uint8_t type;
|
||||||
|
uint16_t total_length;
|
||||||
|
uint8_t num_interfaces;
|
||||||
|
uint8_t configuration_value;
|
||||||
|
uint8_t configuration_string_index;
|
||||||
|
uint8_t attributes;
|
||||||
|
uint8_t max_power;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class RequestConstants<ConfigurationDescriptor> {
|
||||||
|
public:
|
||||||
|
static uint8_t RequestType() { return 0x80; }
|
||||||
|
static uint8_t Request() { return 0x6; }
|
||||||
|
// TODO: Consider getting other description indexes.
|
||||||
|
static uint16_t Value() { return 0x200; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InterfaceDescriptor {
|
||||||
|
uint8_t length;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t interface_number;
|
||||||
|
uint8_t alternate_setting;
|
||||||
|
uint8_t num_endpoints;
|
||||||
|
uint8_t interface_class;
|
||||||
|
uint8_t interface_subclass;
|
||||||
|
uint8_t interface_protocol;
|
||||||
|
uint8_t interfact_string_index;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct EndpointDescriptor {
|
||||||
|
uint8_t length;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t endpoint_address;
|
||||||
|
uint8_t attributes;
|
||||||
|
uint16_t max_packet_size;
|
||||||
|
uint8_t interval;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
|
@ -4,10 +4,13 @@
|
||||||
#include <mammoth/util/debug.h>
|
#include <mammoth/util/debug.h>
|
||||||
|
|
||||||
#include "xhci/trb.h"
|
#include "xhci/trb.h"
|
||||||
|
#include "xhci/xhci_driver.h"
|
||||||
|
|
||||||
void DeviceSlot::EnableAndInitializeDataStructures(
|
void DeviceSlot::EnableAndInitializeDataStructures(
|
||||||
uint8_t slot_index, uint64_t* output_context, volatile uint32_t* doorbell) {
|
XhciDriver* driver, uint8_t slot_index, uint64_t* output_context,
|
||||||
|
volatile uint32_t* doorbell) {
|
||||||
enabled_ = true;
|
enabled_ = true;
|
||||||
|
xhci_driver_ = driver;
|
||||||
slot_index_ = slot_index;
|
slot_index_ = slot_index;
|
||||||
doorbell_ = doorbell;
|
doorbell_ = doorbell;
|
||||||
|
|
||||||
|
@ -42,6 +45,8 @@ XhciTrb DeviceSlot::CreateAddressDeviceCommand(uint8_t root_port,
|
||||||
input_context_->endpoint_contexts[0].tr_dequeue_ptr =
|
input_context_->endpoint_contexts[0].tr_dequeue_ptr =
|
||||||
control_endpoint_transfer_trb_->PhysicalAddress() | 0x1;
|
control_endpoint_transfer_trb_->PhysicalAddress() | 0x1;
|
||||||
|
|
||||||
|
endpoints_ = glcr::Array<Endpoint>(32);
|
||||||
|
|
||||||
return ::CreateAddressDeviceCommand(context_phys_ + kInputSlotContextOffset,
|
return ::CreateAddressDeviceCommand(context_phys_ + kInputSlotContextOffset,
|
||||||
slot_index_);
|
slot_index_);
|
||||||
}
|
}
|
||||||
|
@ -51,8 +56,19 @@ uint8_t DeviceSlot::State() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceSlot::TransferComplete(uint8_t endpoint_index, uint64_t trb_phys) {
|
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) {
|
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)) {
|
if (!control_completion_sempahores_.Contains(trb_phys)) {
|
||||||
|
@ -63,3 +79,27 @@ void DeviceSlot::TransferComplete(uint8_t endpoint_index, uint64_t trb_phys) {
|
||||||
control_completion_sempahores_.at(trb_phys)->Signal();
|
control_completion_sempahores_.at(trb_phys)->Signal();
|
||||||
check(control_completion_sempahores_.Delete(trb_phys));
|
check(control_completion_sempahores_.Delete(trb_phys));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mmth::Semaphore DeviceSlot::IssueConfigureDeviceCommand(uint8_t config_value) {
|
||||||
|
input_context_->input.add_contexts = (0x1 << 3) | 0x1;
|
||||||
|
input_context_->input.configuration_value = config_value;
|
||||||
|
// TODO: Maybe don't hardcode this.
|
||||||
|
input_context_->input.interface_number = 0;
|
||||||
|
|
||||||
|
input_context_->slot_context.route_speed_entries &= 0xFFFFFF;
|
||||||
|
|
||||||
|
// TODO: Don't hardcode this.
|
||||||
|
uint8_t max_endpoint = 0x3;
|
||||||
|
input_context_->slot_context.route_speed_entries |= (max_endpoint << 27);
|
||||||
|
|
||||||
|
// TODO: Dont' hardcode this.
|
||||||
|
endpoints_[3].Initialize(input_context_->endpoint_contexts + 2);
|
||||||
|
|
||||||
|
xhci_driver_->IssueCommand(CreateConfigureEndpointCommand(
|
||||||
|
context_phys_ + kInputSlotContextOffset, slot_index_));
|
||||||
|
return configure_device_semaphore_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceSlot::SignalConfigureDeviceCompleted() {
|
||||||
|
configure_device_semaphore_.Signal();
|
||||||
|
}
|
||||||
|
|
|
@ -8,22 +8,29 @@
|
||||||
#include <mammoth/util/memory_region.h>
|
#include <mammoth/util/memory_region.h>
|
||||||
|
|
||||||
#include "xhci/control_command.h"
|
#include "xhci/control_command.h"
|
||||||
|
#include "xhci/endpoint.h"
|
||||||
#include "xhci/trb_ring.h"
|
#include "xhci/trb_ring.h"
|
||||||
#include "xhci/xhci.h"
|
#include "xhci/xhci.h"
|
||||||
|
|
||||||
|
class XhciDriver;
|
||||||
|
|
||||||
class DeviceSlot {
|
class DeviceSlot {
|
||||||
public:
|
public:
|
||||||
DeviceSlot() = default;
|
DeviceSlot() = default;
|
||||||
DeviceSlot(const DeviceSlot&) = delete;
|
DeviceSlot(const DeviceSlot&) = delete;
|
||||||
DeviceSlot(DeviceSlot&&) = delete;
|
DeviceSlot(DeviceSlot&&) = delete;
|
||||||
|
|
||||||
void EnableAndInitializeDataStructures(uint8_t slot_index_,
|
void EnableAndInitializeDataStructures(XhciDriver* driver,
|
||||||
|
uint8_t slot_index_,
|
||||||
uint64_t* output_context,
|
uint64_t* output_context,
|
||||||
volatile uint32_t* doorbell);
|
volatile uint32_t* doorbell);
|
||||||
|
|
||||||
XhciTrb CreateAddressDeviceCommand(uint8_t root_port, uint32_t route_string,
|
XhciTrb CreateAddressDeviceCommand(uint8_t root_port, uint32_t route_string,
|
||||||
uint16_t max_packet_size);
|
uint16_t max_packet_size);
|
||||||
|
|
||||||
|
mmth::Semaphore IssueConfigureDeviceCommand(uint8_t config_value);
|
||||||
|
void SignalConfigureDeviceCompleted();
|
||||||
|
|
||||||
// Caller must keep the command in scope until it completes.
|
// Caller must keep the command in scope until it completes.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ExecuteReadControlCommand(ReadControlCommand<T>& command);
|
void ExecuteReadControlCommand(ReadControlCommand<T>& command);
|
||||||
|
@ -35,6 +42,7 @@ class DeviceSlot {
|
||||||
private:
|
private:
|
||||||
bool enabled_ = false;
|
bool enabled_ = false;
|
||||||
|
|
||||||
|
XhciDriver* xhci_driver_;
|
||||||
uint8_t slot_index_ = 0;
|
uint8_t slot_index_ = 0;
|
||||||
volatile uint32_t* doorbell_ = nullptr;
|
volatile uint32_t* doorbell_ = nullptr;
|
||||||
|
|
||||||
|
@ -49,6 +57,10 @@ class DeviceSlot {
|
||||||
glcr::UniquePtr<TrbRingWriter> control_endpoint_transfer_trb_;
|
glcr::UniquePtr<TrbRingWriter> control_endpoint_transfer_trb_;
|
||||||
glcr::HashMap<uint64_t, glcr::SharedPtr<mmth::Semaphore>>
|
glcr::HashMap<uint64_t, glcr::SharedPtr<mmth::Semaphore>>
|
||||||
control_completion_sempahores_;
|
control_completion_sempahores_;
|
||||||
|
|
||||||
|
mmth::Semaphore configure_device_semaphore_;
|
||||||
|
|
||||||
|
glcr::Array<Endpoint> endpoints_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include "xhci/endpoint.h"
|
||||||
|
|
||||||
|
#include <mammoth/util/debug.h>
|
||||||
|
|
||||||
|
void Endpoint::Initialize(XhciEndpointContext* context) {
|
||||||
|
enabled_ = true;
|
||||||
|
context_ = context;
|
||||||
|
|
||||||
|
trb_ring_ = glcr::MakeUnique<TrbRingWriter>();
|
||||||
|
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);
|
||||||
|
for (uint64_t i = 0; i < 10; i++) {
|
||||||
|
trb_ring_->EnqueueTrb({
|
||||||
|
.parameter = recv_phys_ + offset_,
|
||||||
|
.status = 8,
|
||||||
|
.type_and_cycle = 1 | (1 << 2) | (1 << 5) | (1 << 10),
|
||||||
|
.control = 0,
|
||||||
|
});
|
||||||
|
offset_ += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Endpoint::TransferComplete(uint64_t trb_phys) {
|
||||||
|
uint64_t phys_offset =
|
||||||
|
(trb_phys - trb_ring_->PhysicalAddress()) / sizeof(XhciTrb);
|
||||||
|
dbgln("Data: {x}", *((uint64_t*)recv_mem_.vaddr() + phys_offset));
|
||||||
|
trb_ring_->EnqueueTrb({
|
||||||
|
.parameter = recv_phys_ + offset_,
|
||||||
|
.status = 8,
|
||||||
|
.type_and_cycle = 1 | (1 << 2) | (1 << 5) | (1 << 10),
|
||||||
|
.control = 0,
|
||||||
|
});
|
||||||
|
offset_ += 8;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/memory/unique_ptr.h>
|
||||||
|
|
||||||
|
#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<TrbRingWriter> trb_ring_;
|
||||||
|
|
||||||
|
uint64_t recv_phys_;
|
||||||
|
mmth::OwnedMemoryRegion recv_mem_;
|
||||||
|
uint64_t offset_ = 0;
|
||||||
|
};
|
|
@ -49,6 +49,17 @@ XhciTrb CreateAddressDeviceCommand(uint64_t input_context, uint8_t slot_id) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XhciTrb CreateConfigureEndpointCommand(uint64_t input_context,
|
||||||
|
uint8_t slot_id) {
|
||||||
|
return {
|
||||||
|
.parameter = input_context,
|
||||||
|
.status = 0,
|
||||||
|
.type_and_cycle =
|
||||||
|
(uint16_t)(TypeToInt(TrbType::ConfigureEndpoint) | kTrb_Cycle),
|
||||||
|
.control = (uint16_t)(slot_id << 8),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
XhciTrb CreateNoOpCommandTrb() {
|
XhciTrb CreateNoOpCommandTrb() {
|
||||||
return {
|
return {
|
||||||
.parameter = 0,
|
.parameter = 0,
|
||||||
|
|
|
@ -18,6 +18,7 @@ enum class TrbType : uint8_t {
|
||||||
// Commands
|
// Commands
|
||||||
EnableSlot = 9,
|
EnableSlot = 9,
|
||||||
AddressDevice = 11,
|
AddressDevice = 11,
|
||||||
|
ConfigureEndpoint = 12,
|
||||||
NoOpCommand = 23,
|
NoOpCommand = 23,
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
@ -32,4 +33,5 @@ XhciTrb CreateLinkTrb(uint64_t physical_address);
|
||||||
|
|
||||||
XhciTrb CreateEnableSlotTrb();
|
XhciTrb CreateEnableSlotTrb();
|
||||||
XhciTrb CreateAddressDeviceCommand(uint64_t input_context, uint8_t slot_id);
|
XhciTrb CreateAddressDeviceCommand(uint64_t input_context, uint8_t slot_id);
|
||||||
|
XhciTrb CreateConfigureEndpointCommand(uint64_t input_context, uint8_t slot_id);
|
||||||
XhciTrb CreateNoOpCommandTrb();
|
XhciTrb CreateNoOpCommandTrb();
|
||||||
|
|
|
@ -36,7 +36,7 @@ uint64_t TrbRingWriter::EnqueueTrb(const XhciTrb& trb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
trb_list_[ptr] = trb;
|
trb_list_[ptr] = trb;
|
||||||
return phys_address_ + (ptr * sizeof(uint64_t));
|
return phys_address_ + (ptr * sizeof(XhciTrb));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrbRingReader::HasNext() {
|
bool TrbRingReader::HasNext() {
|
||||||
|
|
|
@ -31,6 +31,54 @@ void configure_device(void* void_device_slot) {
|
||||||
dbgln("Descriptor Type {x}, ({x})", descriptor->type, descriptor->usb_spec);
|
dbgln("Descriptor Type {x}, ({x})", descriptor->type, descriptor->usb_spec);
|
||||||
dbgln("Device Class/Sub/Protocol: {x}/{x}/{x}", descriptor->device_class,
|
dbgln("Device Class/Sub/Protocol: {x}/{x}/{x}", descriptor->device_class,
|
||||||
descriptor->device_subclass, descriptor->device_protocol);
|
descriptor->device_subclass, descriptor->device_protocol);
|
||||||
|
dbgln("Num Configurations: {}", descriptor->num_configurations);
|
||||||
|
|
||||||
|
ReadControlCommand<ConfigurationDescriptor> config_command;
|
||||||
|
|
||||||
|
device_slot->ExecuteReadControlCommand(config_command);
|
||||||
|
|
||||||
|
ConfigurationDescriptor* config_descriptor = config_command.AwaitResult();
|
||||||
|
|
||||||
|
dbgln("Configuration Value: {x}", config_descriptor->configuration_value);
|
||||||
|
dbgln("Num Interfaces: {x}", config_descriptor->num_interfaces);
|
||||||
|
dbgln("Size: {x}, Total Length: {x}", config_descriptor->length,
|
||||||
|
config_descriptor->total_length);
|
||||||
|
|
||||||
|
uint64_t next_vaddr =
|
||||||
|
reinterpret_cast<uint64_t>(config_descriptor) + config_descriptor->length;
|
||||||
|
for (auto i = config_descriptor->num_interfaces; i > 0; i--) {
|
||||||
|
InterfaceDescriptor* interface =
|
||||||
|
reinterpret_cast<InterfaceDescriptor*>(next_vaddr);
|
||||||
|
dbgln("Interface: {x}", interface->interface_number);
|
||||||
|
dbgln("Interface Class/Sub/Protocol: {x}/{x}/{x}",
|
||||||
|
interface->interface_class, interface->interface_subclass,
|
||||||
|
interface->interface_protocol);
|
||||||
|
dbgln("Num Endpoints: {x}", interface->num_endpoints);
|
||||||
|
|
||||||
|
next_vaddr += interface->length;
|
||||||
|
for (auto j = interface->num_endpoints; j > 0; j--) {
|
||||||
|
EndpointDescriptor* endpoint =
|
||||||
|
reinterpret_cast<EndpointDescriptor*>(next_vaddr);
|
||||||
|
if (endpoint->type != 5) {
|
||||||
|
dbgln("Descriptor type {x}, skipping", endpoint->type);
|
||||||
|
j++;
|
||||||
|
next_vaddr += endpoint->length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dbgln("Endpoint Addr: {x}", endpoint->endpoint_address);
|
||||||
|
dbgln("Endpoint Attr: {x}", endpoint->attributes);
|
||||||
|
next_vaddr += endpoint->length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dbgln("---- Configuring with configuration: {x}",
|
||||||
|
config_descriptor->configuration_value);
|
||||||
|
|
||||||
|
device_slot
|
||||||
|
->IssueConfigureDeviceCommand(config_descriptor->configuration_value)
|
||||||
|
.Wait();
|
||||||
|
|
||||||
|
dbgln("Configured!");
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorOr<glcr::UniquePtr<XhciDriver>> XhciDriver::InitiateDriver(
|
glcr::ErrorOr<glcr::UniquePtr<XhciDriver>> XhciDriver::InitiateDriver(
|
||||||
|
@ -130,6 +178,11 @@ void XhciDriver::DumpDebugInfo() {
|
||||||
runtime_->interrupters[0].event_ring_segment_table_base_address);
|
runtime_->interrupters[0].event_ring_segment_table_base_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XhciDriver::IssueCommand(const XhciTrb& command) {
|
||||||
|
command_ring_.EnqueueTrb(command);
|
||||||
|
doorbells_->doorbell[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
XhciDriver::XhciDriver(mmth::OwnedMemoryRegion&& pci_space)
|
XhciDriver::XhciDriver(mmth::OwnedMemoryRegion&& pci_space)
|
||||||
: pci_region_(glcr::Move(pci_space)) {}
|
: pci_region_(glcr::Move(pci_space)) {}
|
||||||
|
|
||||||
|
@ -152,6 +205,8 @@ glcr::ErrorCode XhciDriver::ParseMmioStructures() {
|
||||||
runtime_ = reinterpret_cast<XhciRuntime*>(mmio_regions_.vaddr() +
|
runtime_ = reinterpret_cast<XhciRuntime*>(mmio_regions_.vaddr() +
|
||||||
capabilities_->runtime_offset);
|
capabilities_->runtime_offset);
|
||||||
|
|
||||||
|
dbgln("INTTTT: {x}", (uint64_t)runtime_->interrupters);
|
||||||
|
|
||||||
doorbells_ = reinterpret_cast<XhciDoorbells*>(mmio_regions_.vaddr() +
|
doorbells_ = reinterpret_cast<XhciDoorbells*>(mmio_regions_.vaddr() +
|
||||||
capabilities_->doorbell_offset);
|
capabilities_->doorbell_offset);
|
||||||
dbgln("Doorbells: {x}", (uint64_t)doorbells_);
|
dbgln("Doorbells: {x}", (uint64_t)doorbells_);
|
||||||
|
@ -290,6 +345,11 @@ void XhciDriver::HandleCommandCompletion(
|
||||||
dbgln("State: {x}", devices_[slot - 1].State());
|
dbgln("State: {x}", devices_[slot - 1].State());
|
||||||
Thread(configure_device, &devices_[slot - 1]);
|
Thread(configure_device, &devices_[slot - 1]);
|
||||||
break;
|
break;
|
||||||
|
case TrbType::ConfigureEndpoint:
|
||||||
|
dbgln("Device COnfigured: {x}", slot);
|
||||||
|
dbgln("State: {x}", devices_[slot - 1].State());
|
||||||
|
devices_[slot - 1].SignalConfigureDeviceCompleted();
|
||||||
|
break;
|
||||||
case TrbType::NoOpCommand:
|
case TrbType::NoOpCommand:
|
||||||
dbgln("No-op Command Completed");
|
dbgln("No-op Command Completed");
|
||||||
break;
|
break;
|
||||||
|
@ -300,6 +360,11 @@ void XhciDriver::HandleCommandCompletion(
|
||||||
}
|
}
|
||||||
|
|
||||||
void XhciDriver::HandleTransferCompletion(const XhciTrb& transfer_event_trb) {
|
void XhciDriver::HandleTransferCompletion(const XhciTrb& transfer_event_trb) {
|
||||||
|
uint8_t status = transfer_event_trb.status >> 24;
|
||||||
|
if (status != 1 && status != 0xD) {
|
||||||
|
dbgln("Unexpected Status {x}", status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
uint8_t slot_id = transfer_event_trb.control >> 8;
|
uint8_t slot_id = transfer_event_trb.control >> 8;
|
||||||
uint8_t endpoint_id = transfer_event_trb.control & 0x1F;
|
uint8_t endpoint_id = transfer_event_trb.control & 0x1F;
|
||||||
uint64_t trb_phys = transfer_event_trb.parameter;
|
uint64_t trb_phys = transfer_event_trb.parameter;
|
||||||
|
@ -309,7 +374,7 @@ void XhciDriver::HandleTransferCompletion(const XhciTrb& transfer_event_trb) {
|
||||||
void XhciDriver::InitializeSlot(uint8_t slot_index) {
|
void XhciDriver::InitializeSlot(uint8_t slot_index) {
|
||||||
// TODO: Consider making this array one longer and ignore the first value.
|
// TODO: Consider making this array one longer and ignore the first value.
|
||||||
devices_[slot_index - 1].EnableAndInitializeDataStructures(
|
devices_[slot_index - 1].EnableAndInitializeDataStructures(
|
||||||
slot_index, &(device_context_base_array_[slot_index]),
|
this, slot_index, &(device_context_base_array_[slot_index]),
|
||||||
&doorbells_->doorbell[slot_index]);
|
&doorbells_->doorbell[slot_index]);
|
||||||
XhciPort* port =
|
XhciPort* port =
|
||||||
reinterpret_cast<XhciPort*>(reinterpret_cast<uint64_t>(operational_) +
|
reinterpret_cast<XhciPort*>(reinterpret_cast<uint64_t>(operational_) +
|
||||||
|
|
|
@ -23,6 +23,8 @@ class XhciDriver {
|
||||||
|
|
||||||
void InterruptLoop();
|
void InterruptLoop();
|
||||||
|
|
||||||
|
void IssueCommand(const XhciTrb& command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// MMIO Structures.
|
// MMIO Structures.
|
||||||
mmth::OwnedMemoryRegion pci_region_;
|
mmth::OwnedMemoryRegion pci_region_;
|
||||||
|
|
Loading…
Reference in New Issue