Kernel: Add support for scratchpad buffers in xHCI

This commit is contained in:
Bananymous 2024-11-22 22:16:57 +02:00
parent e620068416
commit 40c13043b3
2 changed files with 37 additions and 0 deletions

View File

@ -51,6 +51,7 @@ namespace Kernel
BAN::ErrorOr<void> initialize_impl();
BAN::ErrorOr<void> initialize_ports();
BAN::ErrorOr<void> initialize_primary_interrupter();
BAN::ErrorOr<void> initialize_scratchpad();
BAN::ErrorOr<void> reset_controller();
@ -91,6 +92,9 @@ namespace Kernel
uint32_t m_command_enqueue { 0 };
bool m_command_cycle { 1 };
BAN::UniqPtr<DMARegion> m_scratchpad_buffer_array;
BAN::Vector<paddr_t> m_scratchpad_buffers;
BAN::UniqPtr<DMARegion> m_event_ring_region;
uint32_t m_event_dequeue { 0 };
bool m_event_cycle { 1 };

View File

@ -18,6 +18,10 @@ namespace Kernel
{
if (m_port_updater)
m_port_updater->exit(0, SIGKILL);
for (auto paddr : m_scratchpad_buffers)
if (paddr)
Heap::get().release_page(paddr);
}
BAN::ErrorOr<void> XHCIController::take_ownership(PCI::Device& pci_device)
@ -123,6 +127,8 @@ namespace Kernel
TRY(initialize_primary_interrupter());
TRY(initialize_scratchpad());
// enable the controller
operational.usbcmd.run_stop = 1;
while (operational.usbsts & XHCI::USBSTS::HCHalted)
@ -238,6 +244,33 @@ namespace Kernel
return {};
}
BAN::ErrorOr<void> XHCIController::initialize_scratchpad()
{
auto& capabilities = capability_regs();
const uint32_t max_scratchpads = (capabilities.hcsparams2.max_scratchpad_buffers_hi << 5) | capabilities.hcsparams2.max_scratchpad_buffers_lo;
if (max_scratchpads == 0)
return {};
m_scratchpad_buffer_array = TRY(DMARegion::create(max_scratchpads * sizeof(uint64_t)));
TRY(m_scratchpad_buffers.resize(max_scratchpads));
auto* scratchpad_buffer_array = reinterpret_cast<uint64_t*>(m_scratchpad_buffer_array->vaddr());
for (size_t i = 0; i < max_scratchpads; i++)
{
const paddr_t paddr = Heap::get().take_free_page();
if (paddr == 0)
return BAN::Error::from_errno(ENOMEM);
m_scratchpad_buffers[i] = paddr;
scratchpad_buffer_array[i] = paddr;
}
ASSERT(m_dcbaa_region);
*reinterpret_cast<uint64_t*>(m_dcbaa_region->vaddr()) = m_scratchpad_buffer_array->paddr();
return {};
}
static Mutex s_port_mutex;
void XHCIController::port_updater_task()