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,12 +5,12 @@
|
||||
*/
|
||||
|
||||
#include "IntelHda.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "Mixer.hpp"
|
||||
#include <Memory/PageFrameAllocator.hpp>
|
||||
#include <Memory/HHDM.hpp>
|
||||
#include <Memory/Paging.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Hal/Apic/IoApic.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
@@ -173,7 +173,7 @@ namespace Drivers::Audio::IntelHda {
|
||||
static void MicroDelay(int us) {
|
||||
// Simple busy-wait; us is approximate
|
||||
for (volatile int i = 0; i < us * 100; i++) {
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -851,13 +851,9 @@ namespace Drivers::Audio::IntelHda {
|
||||
uint16_t msgCtrl = Pci::LegacyRead16(bus, dev, func, cap + 2);
|
||||
bool is64bit = (msgCtrl & (1 << 7)) != 0;
|
||||
|
||||
Pci::LegacyWrite32(bus, dev, func, cap + 4, MSI_ADDR_BASE);
|
||||
|
||||
if (is64bit) {
|
||||
Pci::LegacyWrite32(bus, dev, func, cap + 8, 0);
|
||||
Pci::LegacyWrite16(bus, dev, func, cap + 12, MSI_VECTOR);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
msgCtrl &= ~(0x70);
|
||||
@@ -868,10 +864,9 @@ namespace Drivers::Audio::IntelHda {
|
||||
pciCmd |= Pci::PCI_CMD_INTX_DISABLE;
|
||||
Pci::LegacyWrite16(bus, dev, func, (uint8_t)Pci::PCI_REG_COMMAND, pciCmd);
|
||||
|
||||
Hal::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
Arch::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
|
||||
KernelLogStream(OK, "HDA") << "MSI enabled: vector " << base::dec << (uint64_t)MSI_VECTOR
|
||||
<< " (IRQ slot " << (uint64_t)MSI_IRQ << ")" << (is64bit ? " [64-bit]" : " [32-bit]");
|
||||
KernelLogStream(OK, "HDA") << "MSI enabled: IRQ slot " << base::dec << (uint64_t)MSI_IRQ << (is64bit ? " [64-bit]" : " [32-bit]");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1023,8 +1018,8 @@ namespace Drivers::Audio::IntelHda {
|
||||
(uint8_t)Pci::PCI_REG_COMMAND);
|
||||
Pci::LegacyWrite16(g_bus, g_dev, g_func,
|
||||
(uint8_t)Pci::PCI_REG_COMMAND, command & ~Pci::PCI_CMD_INTX_DISABLE);
|
||||
Hal::RegisterIrqHandler(irqLine, HandleInterrupt);
|
||||
Hal::IoApic::UnmaskIrq(Hal::IoApic::GetGsiForIrq(irqLine));
|
||||
Arch::RegisterIrqHandler(irqLine, HandleInterrupt);
|
||||
Arch::EnableLegacyIrq(irqLine);
|
||||
} else {
|
||||
KernelLogStream(WARNING, "HDA") << "No interrupt available, polling only";
|
||||
}
|
||||
|
||||
@@ -235,9 +235,7 @@ namespace Drivers::Audio::IntelHda {
|
||||
// MSI configuration
|
||||
// =========================================================================
|
||||
|
||||
constexpr uint8_t MSI_IRQ = 27; // IRQ slot 27 = vector 59
|
||||
constexpr uint32_t MSI_VECTOR = 59;
|
||||
constexpr uint32_t MSI_ADDR_BASE = 0xFEE00000;
|
||||
constexpr uint8_t MSI_IRQ = 27; // IRQ slot 27
|
||||
|
||||
// =========================================================================
|
||||
// Audio stream state (one active output stream)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <ACPI/AML/AmlInterpreter.hpp>
|
||||
#include <Boot/Boot.hpp>
|
||||
#include <Memory/HHDM.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include "IntelGPU.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include <Pci/Pci.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
@@ -17,7 +18,7 @@
|
||||
#include <Io/IoPort.hpp>
|
||||
#include <Graphics/Framebuffer.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
@@ -500,7 +501,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
int busyWait = 100000;
|
||||
while (((g_auxLastStatus = ReadReg(g_auxControlReg)) & DP_AUX_SEND_BUSY)
|
||||
&& --busyWait)
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
if (!busyWait) return -1;
|
||||
|
||||
for (int i = 0; i < sendBytes; i += 4) {
|
||||
@@ -523,7 +524,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
status = ReadReg(g_auxControlReg);
|
||||
g_auxLastStatus = status;
|
||||
if (!(status & DP_AUX_SEND_BUSY)) break;
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
} while (--completeWait);
|
||||
|
||||
if (!completeWait) return -1;
|
||||
@@ -568,7 +569,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
return true;
|
||||
if (nativeReply != 2 && i2cReply != 8 && result >= 0) return false;
|
||||
for (int delay = 0; delay < 40000; delay++)
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1012,7 +1013,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
}
|
||||
|
||||
static void ShortSpin() {
|
||||
for (int i = 0; i < 20000; i++) asm volatile("pause");
|
||||
for (int i = 0; i < 20000; i++) Arch::Pause();
|
||||
}
|
||||
|
||||
// ---- Panel PWM ----------------------------------------------------------
|
||||
@@ -1210,7 +1211,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
if (status & GMBUS_SATOER) return false;
|
||||
if (status & bit) return true;
|
||||
if (Timekeeping::GetMilliseconds() - start > 50) return false;
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1218,7 +1219,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
uint64_t start = Timekeeping::GetMilliseconds();
|
||||
while (ReadReg(GMBUS2) & GMBUS_ACTIVE) {
|
||||
if (Timekeeping::GetMilliseconds() - start > 50) return false;
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1706,7 +1707,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
previous = current;
|
||||
if ((i & 0x3FF) == 0 &&
|
||||
Timekeeping::GetMilliseconds() - started >= 100) return false;
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2098,7 +2099,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
for (int i = 0; i < 200000; i++) {
|
||||
bool state = (ReadReg(g_transConfReg) & PIPECONF_STATE) != 0;
|
||||
if (state == enabled) return true;
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2366,7 +2367,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
|
||||
// Scanout memory is exposed through WC mappings. Drain userspace's
|
||||
// completed frame before programming the display-plane surface.
|
||||
asm volatile("sfence" ::: "memory");
|
||||
Arch::StoreFence();
|
||||
uint64_t gttOff = (index == 0) ? g_fbGttOffsetA : g_buf1GttOffset;
|
||||
WriteReg(DSPASURF, (uint32_t)gttOff);
|
||||
(void)ReadReg(DSPASURF);
|
||||
@@ -2511,7 +2512,7 @@ namespace Drivers::Graphics::IntelGPU {
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
if (ReadReg(PIPEACONF) & PIPECONF_STATE)
|
||||
break;
|
||||
asm volatile("pause");
|
||||
Arch::Pause();
|
||||
}
|
||||
|
||||
if (!(ReadReg(PIPEACONF) & PIPECONF_STATE)) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "InputEvents.hpp"
|
||||
#include <atomic>
|
||||
#include <Sched/Scheduler.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
|
||||
namespace Drivers::InputEvents {
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
#include <Memory/Paging.hpp>
|
||||
#include <Memory/PageFrameAllocator.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Hal/Apic/IoApic.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
#include <atomic>
|
||||
|
||||
@@ -340,8 +339,8 @@ namespace Drivers::Net::E1000 {
|
||||
SetupRx();
|
||||
SetupTx();
|
||||
|
||||
Hal::RegisterIrqHandler(g_irqLine, HandleInterrupt);
|
||||
Hal::IoApic::UnmaskIrq(Hal::IoApic::GetGsiForIrq(g_irqLine));
|
||||
Arch::RegisterIrqHandler(g_irqLine, HandleInterrupt);
|
||||
Arch::EnableLegacyIrq(g_irqLine);
|
||||
WriteReg(REG_IMS, RX_INTERRUPT_MASK | ICR_LSC);
|
||||
|
||||
g_initialized = true;
|
||||
@@ -450,8 +449,8 @@ namespace Drivers::Net::E1000 {
|
||||
SetupTx();
|
||||
|
||||
// Register interrupt handler
|
||||
Hal::RegisterIrqHandler(g_irqLine, HandleInterrupt);
|
||||
Hal::IoApic::UnmaskIrq(Hal::IoApic::GetGsiForIrq(g_irqLine));
|
||||
Arch::RegisterIrqHandler(g_irqLine, HandleInterrupt);
|
||||
Arch::EnableLegacyIrq(g_irqLine);
|
||||
|
||||
// Enable RX and link-change only. TX completion is polled by descriptor.
|
||||
WriteReg(REG_IMS, RX_INTERRUPT_MASK | ICR_LSC);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "E1000E.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include <Pci/Pci.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
@@ -12,8 +13,7 @@
|
||||
#include <Memory/Paging.hpp>
|
||||
#include <Memory/PageFrameAllocator.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Hal/Apic/IoApic.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
#include <atomic>
|
||||
|
||||
@@ -80,9 +80,7 @@ namespace Drivers::Net::E1000E {
|
||||
static constexpr uint32_t g_deviceTableSize = sizeof(g_deviceTable) / sizeof(g_deviceTable[0]);
|
||||
|
||||
// MSI configuration
|
||||
static constexpr uint8_t MSI_IRQ = 24; // IRQ slot 24 = vector 56 (first MSI slot)
|
||||
static constexpr uint32_t MSI_VECTOR = 56; // IRQ_VECTOR_BASE + MSI_IRQ
|
||||
static constexpr uint32_t MSI_ADDR_BASE = 0xFEE00000; // Local APIC message address range
|
||||
static constexpr uint8_t MSI_IRQ = 24; // first MSI IRQ slot
|
||||
|
||||
// Driver state
|
||||
static bool g_initialized = false;
|
||||
@@ -434,17 +432,9 @@ namespace Drivers::Net::E1000E {
|
||||
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)
|
||||
@@ -458,10 +448,9 @@ namespace Drivers::Net::E1000E {
|
||||
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, "E1000E") << "MSI enabled: vector " << base::dec << (uint64_t)MSI_VECTOR
|
||||
<< " (IRQ slot " << (uint64_t)MSI_IRQ << ")" << (is64bit ? " [64-bit]" : " [32-bit]");
|
||||
KernelLogStream(OK, "E1000E") << "MSI enabled: IRQ slot " << base::dec << (uint64_t)MSI_IRQ << (is64bit ? " [64-bit]" : " [32-bit]");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -545,7 +534,7 @@ namespace Drivers::Net::E1000E {
|
||||
WriteReg(REG_CTRL, ctrl | CTRL_RST);
|
||||
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
if (!(ReadReg(REG_CTRL) & CTRL_RST)) break;
|
||||
@@ -592,8 +581,8 @@ namespace Drivers::Net::E1000E {
|
||||
(uint8_t)Pci::PCI_REG_COMMAND);
|
||||
Pci::LegacyWrite16(bus, device, function,
|
||||
(uint8_t)Pci::PCI_REG_COMMAND, command & ~Pci::PCI_CMD_INTX_DISABLE);
|
||||
Hal::RegisterIrqHandler(g_irqLine, HandleInterrupt);
|
||||
Hal::IoApic::UnmaskIrq(Hal::IoApic::GetGsiForIrq(g_irqLine));
|
||||
Arch::RegisterIrqHandler(g_irqLine, HandleInterrupt);
|
||||
Arch::EnableLegacyIrq(g_irqLine);
|
||||
WriteReg(REG_IMS, RX_INTERRUPT_MASK | ICR_LSC);
|
||||
} else {
|
||||
KernelLogStream(WARNING, "E1000E") << "No MSI or legacy IRQ available, using polling mode";
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "Iwx.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include <Fs/Vfs.hpp>
|
||||
#include <Memory/Heap.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
@@ -342,7 +343,7 @@ namespace Drivers::Net::Wifi {
|
||||
}
|
||||
Fs::Vfs::ReadBackendFile(file, buf, 0, size);
|
||||
Fs::Vfs::CloseBackendFile(file);
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
|
||||
*outSize = size;
|
||||
return buf;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "Iwx.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "Ieee80211.hpp"
|
||||
#include <Pci/Pci.hpp>
|
||||
#include <Memory/HHDM.hpp>
|
||||
@@ -26,8 +27,8 @@
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
@@ -38,8 +39,6 @@ namespace Drivers::Net::Wifi {
|
||||
// MSI-X/MSI interrupt slot. Slots in use elsewhere: 24 (E1000E),
|
||||
// 27 (Intel HDA), 28 (GPU vblank), 29 (xHCI).
|
||||
static constexpr uint8_t MSI_IRQ = 25;
|
||||
static constexpr uint32_t MSI_VECTOR = 57; // IRQ_VECTOR_BASE + MSI_IRQ
|
||||
static constexpr uint32_t MSI_ADDR_BASE = 0xFEE00000;
|
||||
|
||||
// Cached MSI-X masks (a cause is ENABLED when its mask bit is clear).
|
||||
static uint32_t g_fhInitMask = 0;
|
||||
@@ -76,14 +75,14 @@ namespace Drivers::Net::Wifi {
|
||||
// exposed here; the loop count is calibrated the same way IntelHda does it.
|
||||
void IwxDelayUs(uint32_t us) {
|
||||
for (volatile uint32_t i = 0; i < us * 100u; i++) {
|
||||
asm volatile("pause" ::: "memory");
|
||||
Arch::Pause();
|
||||
}
|
||||
}
|
||||
|
||||
void IwxDelayMs(uint32_t ms) {
|
||||
uint64_t start = Timekeeping::GetMilliseconds();
|
||||
while (Timekeeping::GetMilliseconds() - start < ms) {
|
||||
asm volatile("pause" ::: "memory");
|
||||
Arch::Pause();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +143,13 @@ namespace Drivers::Net::Wifi {
|
||||
|
||||
uint32_t IwxReadPrph(uint32_t addr) {
|
||||
IwxWrite32(IWX_HBUS_TARG_PRPH_RADDR, PrphAddr(addr));
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
return IwxRead32(IWX_HBUS_TARG_PRPH_RDAT);
|
||||
}
|
||||
|
||||
void IwxWritePrph(uint32_t addr, uint32_t val) {
|
||||
IwxWrite32(IWX_HBUS_TARG_PRPH_WADDR, PrphAddr(addr));
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
IwxWrite32(IWX_HBUS_TARG_PRPH_WDAT, val);
|
||||
}
|
||||
|
||||
@@ -457,7 +456,7 @@ namespace Drivers::Net::Wifi {
|
||||
descs[i].rbid = (uint16_t)(i & 0xffff);
|
||||
descs[i].addr = g_iwx.RxQ.BufPhys[i];
|
||||
}
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
// `stageSlots` reserves one page per concurrently queued frame; pass 0 for
|
||||
@@ -652,7 +651,7 @@ namespace Drivers::Net::Wifi {
|
||||
ci->mcr_size = (uint16_t)IWX_RX_QUEUE_CB_SIZE(IWX_RX_MQ_RING_COUNT);
|
||||
|
||||
memcpy(g_iwx.ImlDma.Virt, g_iwx.Fw.Iml, g_iwx.Fw.ImlLen);
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
|
||||
uint64_t paddr = g_iwx.CtxtInfo.Phys;
|
||||
IwxWrite32(IWX_CSR_CTXT_INFO_ADDR, (uint32_t)(paddr & 0xffffffff));
|
||||
@@ -829,7 +828,7 @@ namespace Drivers::Net::Wifi {
|
||||
auto* scratch = (IwxPrphScratch*)g_iwx.PrphScratch.Virt;
|
||||
scratch->ctrl_cfg.pnvm_cfg.pnvm_base_addr = g_iwx.PnvmDma.Phys;
|
||||
scratch->ctrl_cfg.pnvm_cfg.pnvm_size = g_iwx.PnvmSize;
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
if (!IwxNicLock()) return false;
|
||||
@@ -1006,7 +1005,7 @@ namespace Drivers::Net::Wifi {
|
||||
} else {
|
||||
desc->num_tbs = 1;
|
||||
}
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
|
||||
g_iwx.CmdDone = false;
|
||||
g_iwx.LastCmdId = code;
|
||||
@@ -1337,7 +1336,7 @@ namespace Drivers::Net::Wifi {
|
||||
auto* bc = (IwxGen3BcTblEntry*)ring.BcTbl.Virt;
|
||||
bc[idx].tfd_offset = (uint16_t)((hdrLen + payloadLen) | (chunks << 14));
|
||||
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
|
||||
ring.Queued++;
|
||||
ring.Cur = (ring.Cur + 1) % IWX_TX_RING_COUNT;
|
||||
@@ -1488,7 +1487,7 @@ namespace Drivers::Net::Wifi {
|
||||
static bool IwxReadMem(uint32_t addr, uint32_t* out, int dwords) {
|
||||
if (!IwxNicLock()) return false;
|
||||
IwxWrite32(IWX_HBUS_TARG_MEM_RADDR, addr);
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
for (int i = 0; i < dwords; i++)
|
||||
out[i] = IwxRead32(IWX_HBUS_TARG_MEM_RDAT);
|
||||
IwxNicUnlock();
|
||||
@@ -1786,11 +1785,17 @@ namespace Drivers::Net::Wifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Message for our IRQ slot on the boot CPU
|
||||
Arch::MsiMessage msi;
|
||||
if (!Arch::ComposeMsi(MSI_IRQ, msi)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Program entry 0: all causes are mapped to vector 0 by IwxConfMsixHw.
|
||||
volatile uint32_t* entry = (volatile uint32_t*)(g_iwx.Mmio + tableOff);
|
||||
entry[0] = MSI_ADDR_BASE; // message address (BSP, physical, fixed)
|
||||
entry[1] = 0; // upper address
|
||||
entry[2] = MSI_VECTOR; // message data
|
||||
entry[0] = (uint32_t)msi.address; // message address
|
||||
entry[1] = (uint32_t)(msi.address >> 32); // upper address
|
||||
entry[2] = msi.data; // message data
|
||||
entry[3] = 0; // vector control: unmasked
|
||||
|
||||
msgCtrl |= (1 << 15); // MSI-X enable
|
||||
@@ -1801,9 +1806,8 @@ namespace Drivers::Net::Wifi {
|
||||
pciCmd |= Pci::PCI_CMD_INTX_DISABLE;
|
||||
Pci::LegacyWrite16(bus, dev, func, (uint8_t)Pci::PCI_REG_COMMAND, pciCmd);
|
||||
|
||||
Hal::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
KernelLogStream(OK, "WiFi") << "MSI-X enabled: vector "
|
||||
<< (uint64_t)MSI_VECTOR << " (IRQ slot " << (uint64_t)MSI_IRQ << ")";
|
||||
Arch::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
KernelLogStream(OK, "WiFi") << "MSI-X enabled: IRQ slot " << (uint64_t)MSI_IRQ;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1814,14 +1818,10 @@ namespace Drivers::Net::Wifi {
|
||||
Pci::DisableInterruptDelivery(bus, dev, func);
|
||||
|
||||
uint16_t msgCtrl = Pci::LegacyRead16(bus, dev, func, cap + 2);
|
||||
bool is64 = (msgCtrl & (1 << 7)) != 0;
|
||||
|
||||
Pci::LegacyWrite32(bus, dev, func, cap + 4, MSI_ADDR_BASE);
|
||||
if (is64) {
|
||||
Pci::LegacyWrite32(bus, dev, func, cap + 8, 0);
|
||||
Pci::LegacyWrite16(bus, dev, func, cap + 12, MSI_VECTOR);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
msgCtrl &= ~0x70; // single message
|
||||
@@ -1832,9 +1832,8 @@ namespace Drivers::Net::Wifi {
|
||||
pciCmd |= Pci::PCI_CMD_INTX_DISABLE;
|
||||
Pci::LegacyWrite16(bus, dev, func, (uint8_t)Pci::PCI_REG_COMMAND, pciCmd);
|
||||
|
||||
Hal::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
KernelLogStream(OK, "WiFi") << "MSI enabled: vector "
|
||||
<< (uint64_t)MSI_VECTOR << " (IRQ slot " << (uint64_t)MSI_IRQ << ")";
|
||||
Arch::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
|
||||
KernelLogStream(OK, "WiFi") << "MSI enabled: IRQ slot " << (uint64_t)MSI_IRQ;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "Wifi.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "Iwx.hpp"
|
||||
#include "Wpa.hpp"
|
||||
#include <Fs/Vfs.hpp>
|
||||
@@ -19,10 +20,9 @@
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Hal/SmpBoot.hpp>
|
||||
#include <Hal/Apic/Apic.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
#include <Arch/Smp.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <Sched/Scheduler.hpp>
|
||||
#include <atomic>
|
||||
|
||||
@@ -444,8 +444,7 @@ namespace Drivers::Net::Wifi {
|
||||
auto* t = Smp::GetCpuData(i);
|
||||
if (!t || !t->started) continue;
|
||||
if (t->currentSlot >= 0 || t->reservedForKernelWork) continue;
|
||||
if (Hal::LocalApic::SendFixedIpi(t->lapicId,
|
||||
Hal::IRQ_VECTOR_BASE + Hal::IRQ_RESCHEDULE)) {
|
||||
if (Arch::SendIpi(t->cpuIndex, Arch::IRQ_RESCHEDULE)) {
|
||||
g_lastApKickMs = now;
|
||||
return true;
|
||||
}
|
||||
@@ -624,7 +623,7 @@ namespace Drivers::Net::Wifi {
|
||||
uint64_t start = Timekeeping::GetMilliseconds();
|
||||
while (g_iwx.ScanActive && Timekeeping::GetMilliseconds() - start < timeoutMs) {
|
||||
IwxProcessEvents();
|
||||
for (int i = 0; i < 200; i++) asm volatile("pause" ::: "memory");
|
||||
for (int i = 0; i < 200; i++) Arch::Pause();
|
||||
}
|
||||
|
||||
if (g_iwx.ScanActive) {
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
*/
|
||||
|
||||
#include "Wpa.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "Ieee80211.hpp"
|
||||
#include <Libraries/Crypto.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
@@ -131,12 +132,9 @@ namespace Drivers::Net::Wifi {
|
||||
} pool;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint64_t tsc;
|
||||
asm volatile("rdtsc; shl $32, %%rdx; or %%rdx, %%rax"
|
||||
: "=a"(tsc) :: "rdx");
|
||||
pool.tsc[i] = tsc;
|
||||
pool.tsc[i] = Arch::ReadTimestamp();
|
||||
// Space the samples out so the low bits differ between them.
|
||||
for (int k = 0; k < 64; k++) asm volatile("pause" ::: "memory");
|
||||
for (int k = 0; k < 64; k++) Arch::Pause();
|
||||
}
|
||||
pool.counter = ++counter;
|
||||
memcpy(pool.mac, g_cfg.OwnMac, 6);
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
*/
|
||||
|
||||
#include "Keyboard.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "PS2Controller.hpp"
|
||||
|
||||
#include <Io/IoPort.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Hal/Apic/IoApic.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <Drivers/Input/InputEvents.hpp>
|
||||
|
||||
namespace Drivers::PS2::Keyboard {
|
||||
@@ -145,8 +145,8 @@ namespace Drivers::PS2::Keyboard {
|
||||
g_ExtendedScancode = false;
|
||||
|
||||
// Register IRQ handler and unmask IRQ1 on the IOAPIC
|
||||
Hal::RegisterIrqHandler(Hal::IRQ_KEYBOARD, HandleIRQ);
|
||||
Hal::IoApic::UnmaskIrq(Hal::IoApic::GetGsiForIrq(Hal::IRQ_KEYBOARD));
|
||||
Arch::RegisterIrqHandler(Arch::IRQ_KEYBOARD, HandleIRQ);
|
||||
Arch::EnableLegacyIrq(Arch::IRQ_KEYBOARD);
|
||||
|
||||
Kt::KernelLogStream(Kt::OK, "PS2/KB") << "Keyboard driver initialized";
|
||||
}
|
||||
@@ -299,7 +299,7 @@ namespace Drivers::PS2::Keyboard {
|
||||
}
|
||||
}
|
||||
// Yield the CPU while waiting
|
||||
asm volatile("hlt");
|
||||
Arch::Halt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
#include <CppLib/Stream.hpp>
|
||||
#include <CppLib/Spinlock.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <Hal/Apic/Interrupts.hpp>
|
||||
#include <Hal/Apic/IoApic.hpp>
|
||||
#include <Arch/Interrupts.hpp>
|
||||
#include <Drivers/Input/InputEvents.hpp>
|
||||
|
||||
namespace Drivers::PS2::Mouse {
|
||||
@@ -103,8 +102,8 @@ namespace Drivers::PS2::Mouse {
|
||||
g_PacketIndex = 0;
|
||||
|
||||
// Register IRQ handler and unmask IRQ12 on the IOAPIC
|
||||
Hal::RegisterIrqHandler(Hal::IRQ_MOUSE, HandleIRQ);
|
||||
Hal::IoApic::UnmaskIrq(Hal::IoApic::GetGsiForIrq(Hal::IRQ_MOUSE));
|
||||
Arch::RegisterIrqHandler(Arch::IRQ_MOUSE, HandleIRQ);
|
||||
Arch::EnableLegacyIrq(Arch::IRQ_MOUSE);
|
||||
|
||||
Kt::KernelLogStream(Kt::OK, "PS2/Mouse") << "Mouse driver initialized";
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "Ahci.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "BlockDevice.hpp"
|
||||
#include <Pci/Pci.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
@@ -91,14 +92,14 @@ namespace Drivers::Storage::Ahci {
|
||||
KernelLogStream(OK, "AHCI") << "BIOS handoff complete";
|
||||
return;
|
||||
}
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
// If BIOS Busy, wait another 2 seconds
|
||||
if (ReadReg(REG_BOHC) & BOHC_BB) {
|
||||
for (int i = 0; i < 2000000; i++) {
|
||||
if (!(ReadReg(REG_BOHC) & BOHC_BB)) break;
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +131,7 @@ namespace Drivers::Storage::Ahci {
|
||||
if (!(cmd & PORT_CMD_CR) && !(cmd & PORT_CMD_FR)) {
|
||||
return;
|
||||
}
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
KernelLogStream(WARNING, "AHCI") << "Port " << port << " stop timed out";
|
||||
@@ -140,7 +141,7 @@ namespace Drivers::Storage::Ahci {
|
||||
// Wait for CR to clear before starting
|
||||
for (int i = 0; i < 500000; i++) {
|
||||
if (!(ReadPortReg(port, PORT_CMD) & PORT_CMD_CR)) break;
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
uint32_t cmd = ReadPortReg(port, PORT_CMD);
|
||||
@@ -170,7 +171,7 @@ namespace Drivers::Storage::Ahci {
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
uint32_t tfd = ReadPortReg(port, PORT_TFD);
|
||||
if (!(tfd & PORT_TFD_BSY)) break;
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
uint32_t sig = ReadPortReg(port, PORT_SIG);
|
||||
@@ -248,7 +249,7 @@ namespace Drivers::Storage::Ahci {
|
||||
// Wait for the slot to be free
|
||||
for (int i = 0; i < 500000; i++) {
|
||||
if (!(ReadPortReg(port, PORT_CI) & (1u << slot))) break;
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
// Check that the port isn't in error
|
||||
@@ -258,7 +259,7 @@ namespace Drivers::Storage::Ahci {
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
tfd = ReadPortReg(port, PORT_TFD);
|
||||
if (!(tfd & (PORT_TFD_BSY | PORT_TFD_DRQ))) break;
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
if (tfd & (PORT_TFD_BSY | PORT_TFD_DRQ)) {
|
||||
KernelLogStream(ERROR, "AHCI") << "Port " << port << " device busy before command issue";
|
||||
@@ -294,7 +295,7 @@ namespace Drivers::Storage::Ahci {
|
||||
return false;
|
||||
}
|
||||
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
KernelLogStream(ERROR, "AHCI") << "Port " << port << " command timeout";
|
||||
@@ -554,7 +555,7 @@ namespace Drivers::Storage::Ahci {
|
||||
WriteReg(REG_GHC, ghc);
|
||||
return true;
|
||||
}
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
KernelLogStream(ERROR, "AHCI") << "HBA reset timed out";
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "Gpt.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "BlockDevice.hpp"
|
||||
#include <Terminal/Terminal.hpp>
|
||||
#include <CppLib/Stream.hpp>
|
||||
@@ -565,13 +566,11 @@ namespace Drivers::Storage::Gpt {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Simple GUID generation from RDTSC + mixing
|
||||
// Simple GUID generation from the CPU timestamp counter + mixing
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static uint64_t SimpleRand64() {
|
||||
uint32_t lo, hi;
|
||||
asm volatile ("rdtsc" : "=a"(lo), "=d"(hi));
|
||||
uint64_t val = ((uint64_t)hi << 32) | lo;
|
||||
uint64_t val = Arch::ReadTimestamp();
|
||||
// xorshift64
|
||||
val ^= val << 13;
|
||||
val ^= val >> 7;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "Nvme.hpp"
|
||||
#include <Arch/Cpu.hpp>
|
||||
#include "BlockDevice.hpp"
|
||||
#include <Pci/Pci.hpp>
|
||||
#include <Terminal/Terminal.hpp>
|
||||
@@ -13,7 +14,7 @@
|
||||
#include <Memory/Paging.hpp>
|
||||
#include <Memory/PageFrameAllocator.hpp>
|
||||
#include <Libraries/Memory.hpp>
|
||||
#include <Timekeeping/ApicTimer.hpp>
|
||||
#include <Timekeeping/Timer.hpp>
|
||||
|
||||
using namespace Kt;
|
||||
|
||||
@@ -191,7 +192,7 @@ namespace Drivers::Storage::Nvme {
|
||||
if ((spins & 0x3FFF) == 0 &&
|
||||
Timekeeping::GetMilliseconds() - start >= kTimeoutMs) break;
|
||||
if (spins >= kMaxSpins) break;
|
||||
asm volatile("pause" ::: "memory");
|
||||
Arch::Pause();
|
||||
}
|
||||
|
||||
KernelLogStream(ERROR, "NVMe") << "Command " << base::dec << (uint64_t)cmdId
|
||||
@@ -254,7 +255,7 @@ namespace Drivers::Storage::Nvme {
|
||||
if (!(csts & CSTS_RDY)) {
|
||||
return true;
|
||||
}
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
KernelLogStream(ERROR, "NVMe") << "Controller disable timeout";
|
||||
@@ -280,7 +281,7 @@ namespace Drivers::Storage::Nvme {
|
||||
if (csts & CSTS_RDY) {
|
||||
return true;
|
||||
}
|
||||
asm volatile("" ::: "memory");
|
||||
Arch::CompilerBarrier();
|
||||
}
|
||||
|
||||
KernelLogStream(ERROR, "NVMe") << "Controller enable timeout";
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user