summaryrefslogtreecommitdiff
path: root/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-09-16 12:25:58 +0300
committerMarcelo Tosatti <mtosatti@redhat.com>2009-09-16 16:00:49 -0300
commitf2368792af712e95ad1787a1d0279d234d485bf8 (patch)
tree48f4d6fc42b5f2acbe2e148eeb8d033f52f8dd13 /kvm
parenttest: apic: use 1:1 mapping for apic (diff)
downloadqemu-kvm-f2368792af712e95ad1787a1d0279d234d485bf8.tar.gz
qemu-kvm-f2368792af712e95ad1787a1d0279d234d485bf8.tar.bz2
qemu-kvm-f2368792af712e95ad1787a1d0279d234d485bf8.zip
test: Move apic functions to libcflat
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/config-x86-common.mak1
-rw-r--r--kvm/user/test/lib/x86/apic-defs.h (renamed from kvm/user/test/x86/apic.h)0
-rw-r--r--kvm/user/test/lib/x86/apic.c131
-rw-r--r--kvm/user/test/lib/x86/apic.h33
-rw-r--r--kvm/user/test/x86/apic.c130
-rw-r--r--kvm/user/test/x86/cstart64.S2
6 files changed, 169 insertions, 128 deletions
diff --git a/kvm/user/config-x86-common.mak b/kvm/user/config-x86-common.mak
index 22a18b223..de9e9e8a6 100644
--- a/kvm/user/config-x86-common.mak
+++ b/kvm/user/config-x86-common.mak
@@ -12,6 +12,7 @@ cflatobjs += \
test/lib/x86/smp.o
cflatobjs += test/lib/x86/fwcfg.o
+cflatobjs += test/lib/x86/apic.o
$(libcflat): LDFLAGS += -nostdlib
$(libcflat): CFLAGS += -ffreestanding -I test/lib
diff --git a/kvm/user/test/x86/apic.h b/kvm/user/test/lib/x86/apic-defs.h
index c061e3d4a..c061e3d4a 100644
--- a/kvm/user/test/x86/apic.h
+++ b/kvm/user/test/lib/x86/apic-defs.h
diff --git a/kvm/user/test/lib/x86/apic.c b/kvm/user/test/lib/x86/apic.c
new file mode 100644
index 000000000..25517ef98
--- /dev/null
+++ b/kvm/user/test/lib/x86/apic.c
@@ -0,0 +1,131 @@
+#include "libcflat.h"
+#include "apic.h"
+
+static void *g_apic = (void *)0xfee00000;
+static void *g_ioapic = (void *)0xfec00000;
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned u32;
+typedef unsigned long ulong;
+typedef unsigned long long u64;
+
+struct apic_ops {
+ u32 (*reg_read)(unsigned reg);
+ void (*reg_write)(unsigned reg, u32 val);
+ void (*icr_write)(u32 val, u32 dest);
+};
+
+static void outb(unsigned char data, unsigned short port)
+{
+ asm volatile ("out %0, %1" : : "a"(data), "d"(port));
+}
+
+static u32 xapic_read(unsigned reg)
+{
+ return *(volatile u32 *)(g_apic + reg);
+}
+
+static void xapic_write(unsigned reg, u32 val)
+{
+ *(volatile u32 *)(g_apic + reg) = val;
+}
+
+static void xapic_icr_write(u32 val, u32 dest)
+{
+ while (xapic_read(APIC_ICR) & APIC_ICR_BUSY)
+ ;
+ xapic_write(APIC_ICR2, dest << 24);
+ xapic_write(APIC_ICR, val);
+}
+
+static const struct apic_ops xapic_ops = {
+ .reg_read = xapic_read,
+ .reg_write = xapic_write,
+ .icr_write = xapic_icr_write,
+};
+
+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,
+};
+
+u32 apic_read(unsigned reg)
+{
+ return apic_ops->reg_read(reg);
+}
+
+void apic_write(unsigned reg, u32 val)
+{
+ apic_ops->reg_write(reg, val);
+}
+
+void apic_icr_write(u32 val, u32 dest)
+{
+ apic_ops->icr_write(val, dest);
+}
+
+#define MSR_APIC_BASE 0x0000001b
+
+int 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;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void ioapic_write_reg(unsigned reg, u32 value)
+{
+ *(volatile u32 *)g_ioapic = reg;
+ *(volatile u32 *)(g_ioapic + 0x10) = value;
+}
+
+void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e)
+{
+ ioapic_write_reg(0x10 + line * 2 + 0, ((u32 *)&e)[0]);
+ ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]);
+}
+
+void enable_apic(void)
+{
+ printf("enabling apic\n");
+ apic_write(0xf0, 0x1ff); /* spurious vector register */
+}
+
+void mask_pic_interrupts(void)
+{
+ outb(0xff, 0x21);
+ outb(0xff, 0xa1);
+}
diff --git a/kvm/user/test/lib/x86/apic.h b/kvm/user/test/lib/x86/apic.h
new file mode 100644
index 000000000..0115ba4b2
--- /dev/null
+++ b/kvm/user/test/lib/x86/apic.h
@@ -0,0 +1,33 @@
+#ifndef CFLAT_APIC_H
+#define CFLAT_APIC_H
+
+#include <stdint.h>
+#include "apic-defs.h"
+
+typedef struct {
+ uint8_t vector;
+ uint8_t delivery_mode:3;
+ uint8_t dest_mode:1;
+ uint8_t delivery_status:1;
+ uint8_t polarity:1;
+ uint8_t remote_irr:1;
+ uint8_t trig_mode:1;
+ uint8_t mask:1;
+ uint8_t reserve:7;
+ uint8_t reserved[4];
+ uint8_t dest_id;
+} ioapic_redir_entry_t;
+
+void mask_pic_interrupts(void);
+
+void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e);
+void ioapic_write_reg(unsigned reg, uint32_t value);
+
+void enable_apic(void);
+uint32_t apic_read(unsigned reg);
+void apic_write(unsigned reg, uint32_t val);
+void apic_icr_write(uint32_t val, uint32_t dest);
+
+int enable_x2apic(void);
+
+#endif
diff --git a/kvm/user/test/x86/apic.c b/kvm/user/test/x86/apic.c
index 63d326d45..1edfba5a4 100644
--- a/kvm/user/test/x86/apic.c
+++ b/kvm/user/test/x86/apic.c
@@ -2,9 +2,6 @@
#include "apic.h"
#include "vm.h"
-static void *g_apic;
-static void *g_ioapic;
-
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned u32;
@@ -103,12 +100,6 @@ static idt_entry_t idt[256];
static int g_fail;
static int g_tests;
-struct apic_ops {
- u32 (*reg_read)(unsigned reg);
- void (*reg_write)(unsigned reg, u32 val);
- void (*icr_write)(u32 val, u32 dest);
-};
-
static void outb(unsigned char data, unsigned short port)
{
asm volatile ("out %0, %1" : : "a"(data), "d"(port));
@@ -122,72 +113,6 @@ static void report(const char *msg, int pass)
++g_fail;
}
-static u32 xapic_read(unsigned reg)
-{
- return *(volatile u32 *)(g_apic + reg);
-}
-
-static void xapic_write(unsigned reg, u32 val)
-{
- *(volatile u32 *)(g_apic + reg) = val;
-}
-
-static void xapic_icr_write(u32 val, u32 dest)
-{
- while (xapic_read(APIC_ICR) & APIC_ICR_BUSY)
- ;
- xapic_write(APIC_ICR2, dest << 24);
- xapic_write(APIC_ICR, val);
-}
-
-static const struct apic_ops xapic_ops = {
- .reg_read = xapic_read,
- .reg_write = xapic_write,
- .icr_write = xapic_icr_write,
-};
-
-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);
-}
-
-static void apic_write(unsigned reg, u32 val)
-{
- apic_ops->reg_write(reg, val);
-}
-
-static void apic_icr_write(u32 val, u32 dest)
-{
- apic_ops->icr_write(val, dest);
-}
-
static void test_lapic_existence(void)
{
u32 lvr;
@@ -199,17 +124,9 @@ static void test_lapic_existence(void)
#define MSR_APIC_BASE 0x0000001b
-static void enable_x2apic(void)
+void test_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;
+ if (enable_x2apic()) {
printf("x2apic enabled\n");
} else {
printf("x2apic not detected\n");
@@ -311,32 +228,6 @@ static void test_self_ipi(void)
report("self ipi", ipi_count == 1);
}
-static void ioapic_write_reg(unsigned reg, u32 value)
-{
- *(volatile u32 *)g_ioapic = reg;
- *(volatile u32 *)(g_ioapic + 0x10) = value;
-}
-
-typedef struct {
- u8 vector;
- u8 delivery_mode:3;
- u8 dest_mode:1;
- u8 delivery_status:1;
- u8 polarity:1;
- u8 remote_irr:1;
- u8 trig_mode:1;
- u8 mask:1;
- u8 reserve:7;
- u8 reserved[4];
- u8 dest_id;
-} ioapic_redir_entry_t;
-
-static void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e)
-{
- ioapic_write_reg(0x10 + line * 2 + 0, ((u32 *)&e)[0]);
- ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]);
-}
-
static void set_ioapic_redir(unsigned line, unsigned vec)
{
ioapic_redir_entry_t e = {
@@ -410,30 +301,15 @@ static void test_ioapic_simultaneous(void)
g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip);
}
-static void enable_apic(void)
-{
- printf("enabling apic\n");
- apic_write(0xf0, 0x1ff); /* spurious vector register */
-}
-
-static void mask_pic_interrupts(void)
-{
- outb(0xff, 0x21);
- outb(0xff, 0xa1);
-}
-
int main()
{
setup_vm();
- g_apic = (void *)0xfee00000;
- g_ioapic = (void *)0xfec00000;
-
test_lapic_existence();
mask_pic_interrupts();
enable_apic();
- enable_x2apic();
+ test_enable_x2apic();
init_idt();
test_self_ipi();
diff --git a/kvm/user/test/x86/cstart64.S b/kvm/user/test/x86/cstart64.S
index 912bcf857..14bb98c97 100644
--- a/kvm/user/test/x86/cstart64.S
+++ b/kvm/user/test/x86/cstart64.S
@@ -1,5 +1,5 @@
-#include "apic.h"
+#include "apic-defs.h"
boot_idt = 0