feat: add support for aarch64 timer/interrupts, port MontaukOS userspace
This commit is contained in:
1 parent
8b6379fb7e
commit
8c09ccef66
101 files changed
+1720
-629
No files matched your search
@@ -220,6 +220,13 @@ namespace Drivers::USB::Xhci {
|
||||
*(volatile uint32_t*)(g_opBase + reg) = value;
|
||||
}
|
||||
|
||||
// PollEvents() acknowledges the Port Status Change event, clearing PRC,
|
||||
// so a controller that resets instantly (QEMU) can complete the reset
|
||||
// between two reads of PRC. A port that left reset enabled is done too.
|
||||
static bool PortResetComplete(uint32_t portsc) {
|
||||
return (portsc & PORTSC_PRC) || ((portsc & PORTSC_PED) && !(portsc & PORTSC_PR));
|
||||
}
|
||||
|
||||
static uint32_t ReadOp(uint32_t reg) {
|
||||
return *(volatile uint32_t*)(g_opBase + reg);
|
||||
}
|
||||
@@ -474,6 +481,16 @@ namespace Drivers::USB::Xhci {
|
||||
BudgetExhausted,
|
||||
};
|
||||
|
||||
// Without MSI nothing interrupts: the deferred-work check (timer and
|
||||
// idle loop) looks at the event ring itself instead. This is the only
|
||||
// mode on platforms whose PCIe has no MSI controller (Raspberry Pi 4).
|
||||
static bool g_pollMode = false;
|
||||
|
||||
static bool EventRingHasWork() {
|
||||
const volatile TRB& evt = g_evtRing[g_evtRingDequeue];
|
||||
return ((evt.Control & TRB_CYCLE_BIT) != 0) == g_evtRingCCS;
|
||||
}
|
||||
|
||||
static PollResult PollEventsBounded(uint32_t maxEvents) {
|
||||
// PollEvents runs from synchronous poll loops (ControlTransfer,
|
||||
// SendCommand, firmware download) and idle bottom halves on different
|
||||
@@ -1396,6 +1413,9 @@ namespace Drivers::USB::Xhci {
|
||||
}
|
||||
|
||||
bool HasDeferredWork() {
|
||||
if (g_initialized && g_pollMode && EventRingHasWork()) {
|
||||
g_irqDrainPending.store(true, std::memory_order_release);
|
||||
}
|
||||
return g_initialized &&
|
||||
(g_irqDrainPending.load(std::memory_order_acquire) ||
|
||||
g_deferredWorkPending.load(std::memory_order_acquire) ||
|
||||
@@ -1537,7 +1557,7 @@ namespace Drivers::USB::Xhci {
|
||||
for (uint32_t i = 0; i < 100000; i++) {
|
||||
PollEvents();
|
||||
uint32_t ps = ReadOp(OP_PORTSC_BASE + port * OP_PORTSC_STRIDE);
|
||||
if (ps & PORTSC_PRC) {
|
||||
if (PortResetComplete(ps)) {
|
||||
resetDone = true;
|
||||
break;
|
||||
}
|
||||
@@ -1732,6 +1752,7 @@ namespace Drivers::USB::Xhci {
|
||||
// MSI setup
|
||||
if (!SetupMsi(dev.Bus, dev.Device, dev.Function)) {
|
||||
KernelLogStream(WARNING, "xHCI") << "MSI not available, using poll mode";
|
||||
g_pollMode = true;
|
||||
}
|
||||
|
||||
// Enable interrupter 0
|
||||
@@ -1772,7 +1793,7 @@ namespace Drivers::USB::Xhci {
|
||||
for (uint32_t i = 0; i < 100000; i++) {
|
||||
PollEvents();
|
||||
uint32_t ps = ReadOp(OP_PORTSC_BASE + port * OP_PORTSC_STRIDE);
|
||||
if (ps & PORTSC_PRC) { resetDone = true; break; }
|
||||
if (PortResetComplete(ps)) { resetDone = true; break; }
|
||||
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
@@ -2045,6 +2066,7 @@ namespace Drivers::USB::Xhci {
|
||||
// -----------------------------------------------------------------
|
||||
if (!SetupMsi(foundDev->Bus, foundDev->Device, foundDev->Function)) {
|
||||
KernelLogStream(WARNING, "xHCI") << "MSI not available, using poll mode";
|
||||
g_pollMode = true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user