[Voyageurs] Send ConfigureEndpointCommand to device.
This commit is contained in:
parent
af69415d4d
commit
2cc9c89051
|
@ -4,10 +4,13 @@
|
|||
#include <mammoth/util/debug.h>
|
||||
|
||||
#include "xhci/trb.h"
|
||||
#include "xhci/xhci_driver.h"
|
||||
|
||||
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;
|
||||
xhci_driver_ = driver;
|
||||
slot_index_ = slot_index;
|
||||
doorbell_ = doorbell;
|
||||
|
||||
|
@ -63,3 +66,29 @@ void DeviceSlot::TransferComplete(uint8_t endpoint_index, uint64_t trb_phys) {
|
|||
control_completion_sempahores_.at(trb_phys)->Signal();
|
||||
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.
|
||||
other_endpoint_transfer_trb_ = glcr::MakeUnique<TrbRingWriter>();
|
||||
input_context_->endpoint_contexts[2].tr_dequeue_ptr =
|
||||
other_endpoint_transfer_trb_->PhysicalAddress() | 0x1;
|
||||
|
||||
xhci_driver_->IssueCommand(CreateConfigureEndpointCommand(
|
||||
context_phys_ + kInputSlotContextOffset, slot_index_));
|
||||
return configure_device_semaphore_;
|
||||
}
|
||||
|
||||
void DeviceSlot::SignalConfigureDeviceCompleted() {
|
||||
configure_device_semaphore_.Signal();
|
||||
}
|
||||
|
|
|
@ -11,19 +11,25 @@
|
|||
#include "xhci/trb_ring.h"
|
||||
#include "xhci/xhci.h"
|
||||
|
||||
class XhciDriver;
|
||||
|
||||
class DeviceSlot {
|
||||
public:
|
||||
DeviceSlot() = default;
|
||||
DeviceSlot(const DeviceSlot&) = delete;
|
||||
DeviceSlot(DeviceSlot&&) = delete;
|
||||
|
||||
void EnableAndInitializeDataStructures(uint8_t slot_index_,
|
||||
void EnableAndInitializeDataStructures(XhciDriver* driver,
|
||||
uint8_t slot_index_,
|
||||
uint64_t* output_context,
|
||||
volatile uint32_t* doorbell);
|
||||
|
||||
XhciTrb CreateAddressDeviceCommand(uint8_t root_port, uint32_t route_string,
|
||||
uint16_t max_packet_size);
|
||||
|
||||
mmth::Semaphore IssueConfigureDeviceCommand(uint8_t config_value);
|
||||
void SignalConfigureDeviceCompleted();
|
||||
|
||||
// Caller must keep the command in scope until it completes.
|
||||
template <typename T>
|
||||
void ExecuteReadControlCommand(ReadControlCommand<T>& command);
|
||||
|
@ -35,6 +41,7 @@ class DeviceSlot {
|
|||
private:
|
||||
bool enabled_ = false;
|
||||
|
||||
XhciDriver* xhci_driver_;
|
||||
uint8_t slot_index_ = 0;
|
||||
volatile uint32_t* doorbell_ = nullptr;
|
||||
|
||||
|
@ -49,6 +56,10 @@ class DeviceSlot {
|
|||
glcr::UniquePtr<TrbRingWriter> control_endpoint_transfer_trb_;
|
||||
glcr::HashMap<uint64_t, glcr::SharedPtr<mmth::Semaphore>>
|
||||
control_completion_sempahores_;
|
||||
|
||||
mmth::Semaphore configure_device_semaphore_;
|
||||
|
||||
glcr::UniquePtr<TrbRingWriter> other_endpoint_transfer_trb_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -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() {
|
||||
return {
|
||||
.parameter = 0,
|
||||
|
|
|
@ -18,6 +18,7 @@ enum class TrbType : uint8_t {
|
|||
// Commands
|
||||
EnableSlot = 9,
|
||||
AddressDevice = 11,
|
||||
ConfigureEndpoint = 12,
|
||||
NoOpCommand = 23,
|
||||
|
||||
// Events
|
||||
|
@ -32,4 +33,5 @@ XhciTrb CreateLinkTrb(uint64_t physical_address);
|
|||
|
||||
XhciTrb CreateEnableSlotTrb();
|
||||
XhciTrb CreateAddressDeviceCommand(uint64_t input_context, uint8_t slot_id);
|
||||
XhciTrb CreateConfigureEndpointCommand(uint64_t input_context, uint8_t slot_id);
|
||||
XhciTrb CreateNoOpCommandTrb();
|
||||
|
|
|
@ -70,6 +70,15 @@ void configure_device(void* void_device_slot) {
|
|||
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(
|
||||
|
@ -169,6 +178,11 @@ void XhciDriver::DumpDebugInfo() {
|
|||
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)
|
||||
: pci_region_(glcr::Move(pci_space)) {}
|
||||
|
||||
|
@ -329,6 +343,11 @@ void XhciDriver::HandleCommandCompletion(
|
|||
dbgln("State: {x}", devices_[slot - 1].State());
|
||||
Thread(configure_device, &devices_[slot - 1]);
|
||||
break;
|
||||
case TrbType::ConfigureEndpoint:
|
||||
dbgln("Device COnfigured: {x}", slot);
|
||||
dbgln("State: {x}", devices_[slot - 1].State());
|
||||
devices_[slot - 1].SignalConfigureDeviceCompleted();
|
||||
break;
|
||||
case TrbType::NoOpCommand:
|
||||
dbgln("No-op Command Completed");
|
||||
break;
|
||||
|
@ -353,7 +372,7 @@ void XhciDriver::HandleTransferCompletion(const XhciTrb& transfer_event_trb) {
|
|||
void XhciDriver::InitializeSlot(uint8_t slot_index) {
|
||||
// TODO: Consider making this array one longer and ignore the first value.
|
||||
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]);
|
||||
XhciPort* port =
|
||||
reinterpret_cast<XhciPort*>(reinterpret_cast<uint64_t>(operational_) +
|
||||
|
|
|
@ -23,6 +23,8 @@ class XhciDriver {
|
|||
|
||||
void InterruptLoop();
|
||||
|
||||
void IssueCommand(const XhciTrb& command);
|
||||
|
||||
private:
|
||||
// MMIO Structures.
|
||||
mmth::OwnedMemoryRegion pci_region_;
|
||||
|
|
Loading…
Reference in New Issue