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()