diff --git a/VKernel/Kernel/drivers/core/cpu/apic.vp b/VKernel/Kernel/drivers/core/cpu/apic.vp index be57b2a..3e872b5 100644 --- a/VKernel/Kernel/drivers/core/cpu/apic.vp +++ b/VKernel/Kernel/drivers/core/cpu/apic.vp @@ -237,8 +237,11 @@ def start_aps(): def early_init(): global _cpu_count, _bsp_lapic_id - features: t.CUInt32T = cpu.detect_features_static() - if features & cpu.CPU_FEATURE_APIC: + # 直接以 IA32_APIC_BASE 的 EN 位(bit 11)判断 APIC 是否可用: + # QEMU/OVMF 必启用,且 msr_read 路径已在前置流程验证可用; + # 比依赖 cpuid 特性位更可靠(避免 cpuid 包装被误判时静默跳过 init)。 + msr_val: t.CUInt64T = cpu.msr_read(IA32_APIC_BASE) + if msr_val & APIC_BASE_MSR_ENABLE: init() _cpu_count = detect_cpu_count() else: @@ -247,5 +250,8 @@ def early_init(): def get_cpu_count() -> t.CUInt32T: return _cpu_count +def get_base() -> t.CUInt64T: + return _lapic_base + def get_lapic_id() -> t.CUInt32T: return get_id() diff --git a/VKernel/Kernel/main.vp b/VKernel/Kernel/main.vp index 42681d7..55da781 100644 --- a/VKernel/Kernel/main.vp +++ b/VKernel/Kernel/main.vp @@ -78,13 +78,19 @@ class ViperKernel: apic.early_init() serial.puts("[main] apic init done\n") - # [DBG] 读回 LAPIC LINT0 与 APIC BASE MSR,验证 EXTINT 配置(用后移除) - _lint0: t.CUInt32T = apic.read(0x350) - _apic_msr: t.CUInt64T = cpu.msr_read(apic.IA32_APIC_BASE) - _abuf: t.CArray[t.CChar, 96] - viperlib.snprintf(c.Addr(_abuf), 96, "[APIC] lint0=0x%x apic_base_msr=0x%lx\n", - _lint0, _apic_msr) - serial.puts(c.Addr(_abuf)) + # [DBG] 综合诊断:判定 LAPIC MMIO 是否真正可访问/可写(用后移除) + _dbg_base: t.CUInt64T = apic.get_base() + _dbg_ver: t.CUInt32T = apic.read(0x030) # LAPIC_VERSION:真 LAPIC 应为 0x50014 + _dbg_svr: t.CUInt32T = apic.read(0x0F0) # LAPIC_SVR:init 已写 0x1FF + apic.write(0x350, 0x700) # 再次写 LINT0,验证写粘性 + _dbg_lint0: t.CUInt32T = apic.read(0x350) + _dbg_feat: t.CUInt32T = cpu.detect_features_static() + _dbg_buf: t.CArray[t.CChar, 160] + viperlib.snprintf(c.Addr(_dbg_buf), 160, + "[DBG] base=0x%lx ver=0x%x svr=0x%x lint0=0x%x feat=0x%x apic=%d\n", + _dbg_base, _dbg_ver, _dbg_svr, _dbg_lint0, _dbg_feat, + 1 if (_dbg_feat & cpu.CPU_FEATURE_APIC) else 0) + serial.puts(c.Addr(_dbg_buf)) asm.sti() serial.puts("[main] sti done\n")