diff mbox

[1/2] x86: Split APIC tests into IOAPIC/APIC tests

Message ID 1431482143-28018-1-git-send-email-srutherford@google.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve Rutherford May 13, 2015, 1:55 a.m. UTC
Split apart the APIC tests into constituent parts (IOAPIC and APIC tests).

Signed-off-by: Steve Rutherford <srutherford@google.com>
---
 config/config-x86-common.mak |  2 +
 config/config-x86_64.mak     |  1 +
 lib/x86/apic.c               | 29 +++++++++++++
 lib/x86/apic.h               |  6 +++
 x86/apic.c                   | 80 -----------------------------------
 x86/eventinj.c               |  5 ---
 x86/ioapic.c                 | 99 ++++++++++++++++++++++++++++++++++++++++++++
 x86/unittests.cfg            |  5 +++
 8 files changed, 142 insertions(+), 85 deletions(-)
 create mode 100644 x86/ioapic.c

Comments

Paolo Bonzini May 13, 2015, 8:07 a.m. UTC | #1
On 13/05/2015 03:55, Steve Rutherford wrote:
> Split apart the APIC tests into constituent parts (IOAPIC and APIC tests).
> 
> Signed-off-by: Steve Rutherford <srutherford@google.com>
> ---
>  config/config-x86-common.mak |  2 +
>  config/config-x86_64.mak     |  1 +
>  lib/x86/apic.c               | 29 +++++++++++++
>  lib/x86/apic.h               |  6 +++
>  x86/apic.c                   | 80 -----------------------------------
>  x86/eventinj.c               |  5 ---
>  x86/ioapic.c                 | 99 ++++++++++++++++++++++++++++++++++++++++++++
>  x86/unittests.cfg            |  5 +++
>  8 files changed, 142 insertions(+), 85 deletions(-)
>  create mode 100644 x86/ioapic.c
> 
> diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
> index 8fc3490..d45c9a8 100644
> --- a/config/config-x86-common.mak
> +++ b/config/config-x86-common.mak
> @@ -69,6 +69,8 @@ $(TEST_DIR)/tsc_adjust.elf: $(cstart.o) $(TEST_DIR)/tsc_adjust.o
>  
>  $(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o
>  
> +$(TEST_DIR)/ioapic.elf: $(cstart.o) $(TEST_DIR)/ioapic.o
> +
>  $(TEST_DIR)/tscdeadline_latency.elf: $(cstart.o) $(TEST_DIR)/tscdeadline_latency.o
>  
>  $(TEST_DIR)/init.elf: $(cstart.o) $(TEST_DIR)/init.o
> diff --git a/config/config-x86_64.mak b/config/config-x86_64.mak
> index d62c1e9..dfdeed6 100644
> --- a/config/config-x86_64.mak
> +++ b/config/config-x86_64.mak
> @@ -10,5 +10,6 @@ tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
>  tests += $(TEST_DIR)/svm.flat
>  tests += $(TEST_DIR)/vmx.flat
>  tests += $(TEST_DIR)/tscdeadline_latency.flat
> +tests += $(TEST_DIR)/ioapic.flat
>  
>  include config/config-x86-common.mak
> diff --git a/lib/x86/apic.c b/lib/x86/apic.c
> index 9c42c4d..80b96d8 100644
> --- a/lib/x86/apic.c
> +++ b/lib/x86/apic.c
> @@ -17,6 +17,11 @@ static void outb(unsigned char data, unsigned short port)
>      asm volatile ("out %0, %1" : : "a"(data), "d"(port));
>  }
>  
> +void eoi(void)
> +{
> +    apic_write(APIC_EOI, 0);
> +}
> +
>  static u32 xapic_read(unsigned reg)
>  {
>      return *(volatile u32 *)(g_apic + reg);
> @@ -117,6 +122,12 @@ int enable_x2apic(void)
>      }
>  }
>  
> +u32 ioapic_read_reg(unsigned reg)
> +{
> +    *(volatile u32 *)g_ioapic = reg;
> +    return *(volatile u32 *)(g_ioapic + 0x10);
> +}
> +
>  void ioapic_write_reg(unsigned reg, u32 value)
>  {
>      *(volatile u32 *)g_ioapic = reg;
> @@ -129,6 +140,24 @@ void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e)
>      ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]);
>  }
>  
> +ioapic_redir_entry_t ioapic_read_redir(unsigned line)
> +{
> +    ioapic_redir_entry_t e;
> +
> +    ((u32 *)&e)[0] = ioapic_read_reg(0x10 + line * 2 + 0);
> +    ((u32 *)&e)[1] = ioapic_read_reg(0x10 + line * 2 + 1);
> +    return e;
> +
> +}
> +
> +void set_mask(unsigned line, int mask)
> +{
> +    ioapic_redir_entry_t e = ioapic_read_redir(line);
> +
> +    e.mask = mask;
> +    ioapic_write_redir(line, e);
> +}
> +
>  void enable_apic(void)
>  {
>      printf("enabling apic\n");
> diff --git a/lib/x86/apic.h b/lib/x86/apic.h
> index e325e9a..216b98d 100644
> --- a/lib/x86/apic.h
> +++ b/lib/x86/apic.h
> @@ -20,8 +20,14 @@ typedef struct {
>  
>  void mask_pic_interrupts(void);
>  
> +void eoi(void);
> +
>  void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e);
>  void ioapic_write_reg(unsigned reg, uint32_t value);
> +ioapic_redir_entry_t ioapic_read_redir(unsigned line);
> +uint32_t ioapic_read_reg(unsigned reg);
> +
> +void set_mask(unsigned line, int mask);
>  
>  void enable_apic(void);
>  uint32_t apic_read(unsigned reg);
> diff --git a/x86/apic.c b/x86/apic.c
> index 365c281..d4eec52 100644
> --- a/x86/apic.c
> +++ b/x86/apic.c
> @@ -140,11 +140,6 @@ static void test_apicbase(void)
>      report_prefix_pop();
>  }
>  
> -static void eoi(void)
> -{
> -    apic_write(APIC_EOI, 0);
> -}
> -
>  static int ipi_count;
>  
>  static void self_ipi_isr(isr_regs_t *regs)
> @@ -165,79 +160,6 @@ static void test_self_ipi(void)
>      report("self ipi", ipi_count == 1);
>  }
>  
> -static void set_ioapic_redir(unsigned line, unsigned vec)
> -{
> -    ioapic_redir_entry_t e = {
> -        .vector = vec,
> -        .delivery_mode = 0,
> -        .trig_mode = 0,
> -    };
> -
> -    ioapic_write_redir(line, e);
> -}
> -
> -static void set_irq_line(unsigned line, int val)
> -{
> -    asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line)));
> -}
> -
> -static void toggle_irq_line(unsigned line)
> -{
> -    set_irq_line(line, 1);
> -    set_irq_line(line, 0);
> -}
> -
> -static int g_isr_77;
> -
> -static void ioapic_isr_77(isr_regs_t *regs)
> -{
> -    ++g_isr_77;
> -    eoi();
> -}
> -
> -static void test_ioapic_intr(void)
> -{
> -    handle_irq(0x77, ioapic_isr_77);
> -    set_ioapic_redir(0x0e, 0x77);
> -    toggle_irq_line(0x0e);
> -    asm volatile ("nop");
> -    report("ioapic interrupt", g_isr_77 == 1);
> -}
> -
> -static int g_78, g_66, g_66_after_78;
> -static ulong g_66_rip, g_78_rip;
> -
> -static void ioapic_isr_78(isr_regs_t *regs)
> -{
> -    ++g_78;
> -    g_78_rip = regs->rip;
> -    eoi();
> -}
> -
> -static void ioapic_isr_66(isr_regs_t *regs)
> -{
> -    ++g_66;
> -    if (g_78)
> -        ++g_66_after_78;
> -    g_66_rip = regs->rip;
> -    eoi();
> -}
> -
> -static void test_ioapic_simultaneous(void)
> -{
> -    handle_irq(0x78, ioapic_isr_78);
> -    handle_irq(0x66, ioapic_isr_66);
> -    set_ioapic_redir(0x0e, 0x78);
> -    set_ioapic_redir(0x0f, 0x66);
> -    irq_disable();
> -    toggle_irq_line(0x0f);
> -    toggle_irq_line(0x0e);
> -    irq_enable();
> -    asm volatile ("nop");
> -    report("ioapic simultaneous interrupt",
> -           g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip);
> -}
> -
>  volatile int nmi_counter_private, nmi_counter, nmi_hlt_counter, sti_loop_active;
>  
>  void sti_nop(char *p)
> @@ -390,8 +312,6 @@ int main()
>  
>      test_self_ipi();
>  
> -    test_ioapic_intr();
> -    test_ioapic_simultaneous();
>      test_sti_nmi();
>      test_multiple_nmi();
>  
> diff --git a/x86/eventinj.c b/x86/eventinj.c
> index 32de6f0..bddedce 100644
> --- a/x86/eventinj.c
> +++ b/x86/eventinj.c
> @@ -32,11 +32,6 @@ void apic_self_nmi(void)
>  	apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
>  }
>  
> -static void eoi(void)
> -{
> -    apic_write(APIC_EOI, 0);
> -}
> -
>  #define flush_phys_addr(__s) outl(0xe4, __s)
>  #define flush_stack() do {						\
>  		int __l;						\
> diff --git a/x86/ioapic.c b/x86/ioapic.c
> new file mode 100644
> index 0000000..2afdaa2
> --- /dev/null
> +++ b/x86/ioapic.c
> @@ -0,0 +1,99 @@
> +#include "libcflat.h"
> +#include "apic.h"
> +#include "vm.h"
> +#include "smp.h"
> +#include "desc.h"
> +#include "isr.h"
> +
> +#define EDGE_TRIGGERED 0
> +#define LEVEL_TRIGGERED 1
> +
> +static void set_ioapic_redir(unsigned line, unsigned vec, unsigned trig_mode)
> +{
> +	ioapic_redir_entry_t e = {
> +		.vector = vec,
> +		.delivery_mode = 0,
> +		.trig_mode = trig_mode,
> +	};
> +
> +	ioapic_write_redir(line, e);
> +}
> +
> +static void set_irq_line(unsigned line, int val)
> +{
> +	asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line)));
> +}
> +
> +static void toggle_irq_line(unsigned line)
> +{
> +	set_irq_line(line, 1);
> +	set_irq_line(line, 0);
> +}
> +
> +static volatile int g_isr_77;
> +
> +static void ioapic_isr_77(isr_regs_t *regs)
> +{
> +	++g_isr_77;
> +	eoi();
> +}
> +
> +static void test_ioapic_intr(void)
> +{
> +	handle_irq(0x77, ioapic_isr_77);
> +	set_ioapic_redir(0x0e, 0x77, EDGE_TRIGGERED);
> +	toggle_irq_line(0x0e);
> +	asm volatile ("nop");
> +	report("ioapic interrupt", g_isr_77 == 1);
> +}
> +
> +static int g_78, g_66, g_66_after_78;
> +static ulong g_66_rip, g_78_rip;
> +
> +static void ioapic_isr_78(isr_regs_t *regs)
> +{
> +	++g_78;
> +	g_78_rip = regs->rip;
> +	eoi();
> +}
> +
> +static void ioapic_isr_66(isr_regs_t *regs)
> +{
> +	++g_66;
> +	if (g_78)
> +		++g_66_after_78;
> +	g_66_rip = regs->rip;
> +	eoi();
> +}
> +
> +static void test_ioapic_simultaneous(void)
> +{
> +	handle_irq(0x78, ioapic_isr_78);
> +	handle_irq(0x66, ioapic_isr_66);
> +	set_ioapic_redir(0x0e, 0x78, EDGE_TRIGGERED);
> +	set_ioapic_redir(0x0f, 0x66, EDGE_TRIGGERED);
> +	irq_disable();
> +	toggle_irq_line(0x0f);
> +	toggle_irq_line(0x0e);
> +	irq_enable();
> +	asm volatile ("nop");
> +	report("ioapic simultaneous interrupt",
> +		g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip);
> +}
> +
> +int main(void)
> +{
> +	setup_vm();
> +	smp_init();
> +	setup_idt();
> +
> +	mask_pic_interrupts();
> +	enable_apic();
> +
> +	irq_enable();
> +
> +	test_ioapic_intr();
> +	test_ioapic_simultaneous();
> +
> +	return report_summary();
> +}
> diff --git a/x86/unittests.cfg b/x86/unittests.cfg
> index badb08a..a38544f 100644
> --- a/x86/unittests.cfg
> +++ b/x86/unittests.cfg
> @@ -12,6 +12,11 @@ smp = 2
>  extra_params = -cpu qemu64,+x2apic,+tsc-deadline
>  arch = x86_64
>  
> +[ioapic]
> +file = ioapic.flat
> +extra_params = -cpu qemu64
> +arch = x86_64
> +
>  [smptest]
>  file = smptest.flat
>  smp = 2
> 

Applying these two, thanks!

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/config/config-x86-common.mak b/config/config-x86-common.mak
index 8fc3490..d45c9a8 100644
--- a/config/config-x86-common.mak
+++ b/config/config-x86-common.mak
@@ -69,6 +69,8 @@  $(TEST_DIR)/tsc_adjust.elf: $(cstart.o) $(TEST_DIR)/tsc_adjust.o
 
 $(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o
 
+$(TEST_DIR)/ioapic.elf: $(cstart.o) $(TEST_DIR)/ioapic.o
+
 $(TEST_DIR)/tscdeadline_latency.elf: $(cstart.o) $(TEST_DIR)/tscdeadline_latency.o
 
 $(TEST_DIR)/init.elf: $(cstart.o) $(TEST_DIR)/init.o
diff --git a/config/config-x86_64.mak b/config/config-x86_64.mak
index d62c1e9..dfdeed6 100644
--- a/config/config-x86_64.mak
+++ b/config/config-x86_64.mak
@@ -10,5 +10,6 @@  tests = $(TEST_DIR)/access.flat $(TEST_DIR)/apic.flat \
 tests += $(TEST_DIR)/svm.flat
 tests += $(TEST_DIR)/vmx.flat
 tests += $(TEST_DIR)/tscdeadline_latency.flat
+tests += $(TEST_DIR)/ioapic.flat
 
 include config/config-x86-common.mak
diff --git a/lib/x86/apic.c b/lib/x86/apic.c
index 9c42c4d..80b96d8 100644
--- a/lib/x86/apic.c
+++ b/lib/x86/apic.c
@@ -17,6 +17,11 @@  static void outb(unsigned char data, unsigned short port)
     asm volatile ("out %0, %1" : : "a"(data), "d"(port));
 }
 
+void eoi(void)
+{
+    apic_write(APIC_EOI, 0);
+}
+
 static u32 xapic_read(unsigned reg)
 {
     return *(volatile u32 *)(g_apic + reg);
@@ -117,6 +122,12 @@  int enable_x2apic(void)
     }
 }
 
+u32 ioapic_read_reg(unsigned reg)
+{
+    *(volatile u32 *)g_ioapic = reg;
+    return *(volatile u32 *)(g_ioapic + 0x10);
+}
+
 void ioapic_write_reg(unsigned reg, u32 value)
 {
     *(volatile u32 *)g_ioapic = reg;
@@ -129,6 +140,24 @@  void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e)
     ioapic_write_reg(0x10 + line * 2 + 1, ((u32 *)&e)[1]);
 }
 
+ioapic_redir_entry_t ioapic_read_redir(unsigned line)
+{
+    ioapic_redir_entry_t e;
+
+    ((u32 *)&e)[0] = ioapic_read_reg(0x10 + line * 2 + 0);
+    ((u32 *)&e)[1] = ioapic_read_reg(0x10 + line * 2 + 1);
+    return e;
+
+}
+
+void set_mask(unsigned line, int mask)
+{
+    ioapic_redir_entry_t e = ioapic_read_redir(line);
+
+    e.mask = mask;
+    ioapic_write_redir(line, e);
+}
+
 void enable_apic(void)
 {
     printf("enabling apic\n");
diff --git a/lib/x86/apic.h b/lib/x86/apic.h
index e325e9a..216b98d 100644
--- a/lib/x86/apic.h
+++ b/lib/x86/apic.h
@@ -20,8 +20,14 @@  typedef struct {
 
 void mask_pic_interrupts(void);
 
+void eoi(void);
+
 void ioapic_write_redir(unsigned line, ioapic_redir_entry_t e);
 void ioapic_write_reg(unsigned reg, uint32_t value);
+ioapic_redir_entry_t ioapic_read_redir(unsigned line);
+uint32_t ioapic_read_reg(unsigned reg);
+
+void set_mask(unsigned line, int mask);
 
 void enable_apic(void);
 uint32_t apic_read(unsigned reg);
diff --git a/x86/apic.c b/x86/apic.c
index 365c281..d4eec52 100644
--- a/x86/apic.c
+++ b/x86/apic.c
@@ -140,11 +140,6 @@  static void test_apicbase(void)
     report_prefix_pop();
 }
 
-static void eoi(void)
-{
-    apic_write(APIC_EOI, 0);
-}
-
 static int ipi_count;
 
 static void self_ipi_isr(isr_regs_t *regs)
@@ -165,79 +160,6 @@  static void test_self_ipi(void)
     report("self ipi", ipi_count == 1);
 }
 
-static void set_ioapic_redir(unsigned line, unsigned vec)
-{
-    ioapic_redir_entry_t e = {
-        .vector = vec,
-        .delivery_mode = 0,
-        .trig_mode = 0,
-    };
-
-    ioapic_write_redir(line, e);
-}
-
-static void set_irq_line(unsigned line, int val)
-{
-    asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line)));
-}
-
-static void toggle_irq_line(unsigned line)
-{
-    set_irq_line(line, 1);
-    set_irq_line(line, 0);
-}
-
-static int g_isr_77;
-
-static void ioapic_isr_77(isr_regs_t *regs)
-{
-    ++g_isr_77;
-    eoi();
-}
-
-static void test_ioapic_intr(void)
-{
-    handle_irq(0x77, ioapic_isr_77);
-    set_ioapic_redir(0x0e, 0x77);
-    toggle_irq_line(0x0e);
-    asm volatile ("nop");
-    report("ioapic interrupt", g_isr_77 == 1);
-}
-
-static int g_78, g_66, g_66_after_78;
-static ulong g_66_rip, g_78_rip;
-
-static void ioapic_isr_78(isr_regs_t *regs)
-{
-    ++g_78;
-    g_78_rip = regs->rip;
-    eoi();
-}
-
-static void ioapic_isr_66(isr_regs_t *regs)
-{
-    ++g_66;
-    if (g_78)
-        ++g_66_after_78;
-    g_66_rip = regs->rip;
-    eoi();
-}
-
-static void test_ioapic_simultaneous(void)
-{
-    handle_irq(0x78, ioapic_isr_78);
-    handle_irq(0x66, ioapic_isr_66);
-    set_ioapic_redir(0x0e, 0x78);
-    set_ioapic_redir(0x0f, 0x66);
-    irq_disable();
-    toggle_irq_line(0x0f);
-    toggle_irq_line(0x0e);
-    irq_enable();
-    asm volatile ("nop");
-    report("ioapic simultaneous interrupt",
-           g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip);
-}
-
 volatile int nmi_counter_private, nmi_counter, nmi_hlt_counter, sti_loop_active;
 
 void sti_nop(char *p)
@@ -390,8 +312,6 @@  int main()
 
     test_self_ipi();
 
-    test_ioapic_intr();
-    test_ioapic_simultaneous();
     test_sti_nmi();
     test_multiple_nmi();
 
diff --git a/x86/eventinj.c b/x86/eventinj.c
index 32de6f0..bddedce 100644
--- a/x86/eventinj.c
+++ b/x86/eventinj.c
@@ -32,11 +32,6 @@  void apic_self_nmi(void)
 	apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
 }
 
-static void eoi(void)
-{
-    apic_write(APIC_EOI, 0);
-}
-
 #define flush_phys_addr(__s) outl(0xe4, __s)
 #define flush_stack() do {						\
 		int __l;						\
diff --git a/x86/ioapic.c b/x86/ioapic.c
new file mode 100644
index 0000000..2afdaa2
--- /dev/null
+++ b/x86/ioapic.c
@@ -0,0 +1,99 @@ 
+#include "libcflat.h"
+#include "apic.h"
+#include "vm.h"
+#include "smp.h"
+#include "desc.h"
+#include "isr.h"
+
+#define EDGE_TRIGGERED 0
+#define LEVEL_TRIGGERED 1
+
+static void set_ioapic_redir(unsigned line, unsigned vec, unsigned trig_mode)
+{
+	ioapic_redir_entry_t e = {
+		.vector = vec,
+		.delivery_mode = 0,
+		.trig_mode = trig_mode,
+	};
+
+	ioapic_write_redir(line, e);
+}
+
+static void set_irq_line(unsigned line, int val)
+{
+	asm volatile("out %0, %1" : : "a"((u8)val), "d"((u16)(0x2000 + line)));
+}
+
+static void toggle_irq_line(unsigned line)
+{
+	set_irq_line(line, 1);
+	set_irq_line(line, 0);
+}
+
+static volatile int g_isr_77;
+
+static void ioapic_isr_77(isr_regs_t *regs)
+{
+	++g_isr_77;
+	eoi();
+}
+
+static void test_ioapic_intr(void)
+{
+	handle_irq(0x77, ioapic_isr_77);
+	set_ioapic_redir(0x0e, 0x77, EDGE_TRIGGERED);
+	toggle_irq_line(0x0e);
+	asm volatile ("nop");
+	report("ioapic interrupt", g_isr_77 == 1);
+}
+
+static int g_78, g_66, g_66_after_78;
+static ulong g_66_rip, g_78_rip;
+
+static void ioapic_isr_78(isr_regs_t *regs)
+{
+	++g_78;
+	g_78_rip = regs->rip;
+	eoi();
+}
+
+static void ioapic_isr_66(isr_regs_t *regs)
+{
+	++g_66;
+	if (g_78)
+		++g_66_after_78;
+	g_66_rip = regs->rip;
+	eoi();
+}
+
+static void test_ioapic_simultaneous(void)
+{
+	handle_irq(0x78, ioapic_isr_78);
+	handle_irq(0x66, ioapic_isr_66);
+	set_ioapic_redir(0x0e, 0x78, EDGE_TRIGGERED);
+	set_ioapic_redir(0x0f, 0x66, EDGE_TRIGGERED);
+	irq_disable();
+	toggle_irq_line(0x0f);
+	toggle_irq_line(0x0e);
+	irq_enable();
+	asm volatile ("nop");
+	report("ioapic simultaneous interrupt",
+		g_66 && g_78 && g_66_after_78 && g_66_rip == g_78_rip);
+}
+
+int main(void)
+{
+	setup_vm();
+	smp_init();
+	setup_idt();
+
+	mask_pic_interrupts();
+	enable_apic();
+
+	irq_enable();
+
+	test_ioapic_intr();
+	test_ioapic_simultaneous();
+
+	return report_summary();
+}
diff --git a/x86/unittests.cfg b/x86/unittests.cfg
index badb08a..a38544f 100644
--- a/x86/unittests.cfg
+++ b/x86/unittests.cfg
@@ -12,6 +12,11 @@  smp = 2
 extra_params = -cpu qemu64,+x2apic,+tsc-deadline
 arch = x86_64
 
+[ioapic]
+file = ioapic.flat
+extra_params = -cpu qemu64
+arch = x86_64
+
 [smptest]
 file = smptest.flat
 smp = 2