From 0d970a6d25ca042049d52a4e8eae9b05c32b45ed Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 23 May 2025 10:13:54 -0400 Subject: [PATCH] XHCI: allocate scratchpad buffers --- src/hulk/usb/xhci.d | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/hulk/usb/xhci.d b/src/hulk/usb/xhci.d index 013ab35..2226df8 100644 --- a/src/hulk/usb/xhci.d +++ b/src/hulk/usb/xhci.d @@ -47,6 +47,11 @@ struct XHCI */ Volatile!uint hcs_params1; + @property ubyte max_slots() + { + return this.hcs_params1 & 0xFFu; + } + /** * 3:0 isochronous scheduling threshold (IST) * 7:4 event ring segment table max (ERST Max) @@ -57,6 +62,12 @@ struct XHCI */ Volatile!uint hcs_params2; + @property size_t max_scratchpad_buffers() + { + uint v = this.hcs_params2; + return (v >> 27u) | ((v >> (21 - 5)) & 0x3E0u); + } + /** * 7:0 U1 device exit latency * 15:8 reserved @@ -118,11 +129,6 @@ struct XHCI * 31:12 VTIO register space offset (xHCI v1.2+) */ Volatile!uint vtios_offset; - - @property ubyte max_slots() - { - return this.hcs_params1 & 0xFFu; - } } static assert(CapabilityRegisters.sizeof == 0x24u); @@ -370,17 +376,14 @@ struct XHCI ubyte * page = cast(ubyte *)Hippo.allocate_page(); /* Device Context Index: 2K */ void ** device_context_index = cast(void **)page; - page = cast(ubyte *)Hippo.allocate_page(); /* Input Control Context: 64 bytes */ - void * input_control_context = page; + void * input_control_context = &page[2048]; /* Slot Context: 64 bytes */ - void * slot_context = &page[64]; + void * slot_context = &page[2048 + 64]; /* Endpoint Context: 64 bytes */ - void * endpoint_context = &page[128]; + void * endpoint_context = &page[2048 + 64 + 64]; /* Stream Context: 16 bytes */ - void * stream_context = &page[192]; - /* Scratchpad Buffer Array: 248 bytes */ - void ** scratchpad_buffer_array = cast(void **)&page[256]; + void * stream_context = &page[2048 + 64 + 64 + 64]; /* Stream Array (Linear): 1M */ void * stream_array_linear = Hippo.allocate_aligned_region(1024 * 1024, PAGE_SIZE); /* Stream Array (Pri/Sec): 4K */ @@ -393,8 +396,15 @@ struct XHCI void * event_ring_segments = Hippo.allocate_aligned_region(64 * 1024, 64 * 1024); /* Event Ring Segment Table: 512K */ void * event_ring_segment_table = Hippo.allocate_aligned_region(512 * 1024, PAGE_SIZE); - /* Scratchpad Buffers: 4K */ - void * scratchpad_buffers = Hippo.allocate_page(); + /* Scratchpad Buffer Array: 248 bytes */ + void ** scratchpad_buffer_array = cast(void **)Hippo.allocate_aligned_region(2 * PAGE_SIZE, PAGE_SIZE); + + size_t n_scratchpad_buffers = m_capability_registers.max_scratchpad_buffers; + for (size_t i = 0u; i < n_scratchpad_buffers; i++) + { + void * scratchpad_buffer = Hippo.allocate_page(); + scratchpad_buffer_array[i] = scratchpad_buffer; + } device_context_index[0] = scratchpad_buffer_array;