Files
TermiNexus a518f75b24 chore(vkernel): 重置基线 — 纳入 TPV codegen 修复配合的内核侧调整与既有工作区内容
- devfs.vp: string.split 传 PATH_BUFFER_SIZE(配合 split 新增容量参数)

- fat32_types.vp: lfn_extract 越界钳制(base+i > MAX_LFN 返回 -1)

- sheet.vp: gfx.Renderer 实参修正为 (fb, zb, w, h)(原单参导致 w/h=0 渲染空操作)

- 同批包含 VKernel 其余既有移植改动与 vpsdk/Apps/Libs 工作区内容
2026-09-11 14:27:01 +08:00

130 lines
4.4 KiB
Plaintext
Raw Permalink 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 drivers.serial.uart.serial as serial
import viperlib
import asm
import t, c
TIMER_FREQUENCY: t.CDefine = 1000
TICKS_PER_SECOND: t.CDefine = TIMER_FREQUENCY
MILLISECONDS_PER_TICK: t.CDefine = (1000 / TIMER_FREQUENCY)
ticks: t.CStatic | t.CVolatile | uint64 = 0
seconds: t.CStatic | t.CVolatile | uint32 = 0
milliseconds: t.CStatic | t.CVolatile | uint32 = 0
timer_running: t.CStatic | t.CVolatile | bool = False
_dbg_once: int = 0
def timer_init():
global ticks, seconds, milliseconds, timer_running
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
ticks = 0
seconds = 0
milliseconds = 0
timer_running = True
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
pit.pit_init(TIMER_FREQUENCY)
# [DBG] 读 PIT 计数器验证是否在走(用后移除)
asm.outb(0x43, 0x00) # latch channel 0
_lo: uint8 = asm.inb(0x40)
_hi: uint8 = asm.inb(0x40)
_cnt: int = int(_lo) | (int(_hi) << 8)
_cb: t.CArray[t.CChar, 40]
viperlib.snprintf(c.Addr(_cb), 40, "[PIT] cnt=%d\n", _cnt)
serial.puts(c.Addr(_cb))
def timer_handler():
global ticks, seconds, milliseconds, timer_running, _dbg_once
# [DBG] 一次性打印:'H' 出现说明定时 ISR 被调用(用后移除)
if _dbg_once == 0:
_dbg_once = 1
serial.puts("H")
if not timer_running:
pic.eoi(0)
apic.eoi()
return
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
ticks = ticks + 1
milliseconds = milliseconds + MILLISECONDS_PER_TICK
if milliseconds >= 1000:
seconds = seconds + 1
milliseconds = milliseconds - 1000
c.Asm("mfence", op=[t.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
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
timer_running = True
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
def timer_stop():
global timer_running
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
timer_running = False
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
def timer_reset():
global ticks, seconds, milliseconds
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
ticks = 0
seconds = 0
milliseconds = 0
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
def timer_get_ticks() -> uint64:
current_ticks: uint64
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
current_ticks = ticks
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
return current_ticks
def timer_get_seconds() -> uint32:
current_seconds: uint32
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
current_seconds = seconds
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
return current_seconds
def timer_get_milliseconds() -> uint32:
current_milliseconds: uint32
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
current_milliseconds = milliseconds
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
return current_milliseconds
def timer_get_time(out_seconds: uint32 | t.CPtr, out_milliseconds: uint32 | t.CPtr):
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
if out_seconds:
c.Set(c.Deref(out_seconds), seconds)
if out_milliseconds:
c.Set(c.Deref(out_milliseconds), milliseconds)
c.Asm("mfence", op=[t.ASM_DESCR.CLOBBER_MEMORY])
def timer_msleep(ms: uint32):
target: uint64 = ticks + (ms + MILLISECONDS_PER_TICK - 1) / MILLISECONDS_PER_TICK
_spin: uint64 = 0
while ticks < target:
# [DBG] 自旋计数:每 1M 次迭代打印 s——hlt 能唤醒说明中断触发
# (用后移除)
_spin += 1
if (_spin & 0xFFFFF) == 0:
serial.puts("s")
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()