From be868a43185826b02bf6d091019bb779678525bb Mon Sep 17 00:00:00 2001 From: salmonik Date: Mon, 17 Aug 2026 14:53:52 +0200 Subject: USB2/1.1 (EHCI/UHCI) drivers + real-hardware bring-up hardening - Add polled EHCI (USB2) and UHCI (USB1.1) host-controller drivers with HID boot mouse support, wired into cursor polling and the 'usb' shell cmd - Add USB Legacy ownership handoff (claim_usb_legacy) plus config_write_byte - Harden boot: verify the PIT/timer ticks before shell entry, EOI stray interrupts in the LAPIC to stop interrupt storms, bound PS/2 controller waits, and INTx-disable AHCI (polled driver) - Add boot stage markers, klog screen echo, and QR lock; scheduler mark_shell_running; NO_USB stopgap to keep BIOS USB-Legacy input alive - alloc_pages_above for DMA buffers that must avoid low conventional memory - Expand DEBUG_NOTES with EHCI/QEMU bring-up findings --- rsnix/src/memory.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'rsnix/src/memory.rs') diff --git a/rsnix/src/memory.rs b/rsnix/src/memory.rs index 099f607..2a32da8 100644 --- a/rsnix/src/memory.rs +++ b/rsnix/src/memory.rs @@ -1194,6 +1194,50 @@ pub fn alloc_pages(count: usize) -> Option { alloc_pages_aligned(count, 1) } +/// Allocate `count` contiguous physical pages at or above `min_addr` +/// (first-fit upward from there). Used for controller DMA buffers that +/// must avoid low conventional memory — the first 640 K on some real +/// chipsets is hostile to PCI masters and shows up as a controller +/// "System Error" (SE) halt. Page-aligned like `alloc_pages`. +pub fn alloc_pages_above(count: usize, min_addr: usize) -> Option { + if count == 0 { + return None; + } + unsafe { + if BITMAP.is_null() { + return None; + } + let span = SPAN_PAGES; + let min_page = min_addr.div_ceil(PAGE_SIZE).max(BASE_PAGE); + if min_page >= BASE_PAGE + span { + return None; + } + let start_idx = min_page - BASE_PAGE; + let mut run_start = 0usize; + let mut run_len = 0usize; + for idx in start_idx..span { + let free = (*BITMAP.add(idx / 8) >> (idx % 8)) & 1 == 0; + if free { + if run_len == 0 { + run_start = idx; + } + run_len += 1; + if run_len >= count { + let p = (BASE_PAGE + run_start) * PAGE_SIZE; + for k in run_start..run_start + count { + *BITMAP.add(k / 8) |= 1 << (k % 8); + } + FREE_PAGES -= count; + return Some(p); + } + } else { + run_len = 0; + } + } + None + } +} + /// Allocate `count` contiguous physical pages whose start address is /// aligned to `align_pages` (a power of two, in page units). pub fn alloc_pages_aligned(count: usize, align_pages: usize) -> Option { -- cgit v1.2.3