feat: make kernel architecture-agnostic; primitive work on arm port
This commit is contained in:
1 parent
dab7d5427b
commit
1bae77ec84
164 files changed
+3664
-1641
No files matched your search
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "Xhci.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include <atomic>
|
||||
#include "UsbDevice.hpp"
|
||||
#include "HidKeyboard.hpp"
|
||||
@@ -18,28 +19,26 @@
|
||||
#include <Memory/Paging.hpp>
|
||||
#include <Memory/PageFrameAllocator.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Hal/SmpBoot.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <Arch/Smp.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
#include <atomic>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
static void BusyWaitMs(uint64_t ms) {
|
||||
uint64_t flags;
|
||||
asm volatile("pushfq; pop %0" : "=r"(flags));
|
||||
if (flags & (1 << 9)) {
|
||||
if (Arch::InterruptsEnabled()) {
|
||||
// Interrupts enabled — use timer-based delay
|
||||
uint64_t start = Timekeeping::GetMilliseconds();
|
||||
while (Timekeeping::GetMilliseconds() - start < ms) {
|
||||
asm volatile("pause" ::: "memory");
|
||||
Arch::Pause();
|
||||
}
|
||||
} else {
|
||||
// Interrupts disabled (e.g. timer tick context) — use I/O port delay
|
||||
// Each outb to port 0x80 takes ~1µs on x86
|
||||
// Interrupts disabled (e.g. timer tick context) — the tick is not
|
||||
// advancing here, so count ~1 µs delays instead
|
||||
for (uint64_t i = 0; i < ms * 1000; i++) {
|
||||
asm volatile("outb %%al, $0x80" ::: "memory");
|
||||
Arch::IoDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,17 +428,9 @@ namespace Drivers::USB::Xhci {
|
||||
uint16_t msgCtrl = Pci::LegacyRead16(bus, dev, func, cap + 2);
|
||||
bool is64bit = (msgCtrl & (1 << 7)) != 0;
|
||||
|
||||
// Write Message Address (cap+4): BSP APIC ID 0, physical destination, fixed delivery
|
||||
Pci::LegacyWrite32(bus, dev, func, cap + 4, MSI_ADDR_BASE);
|
||||
|
||||
// Write Message Data (vector number, edge-triggered, fixed delivery)
|
||||
if (is64bit) {
|
||||
// 64-bit: Upper Address at cap+8, Data at cap+12
|
||||
Pci::LegacyWrite32(bus, dev, func, cap + 8, 0);
|
||||
Pci::LegacyWrite16(bus, dev, func, cap + 12, MSI_VECTOR);
|
||||
} else {
|
||||
// 32-bit: Data at cap+8
|
||||
Pci::LegacyWrite16(bus, dev, func, cap + 8, MSI_VECTOR);
|
||||
// Message Address/Data: IRQ slot MSI_IRQ on the boot CPU
|
||||
if (!Pci::WriteMsiMessage(bus, dev, func, cap, MSI_IRQ)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enable MSI: set bit 0 (MSI Enable), clear bits 6:4 (single message)
|
||||
@@ -453,10 +444,9 @@ namespace Drivers::USB::Xhci {
|
||||
Pci::LegacyWrite16(bus, dev, func, (uint8_t)Pci::PCI_REG_COMMAND, pciCmd);
|
||||
|
||||
// Register the interrupt handler for MSI vector
|
||||
Hal::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
Arch::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
|
||||
KernelLogStream(OK, "xHCI") << "MSI enabled: vector " << base::dec << (uint64_t)MSI_VECTOR
|
||||
<< " (IRQ slot " << (uint64_t)MSI_IRQ << ")" << (is64bit ? " [64-bit]" : " [32-bit]");
|
||||
KernelLogStream(OK, "xHCI") << "MSI enabled: IRQ slot " << base::dec << (uint64_t)MSI_IRQ << (is64bit ? " [64-bit]" : " [32-bit]");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -814,7 +804,7 @@ namespace Drivers::USB::Xhci {
|
||||
}
|
||||
// Small delay
|
||||
for (int j = 0; j < 100; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,7 +926,7 @@ namespace Drivers::USB::Xhci {
|
||||
return g_xferCompletionCode[slotId];
|
||||
}
|
||||
for (int j = 0; j < 100; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1358,7 +1348,7 @@ namespace Drivers::USB::Xhci {
|
||||
}
|
||||
|
||||
for (int j = 0; j < 100; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1552,7 +1542,7 @@ namespace Drivers::USB::Xhci {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < 100; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1665,7 +1655,7 @@ namespace Drivers::USB::Xhci {
|
||||
|
||||
for (uint32_t i = 0; i < 100000; i++) {
|
||||
if (ReadOp(OP_USBSTS) & USBSTS_HCH) break;
|
||||
for (int j = 0; j < 10; j++) asm volatile("" ::: "memory");
|
||||
for (int j = 0; j < 10; j++) Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
if (!(ReadOp(OP_USBSTS) & USBSTS_HCH)) {
|
||||
@@ -1677,11 +1667,11 @@ namespace Drivers::USB::Xhci {
|
||||
WriteOp(OP_USBCMD, USBCMD_HCRST);
|
||||
for (uint32_t i = 0; i < 100000; i++) {
|
||||
if (!(ReadOp(OP_USBCMD) & USBCMD_HCRST)) break;
|
||||
for (int j = 0; j < 10; j++) asm volatile("" ::: "memory");
|
||||
for (int j = 0; j < 10; j++) Arch::CompilerBarrier();
|
||||
}
|
||||
for (uint32_t i = 0; i < 100000; i++) {
|
||||
if (!(ReadOp(OP_USBSTS) & USBSTS_CNR)) break;
|
||||
for (int j = 0; j < 10; j++) asm volatile("" ::: "memory");
|
||||
for (int j = 0; j < 10; j++) Arch::CompilerBarrier();
|
||||
}
|
||||
if (ReadOp(OP_USBSTS) & USBSTS_CNR) {
|
||||
KernelLogStream(WARNING, "xHCI") << "Controller not ready after reset";
|
||||
@@ -1752,7 +1742,7 @@ namespace Drivers::USB::Xhci {
|
||||
WriteOp(OP_USBCMD, USBCMD_RS | USBCMD_INTE | USBCMD_HSEE);
|
||||
for (uint32_t i = 0; i < 100000; i++) {
|
||||
if (!(ReadOp(OP_USBSTS) & USBSTS_HCH)) break;
|
||||
for (int j = 0; j < 10; j++) asm volatile("" ::: "memory");
|
||||
for (int j = 0; j < 10; j++) Arch::CompilerBarrier();
|
||||
}
|
||||
KernelLogStream(OK, "xHCI") << "Controller started";
|
||||
g_initialized = true;
|
||||
@@ -1783,7 +1773,7 @@ namespace Drivers::USB::Xhci {
|
||||
PollEvents();
|
||||
uint32_t ps = ReadOp(OP_PORTSC_BASE + port * OP_PORTSC_STRIDE);
|
||||
if (ps & PORTSC_PRC) { resetDone = true; break; }
|
||||
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
|
||||
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
if (!resetDone) {
|
||||
@@ -1924,7 +1914,7 @@ namespace Drivers::USB::Xhci {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < 10; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1945,7 +1935,7 @@ namespace Drivers::USB::Xhci {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < 10; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1955,7 +1945,7 @@ namespace Drivers::USB::Xhci {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < 10; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2074,7 +2064,7 @@ namespace Drivers::USB::Xhci {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < 10; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2123,7 +2113,7 @@ namespace Drivers::USB::Xhci {
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < 100; j++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user