Files
ViperOS/VKernel/Kernel/platform/pch/timer.vp
T
TermiNexus 3a497e38ec fix(usb): 控制传输短读判失败+描述符链完整性校验;CCB 读改写屏蔽 IRQ1;清理已验证探针
uhci.control_transfer:除错误位外再比对 DATA TD 的 Actual Length(bit10:0)。短读时错误位可能全 0(QEMU/硬件不把短包当错误),只查错误位会漏 —— 现场是 USB 鼠标的 25 字节配置描述符只落下前 9 字节 ⇒ 接口解析为 0 ⇒ [usb_mse] no USB mouse found。

usb._parse_config 改为返回实际走完的偏移,enumerate_port 要求恰好走完 total_len,否则重读、仍不完整即报错返回(fail-fast,不带着半截描述符继续);同时删除两条探针。

keyboard.init/mouse.init 读-改-写 CCB 全程 pic.setMask(1):读 CCB 的 0x20 会把 CCB 值放进 0x60 输出缓冲并拉高 IRQ1,IRQ1 handler 会把它当扫描码抢走(现场 sc=0x47),使回读拿到残留值。改为只在校验失败时打印错误,去掉全部 [kbd] 探针。

清理已验证调试输出:idt 的 IRQ1 handler 探针及其计数器、desktop 的 [dbg] back_fb/row_buf/bg_row_buf、main 的 [DBG] LAPIC/idt32/swint/pic_isr 与 [DB] BootInfo 转储、timer 的 [PIT] 与自旋打印及随之无用的 import。
2026-10-16 15:26:35 +08:00

109 lines
3.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import platform.pch.pic as pic
import platform.pch.pit as pit
import sched.sched as sched
import drivers.core.cpu.apic as apic
import asm
define TIMER_FREQUENCY = 1000
define TICKS_PER_SECOND = TIMER_FREQUENCY
define MILLISECONDS_PER_TICK = (1000 / TIMER_FREQUENCY)
static ticks: volatile uint64 = 0
static seconds: volatile uint32 = 0
static milliseconds: volatile uint32 = 0
static timer_running: volatile bool = False
def timer_init():
global ticks, seconds, milliseconds, timer_running
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
ticks = 0
seconds = 0
milliseconds = 0
timer_running = True
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
pit.pit_init(TIMER_FREQUENCY)
def timer_handler():
global ticks, seconds, milliseconds, timer_running
if not timer_running:
pic.eoi(0)
apic.eoi()
return
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
ticks = ticks + 1
milliseconds = milliseconds + MILLISECONDS_PER_TICK
if milliseconds >= 1000:
seconds = seconds + 1
milliseconds = milliseconds - 1000
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
sched.Scheduler.sched_tick()
pic.eoi(0)
# LAPIC EOI:APIC 启用后中断经 LINT0(EXTINT) 送达会置 LAPIC ISR,
# 只发 PIC EOI 不清 LAPIC ISR → 首个定时中断后后续中断被屏蔽 →
# ticks 不推进 → msleep 永久挂起(QEMU/OVMF 下 APIC 必启用)。
apic.eoi()
def timer_start():
global timer_running
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
timer_running = True
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
def timer_stop():
global timer_running
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
timer_running = False
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
def timer_reset():
global ticks, seconds, milliseconds
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
ticks = 0
seconds = 0
milliseconds = 0
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
def timer_get_ticks() -> uint64:
current_ticks: uint64
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
current_ticks = ticks
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
return current_ticks
def timer_get_seconds() -> uint32:
current_seconds: uint32
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
current_seconds = seconds
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
return current_seconds
def timer_get_milliseconds() -> uint32:
current_milliseconds: uint32
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
current_milliseconds = milliseconds
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
return current_milliseconds
def timer_get_time(out_seconds: uint32*, out_milliseconds: uint32*):
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
if out_seconds:
*out_seconds = seconds
if out_milliseconds:
*out_milliseconds = milliseconds
__asm__("mfence", op=[ASM_DESCR.CLOBBER_MEMORY])
def timer_msleep(ms: uint32):
target: uint64 = ticks + (ms + MILLISECONDS_PER_TICK - 1) / MILLISECONDS_PER_TICK
while ticks < target:
asm.sti()
asm.hlt()
sched.Scheduler._yield()
def timer_sleep(sec: uint32):
target: uint64 = ticks + sec * TICKS_PER_SECOND
while ticks < target:
asm.sti()
asm.hlt()
sched.Scheduler._yield()