diff options
author | Avi Kivity <avi@redhat.com> | 2009-09-16 12:25:53 +0300 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2009-09-16 16:00:47 -0300 |
commit | 52358c14c888722c623f1fcfbea70c2e65cd87f6 (patch) | |
tree | bcd47fbbf96c2b67743a02f03daa8a987c2542ea /kvm | |
parent | test: use new apic_icr_write() to issue IPI (diff) | |
download | qemu-kvm-52358c14c888722c623f1fcfbea70c2e65cd87f6.tar.gz qemu-kvm-52358c14c888722c623f1fcfbea70c2e65cd87f6.tar.bz2 qemu-kvm-52358c14c888722c623f1fcfbea70c2e65cd87f6.zip |
test: add x2apic test
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'kvm')
-rw-r--r-- | kvm/user/test/x86/apic.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/kvm/user/test/x86/apic.c b/kvm/user/test/x86/apic.c index fdeec4c5e..504def2ad 100644 --- a/kvm/user/test/x86/apic.c +++ b/kvm/user/test/x86/apic.c @@ -9,6 +9,7 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned u32; typedef unsigned long ulong; +typedef unsigned long long u64; typedef struct { unsigned short offset0; @@ -147,6 +148,31 @@ static const struct apic_ops xapic_ops = { static const struct apic_ops *apic_ops = &xapic_ops; +static u32 x2apic_read(unsigned reg) +{ + unsigned a, d; + + asm volatile ("rdmsr" : "=a"(a), "=d"(d) : "c"(APIC_BASE_MSR + reg/16)); + return a | (u64)d << 32; +} + +static void x2apic_write(unsigned reg, u32 val) +{ + asm volatile ("wrmsr" : : "a"(val), "d"(0), "c"(APIC_BASE_MSR + reg/16)); +} + +static void x2apic_icr_write(u32 val, u32 dest) +{ + asm volatile ("wrmsr" : : "a"(val), "d"(dest), + "c"(APIC_BASE_MSR + APIC_ICR/16)); +} + +static const struct apic_ops x2apic_ops = { + .reg_read = x2apic_read, + .reg_write = x2apic_write, + .icr_write = x2apic_icr_write, +}; + static u32 apic_read(unsigned reg) { return apic_ops->reg_read(reg); @@ -171,6 +197,25 @@ static void test_lapic_existence(void) report("apic existence", (u16)lvr == 0x14); } +#define MSR_APIC_BASE 0x0000001b + +static void enable_x2apic(void) +{ + unsigned a, b, c, d; + + asm ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(1)); + + if (c & (1 << 21)) { + asm ("rdmsr" : "=a"(a), "=d"(d) : "c"(MSR_APIC_BASE)); + a |= 1 << 10; + asm ("wrmsr" : : "a"(a), "d"(d), "c"(MSR_APIC_BASE)); + apic_ops = &x2apic_ops; + printf("x2apic enabled\n"); + } else { + printf("x2apic not detected\n"); + } +} + static u16 read_cs(void) { u16 v; @@ -388,6 +433,7 @@ int main() mask_pic_interrupts(); enable_apic(); + enable_x2apic(); init_idt(); test_self_ipi(); |