QEMU,Limine: IA32_APIC_BASE MSR is empty

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
mleks
Posts: 8
Joined: Fri May 31, 2024 2:05 am

QEMU,Limine: IA32_APIC_BASE MSR is empty

Post by mleks »

Hello,

I am using the Limine bootloader (versions 7.x and 8.x) and QEMU v8.2.2 with the arguments `-M q35, -m 2G`. Regardless of whether I use KVM or not, my MSR (0x1B) reads as follows:

Code: Select all

[info] (apic) Checking if LAPIC is supported: true
[info] (apic) Before updating APIC 0x1B@MSR: 0b0000000000000000000000000000000000000000000000000000000000000000
The QEMU monitor output for `info lapic` is:

Code: Select all

QEMU 8.2.2 monitor - type 'help' for more information
(qemu) info lapic
dumping local APIC state for CPU 0

LVT0     0x00008700 active-hi level                             ExtINT (vec 0)
LVT1     0x00008400 active-hi level                             NMI
LVTPC    0x00010000 active-hi edge  masked                      Fixed  (vec 0)
LVTERR   0x00010000 active-hi edge  masked                      Fixed  (vec 0)
LVTTHMR  0x00010000 active-hi edge  masked                      Fixed  (vec 0)
LVTT     0x00010000 active-hi edge  masked         one-shot     Fixed  (vec 0)
Timer    DCR=0x0 (divide by 2) initial_count = 0 current_count = 0
SPIV     0x000001ff APIC enabled, focus=off, spurious vec 255
ICR      0x000c4610 physical edge assert all
ICR2     0x00000000
ESR      0x00000000
ISR      (none)
IRR      (none)

APR 0x00 TPR 0x00 DFR 0x0f LDR 0x00 PPR 0x00
When I try to set it manually, for example:

Code: Select all

const apic_default_base_phys = 0xFEE0_0000;
apic_base_msr |= apic_default_base_phys | 1 << 11 | 1 << 8;
log.info("Setting APIC MSR to 0x{x}", .{apic_base_msr});
cpu.wrmsr(apic_base_msr_addr, apic_base_msr);
and read the MSR again, I still get only zeros. When I try to allocate memory for the whole page and set apic base address to its frame (which should work on Xeons at least), I can set the MSR, but the registers are still zeros.

Any ideas?
mleks
Posts: 8
Joined: Fri May 31, 2024 2:05 am

Re: QEMU,Limine: IA32_APIC_BASE MSR is empty

Post by mleks »

It was my fault in my inline assembly:

Code: Select all

 
pub inline fn rdmsr(msr: u32) usize {
    var low: u32 = undefined;
    var high: u32 = undefined;
    asm volatile ("rdmsr"
        : [low] "={eax}" (low),
          [high] "={edx}" (high),
        : [msr] "N{ecx}" (msr),
        : "ecx", "eax", "edx"
    );
    return (@as(u64, high) << 32) | low;
}

->

Code: Select all

 
pub inline fn rdmsr(msr: u32) usize {
    var low: u32 = undefined;
    var high: u32 = undefined;
    asm volatile ("rdmsr"
        : [low] "={eax}" (low),
          [high] "={edx}" (high),
        : [msr] "{ecx}" (msr),
        : "ecx", "eax", "edx"
    );
    return (@as(u64, high) << 32) | low;
}


this `N` took my whole day ;)
Post Reply