feat: make kernel architecture-agnostic; primitive work on arm port

This commit is contained in:
daniel committed 2026-10-24 21:25:18 +02:00
1 parent dab7d5427b
commit 1bae77ec84
164 files changed
+3664 -1641

No files matched your search

+12 -11
View File
@@ -5,6 +5,7 @@
*/
#include "A2dp.hpp"
#include <Arch/Cpu.hpp>
#include "Sbc.hpp"
#include "L2cap.hpp"
#include "Hci.hpp"
@@ -12,7 +13,7 @@
#include <Terminal/Terminal.hpp>
#include <CppLib/Stream.hpp>
#include <Libraries/Memory.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Timekeeping/Timer.hpp>
#include <atomic>
using namespace Kt;
@@ -232,7 +233,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
return true;
}
for (int j = 0; j < 100; j++) {
asm volatile("" ::: "memory");
Arch::CompilerBarrier();
}
}
g_expectLabel.store(0xFF, std::memory_order_release);
@@ -1166,7 +1167,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
answered = true;
break;
}
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
// Transaction over: CLOSE the client channel (FreeChannel sends the
@@ -1200,7 +1201,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
Hci::ProcessPendingCommands();
auto* c = Hci::GetConnection(g_aclHandle.load(std::memory_order_acquire));
if (c && c->Encrypted) return true;
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
return false;
}
@@ -1236,7 +1237,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
&& Timekeeping::GetMilliseconds() - waitStart < timeoutMs) {
Xhci::PollEvents();
Hci::DrainEvents();
for (int j = 0; j < 100; j++) asm volatile("pause" ::: "memory");
for (int j = 0; j < 100; j++) Arch::Pause();
}
return IsReady();
}
@@ -1268,7 +1269,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
Hci::DrainEvents();
Hci::ProcessPendingCommands();
if (g_sigCid.load(std::memory_order_acquire) != 0) break;
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
}
if (g_sigCid.load(std::memory_order_acquire) != 0) {
@@ -1327,7 +1328,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
// timer.
if (L2cap::ConnRspResult(sig) == L2cap::CONN_PENDING)
waitBudgetMs = timeoutMs;
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
uint16_t readySig = g_sigCid.load(std::memory_order_acquire);
if (readySig != 0) {
@@ -1364,7 +1365,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
while (Timekeeping::GetMilliseconds() - st < 400) {
Xhci::PollEvents();
Hci::DrainEvents();
for (int j = 0; j < 200; j++) asm volatile("pause" ::: "memory");
for (int j = 0; j < 200; j++) Arch::Pause();
}
}
@@ -1387,7 +1388,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
Hci::DrainEvents();
State s = g_state.load(std::memory_order_acquire);
if (s == State::Open || s == State::Streaming) break;
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
State s = g_state.load(std::memory_order_acquire);
if (s != State::Open && s != State::Streaming) {
@@ -1495,7 +1496,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
g_mediaCid.store(other, std::memory_order_release);
break;
}
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
if (g_mediaCid.load(std::memory_order_acquire) == 0) {
@@ -1879,7 +1880,7 @@ namespace Drivers::USB::Bluetooth::A2dp {
if (g_serviceActive.compare_exchange_weak(expected, true,
std::memory_order_acquire))
return true;
asm volatile("pause" ::: "memory");
Arch::Pause();
}
return false;
}
@@ -5,6 +5,7 @@
*/
#include "Bluetooth.hpp"
#include <Arch/Cpu.hpp>
#include "Hci.hpp"
#include "A2dp.hpp"
#include "IntelFirmware.hpp"
@@ -15,8 +16,8 @@
#include <Terminal/Terminal.hpp>
#include <CppLib/Stream.hpp>
#include <Libraries/Memory.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Hal/SmpBoot.hpp>
#include <Timekeeping/Timer.hpp>
#include <Arch/Smp.hpp>
#include <atomic>
using namespace Kt;
@@ -223,7 +224,7 @@ namespace Drivers::USB::Bluetooth {
uint64_t start = Timekeeping::GetMilliseconds();
while (Timekeeping::GetMilliseconds() - start < 200) {
Xhci::PollEvents();
asm volatile("pause" ::: "memory");
Arch::Pause();
}
// Start the event pipe BEFORE sending any HCI commands.
@@ -498,7 +499,7 @@ namespace Drivers::USB::Bluetooth {
auto* conn = Hci::GetConnectionByIndex(i);
if (conn && conn->Active) { anyActive = true; break; }
}
for (int k = 0; k < 200; k++) asm volatile("pause" ::: "memory");
for (int k = 0; k < 200; k++) Arch::Pause();
}
if (anyActive) return false;
}
@@ -551,7 +552,7 @@ namespace Drivers::USB::Bluetooth {
Hci::DrainEvents();
for (int j = 0; j < 200; j++) {
asm volatile("pause" ::: "memory");
Arch::Pause();
}
}
@@ -568,7 +569,7 @@ namespace Drivers::USB::Bluetooth {
Xhci::PollEvents();
Hci::DrainEvents();
for (int j = 0; j < 100; j++)
asm volatile("pause" ::: "memory");
Arch::Pause();
}
if (Hci::IsInquiryActive() && !Hci::CancelInquiry()) return -1;
}
@@ -615,7 +616,7 @@ namespace Drivers::USB::Bluetooth {
Hci::DrainEvents();
target = FindAclConnection(bdAddr);
for (int j = 0; j < 200; j++) {
asm volatile("pause" ::: "memory");
Arch::Pause();
}
}
if (!target) return -1;
@@ -635,7 +636,7 @@ namespace Drivers::USB::Bluetooth {
Hci::ProcessPendingCommands();
if (!target->Active || !SameAddress(target->BdAddr, bdAddr)) break;
if (target->Encrypted) break;
for (int k = 0; k < 200; k++) asm volatile("pause" ::: "memory");
for (int k = 0; k < 200; k++) Arch::Pause();
}
}
+11 -10
View File
@@ -5,6 +5,7 @@
*/
#include "Hci.hpp"
#include <Arch/Cpu.hpp>
#include "L2cap.hpp"
#include "A2dp.hpp"
#include <atomic>
@@ -17,7 +18,7 @@
#include <Memory/HHDM.hpp>
#include <Memory/PageFrameAllocator.hpp>
#include <Libraries/Memory.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Timekeeping/Timer.hpp>
using namespace Kt;
@@ -632,7 +633,7 @@ namespace Drivers::USB::Bluetooth::Hci {
static void BusyWaitMs(uint64_t ms) {
uint64_t start = Timekeeping::GetMilliseconds();
while (Timekeeping::GetMilliseconds() - start < ms) {
asm volatile("pause" ::: "memory");
Arch::Pause();
}
}
@@ -643,7 +644,7 @@ namespace Drivers::USB::Bluetooth::Hci {
Xhci::PollEvents();
DrainEvents();
for (int j = 0; j < 100; j++) {
asm volatile("" ::: "memory");
Arch::CompilerBarrier();
}
}
}
@@ -835,7 +836,7 @@ namespace Drivers::USB::Bluetooth::Hci {
}
for (int j = 0; j < 100; j++) {
asm volatile("" ::: "memory");
Arch::CompilerBarrier();
}
}
@@ -884,7 +885,7 @@ namespace Drivers::USB::Bluetooth::Hci {
}
for (int j = 0; j < 100; j++) {
asm volatile("" ::: "memory");
Arch::CompilerBarrier();
}
}
@@ -1644,7 +1645,7 @@ namespace Drivers::USB::Bluetooth::Hci {
}
}
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
// Distinguish "pipe dead" (0 completions) from "responses arriving but
@@ -1734,7 +1735,7 @@ namespace Drivers::USB::Bluetooth::Hci {
if (outStatus) *outStatus = g_secureStatus;
return true;
}
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
return false;
}
@@ -1809,7 +1810,7 @@ namespace Drivers::USB::Bluetooth::Hci {
<< " byte " << g_ssBytesSent;
return false;
}
asm volatile("pause" ::: "memory");
Arch::Pause();
}
g_aclTxLock.Acquire();
@@ -1846,7 +1847,7 @@ namespace Drivers::USB::Bluetooth::Hci {
DrainEvents();
if (g_aclTxTransportError.load(std::memory_order_acquire)) return false;
if (Timekeeping::GetMilliseconds() - start > timeoutMs) return false;
asm volatile("pause" ::: "memory");
Arch::Pause();
}
return !g_aclTxTransportError.load(std::memory_order_acquire);
}
@@ -1874,7 +1875,7 @@ namespace Drivers::USB::Bluetooth::Hci {
Xhci::PollEvents();
DrainEvents();
if (g_intelBootup) return true;
for (int j = 0; j < 100; j++) asm volatile("" ::: "memory");
for (int j = 0; j < 100; j++) Arch::CompilerBarrier();
}
KernelLogStream(ERROR, "BT-HCI") << "Timed out waiting for Intel bootup event";
@@ -12,13 +12,14 @@
*/
#include "IntelFirmware.hpp"
#include <Arch/Cpu.hpp>
#include "Hci.hpp"
#include <Fs/Vfs.hpp>
#include <Memory/Heap.hpp>
#include <Terminal/Terminal.hpp>
#include <CppLib/Stream.hpp>
#include <Libraries/Memory.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Timekeeping/Timer.hpp>
using namespace Kt;
@@ -475,7 +476,7 @@ namespace Drivers::USB::Bluetooth {
}
Fs::Vfs::ReadBackendFile(file, fw, 0, size);
Fs::Vfs::CloseBackendFile(file);
asm volatile("" ::: "memory");
Arch::CompilerBarrier();
// 4. Run the secure download + boot sequence.
bool ok = DownloadImage(fw, size, ver, cnvi, cnvr);
+3 -2
View File
@@ -5,6 +5,7 @@
*/
#include "L2cap.hpp"
#include <Arch/Cpu.hpp>
#include "Hci.hpp"
#include "A2dp.hpp"
#include "Avrcp.hpp"
@@ -12,7 +13,7 @@
#include <Terminal/Terminal.hpp>
#include <CppLib/Stream.hpp>
#include <Libraries/Memory.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Timekeeping/Timer.hpp>
using namespace Kt;
@@ -554,7 +555,7 @@ namespace Drivers::USB::Bluetooth::L2cap {
if (ch && ch->Configured) return true;
for (int j = 0; j < 100; j++) {
asm volatile("" ::: "memory");
Arch::CompilerBarrier();
}
}
return false;
+1 -1
View File
@@ -7,7 +7,7 @@
#include "HidKeyboard.hpp"
#include <Drivers/PS2/Keyboard.hpp>
#include <Terminal/Terminal.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Timekeeping/Timer.hpp>
#include <CppLib/Stream.hpp>
using namespace Kt;
+6 -7
View File
@@ -5,6 +5,7 @@
*/
#include "MassStorage.hpp"
#include <Arch/Cpu.hpp>
#include "Xhci.hpp"
#include "UsbDevice.hpp"
#include <Drivers/Storage/BlockDevice.hpp>
@@ -15,7 +16,7 @@
#include <Memory/HHDM.hpp>
#include <Memory/PageFrameAllocator.hpp>
#include <Libraries/Memory.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Timekeeping/Timer.hpp>
#include <atomic>
using namespace Kt;
@@ -130,12 +131,10 @@ namespace Drivers::USB::MassStorage {
}
static void PollWaitMs(uint32_t ms) {
uint64_t flags;
asm volatile("pushfq; pop %0" : "=r"(flags));
if ((flags & (1 << 9)) == 0) {
if (!Arch::InterruptsEnabled()) {
for (uint64_t i = 0; i < (uint64_t)ms * 1000; i++) {
Xhci::PollEvents();
asm volatile("outb %%al, $0x80" ::: "memory");
Arch::IoDelay();
}
return;
}
@@ -143,7 +142,7 @@ namespace Drivers::USB::MassStorage {
uint64_t start = Timekeeping::GetMilliseconds();
while (Timekeeping::GetMilliseconds() - start < ms) {
Xhci::PollEvents();
asm volatile("pause" ::: "memory");
Arch::Pause();
}
}
@@ -221,7 +220,7 @@ namespace Drivers::USB::MassStorage {
std::memory_order_acquire,
std::memory_order_relaxed)) {
expected = false;
asm volatile("pause" ::: "memory");
Arch::Pause();
}
}
+7 -8
View File
@@ -5,6 +5,7 @@
*/
#include "UsbDevice.hpp"
#include <Arch/Cpu.hpp>
#include "Xhci.hpp"
#include "HidKeyboard.hpp"
#include "HidMouse.hpp"
@@ -15,24 +16,22 @@
#include <Memory/HHDM.hpp>
#include <Memory/PageFrameAllocator.hpp>
#include <Libraries/Memory.hpp>
#include <Timekeeping/ApicTimer.hpp>
#include <Timekeeping/Timer.hpp>
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();
}
}
}
+28 -38
View File
@@ -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();
}
}
-2
View File
@@ -24,8 +24,6 @@ namespace Drivers::USB::Xhci {
// the IRQ dispatcher has one handler per slot, so sharing would replace
// one driver's handler and eventually strand USB or storage completions.
constexpr uint8_t MSI_IRQ = 29;
constexpr uint32_t MSI_VECTOR = 61;
constexpr uint32_t MSI_ADDR_BASE = 0xFEE00000;
// PCI class/subclass/progif for xHCI
constexpr uint8_t PCI_CLASS_SERIAL = 0x0C;