| 235 | } |
| 236 | |
| 237 | void XHCIController::OnInterrupt(){ |
| 238 | Log::Info("[XHCI] Interrupt!"); |
| 239 | |
| 240 | if(!eventRingSegments) return; |
| 241 | |
| 242 | XHCIEventRingSegment* segment = &eventRingSegments[0]; |
| 243 | xhci_event_trb_t* event = eventRingDequeue; |
| 244 | |
| 245 | if(debugLevelXHCI >= DebugLevelVerbose){ |
| 246 | Log::Info("cycle: %Y event cycle: %Y", event->cycleBit, eventRingCycleState); |
| 247 | } |
| 248 | |
| 249 | while(!!event->cycleBit == !!eventRingCycleState){ |
| 250 | if(debugLevelXHCI >= DebugLevelVerbose){ |
| 251 | Log::Info("[XHCI] Received event (TRB Type: %x (%x))", event->trbType, (((uint32_t*)event)[3] >> 10) & 0x3f); |
| 252 | } |
| 253 | |
| 254 | event++; |
| 255 | uintptr_t diff = reinterpret_cast<uintptr_t>(event) - reinterpret_cast<uintptr_t>(segment->segment); |
| 256 | if(!diff || !((diff) % (segment->size * XHCI_TRB_SIZE))){ // Check if we are at either beginning or end of ring segment |
| 257 | eventRingDequeue = segment->segment; |
| 258 | event = eventRingDequeue; |
| 259 | eventRingCycleState = !eventRingCycleState; |
| 260 | break; |
| 261 | } |
| 262 | } |
| 263 | |
| 264 | interrupter->eventRingDequeuePointer = reinterpret_cast<uintptr_t>(eventRingDequeue) | XHCI_INT_ERDP_BUSY; |
| 265 | interrupter->interruptPending = 0; |
| 266 | opRegs->usbStatus &= ~USB_STS_EINT; |
| 267 | } |
| 268 | |
| 269 | bool XHCIController::TakeOwnership(){ |
| 270 | volatile xhci_ext_cap_legacy_support_t* cap = reinterpret_cast<xhci_ext_cap_legacy_support_t*>(extCapabilities); // Legacy support should be the first entry in the extended capabilities |
no test coverage detected