- 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 工作区内容
130 lines
4.4 KiB
Plaintext
130 lines
4.4 KiB
Plaintext
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()
|