Compare commits

...

2 Commits

Author SHA1 Message Date
4814b51daf Dump xHCI extended capabilities 2023-09-19 11:07:18 -04:00
14bb3adf37 Document xHCI capability registers 2023-09-19 11:07:02 -04:00

View File

@ -16,19 +16,105 @@ struct XHCI
{ {
/** /**
* Located at PCI base address. * Located at PCI base address.
*
* All are read-only.
*/ */
struct CapabilityRegisters struct CapabilityRegisters
{ {
/**
* Offset from beginning of capability registers to beginning of
* operational registers.
*/
ubyte capability_length; ubyte capability_length;
ubyte _reserved01; ubyte _reserved01;
/**
* Interface version number supported (psuedo-BSD).
*/
ushort hci_version; ushort hci_version;
uint[3] hcs_params;
/**
* 7:0 number of device slots (MaxSlots)
* 18:8 number of interrupters (MaxIntrs)
* 23:19 reserved
* 31:24 number of ports (MaxPorts)
*/
uint hcs_params1;
/**
* 3:0 isochronous scheduling threshold (IST)
* 7:4 event ring segment table max (ERST Max)
* 20:8 reserved
* 25:21 max scratchpad buffers (high 5 bits; xHCI v1.1+)
* 26 scratchpad restore (SPR)
* 31:27 max scratchpad buffers (low 5 bits)
*/
uint hcs_params2;
/**
* 7:0 U1 device exit latency
* 15:8 reserved
* 31:16 U2 device exit latency
*/
uint hcs_params3;
/**
* 0 64-bit addressing capability (AC64)
* 1 BW negotiation capability (BNC)
* 2 context size (CSZ)
* 3 port power control (PPC)
* 4 port indicators (PIND)
* 5 light HC reset capability (LHRC)
* 6 latency tolerance messaging capability (LTC)
* 7 no secondary SID support (NSS)
* 8 parse all event data (PAE; xHCI v1.1+)
* 9 stopped - short packet capability (SPC; xHCI v1.1+)
* 10 stopped EDTLA capability (SEC; xHCI v1.1+)
* 11 continuous frame ID capability (CFC; xHCI v1.1+)
* 15:12 maximum primary stream array size (MaxPSASize)
* 31:16 xHCI extended capabilities pointer (xECP)
* offset in 32-bit words from base of capability registers to base
* of capabilities list
*/
uint hcc_params1; uint hcc_params1;
/**
* 1:0 reserved
* 31:2 doorbell array offset in 32-bit words
* offset in 32-bit words from base of capability registers to the
* doorbell array
*/
uint doorbell_offset; uint doorbell_offset;
/**
* 4:0 reserved
* 31:5 runtime register space offset
*/
uint rts_offset; uint rts_offset;
/**
* 0 U3 entry capability (U3C)
* 1 ConfigEP command max exit latency too large (CMC)
* 2 force save context capability (FSC)
* 3 compliance transition capability (CTC)
* 4 large ESIT payload capability (LEC)
* 5 configuration information capability (CIC)
* 6 extended TBC capability (ETC)
* 7 extended TBC TRB status capability (ETC_TSC)
* 8 get/set extended property capability (GSC; xHCI v1.1+)
* 9 virtualization based trusted I/O capability (VTC; xHCI v1.2+)
* 31:10 reserved
*/
uint hcc_params2; uint hcc_params2;
/**
* 11:0 reserved
* 31:12 VTIO register space offset (xHCI v1.2+)
*/
uint vtios_offset;
} }
static assert(CapabilityRegisters.sizeof == 0x20u); static assert(CapabilityRegisters.sizeof == 0x24u);
/** /**
* Located at offset capability_length from PCI base address. * Located at offset capability_length from PCI base address.
@ -91,6 +177,47 @@ struct XHCI
m_port_registers = cast(PortRegisters *)(cast(void *)m_operational_registers + 0x400); m_port_registers = cast(PortRegisters *)(cast(void *)m_operational_registers + 0x400);
m_runtime_registers = cast(RuntimeRegisters *)(base_address + m_capability_registers.rts_offset); m_runtime_registers = cast(RuntimeRegisters *)(base_address + m_capability_registers.rts_offset);
m_doorbell_registers = cast(DoorbellRegister *)(base_address + m_capability_registers.doorbell_offset); m_doorbell_registers = cast(DoorbellRegister *)(base_address + m_capability_registers.doorbell_offset);
dump_extended_capabilities();
}
private void dump_extended_capabilities()
{
size_t ext_cap_off = (m_capability_registers.hcc_params1 >> 16u);
if (ext_cap_off != 0u)
{
Klog.writefln("Extended capabilities:");
uint * extended_capabilities = cast(uint *)m_capability_registers + ext_cap_off;
for (;;)
{
uint ec0 = extended_capabilities[0];
size_t next_offset = (ec0 >> 8u) & 0xFFu;
size_t len = next_offset;
if (len < 1u)
{
len = 1u;
}
ubyte type = ec0 & 0xFFu;
if (type == 2u)
{
len = 4u;
}
for (size_t i = 0u; i < len; i++)
{
uint ecv = extended_capabilities[i];
Klog.writef(" %02X %02X %02X %02X",
ecv & 0xFFu,
(ecv >> 8u) & 0xFFu,
(ecv >> 16u) & 0xFFu,
(ecv >> 24u) & 0xFFu);
}
Klog.writef("\n");
if (next_offset == 0u)
{
break;
}
extended_capabilities += next_offset;
}
}
} }
static void build(Pci.Device * pci_device) static void build(Pci.Device * pci_device)