#pragma once #include #include #include #include "xhci/descriptors.h" #include "xhci/xhci.h" template class ReadControlCommand { public: ReadControlCommand() { output_mem_ = mmth::OwnedMemoryRegion::ContiguousPhysical(0x1000, &output_phys_); } XhciTrb SetupTrb() { uint64_t request_type = RequestConstants::RequestType(); uint64_t request = RequestConstants::Request() << 8; uint64_t value = RequestConstants::Value() << 16; // TODO: May need to be non-0 for string descriptors. uint64_t index = (uint64_t)0 << 32; uint64_t length = (uint64_t)0x1000 << 48; return { .parameter = request_type | request | value | index | length, .status = 8, .type_and_cycle = 1 | (1 << 5) | (1 << 6) | (2 << 10), // IN Data Stage .control = 3, }; } XhciTrb DataTrb() { return { .parameter = output_phys_, .status = 0x1000, .type_and_cycle = 1 | (1 << 5) | (3 << 10), .control = 1, }; } XhciTrb StatusTrb() { return { .parameter = 0, .status = 0, .type_and_cycle = 1 | (1 << 5) | (4 << 10), .control = 0, }; } Output* AwaitResult() { if (!is_complete_) { semaphore_->Wait(); } is_complete_ = true; return reinterpret_cast(output_mem_.vaddr()); } glcr::SharedPtr CompletionSemaphore() { return semaphore_; } private: uint64_t output_phys_; mmth::OwnedMemoryRegion output_mem_; bool is_complete_ = false; glcr::SharedPtr semaphore_ = glcr::MakeShared(); };