Commit 0f187a08 authored by Steve Rutherford's avatar Steve Rutherford Committed by Paolo Bonzini
Browse files

x86: Split APIC tests into IOAPIC/APIC tests



Split apart the APIC tests into constituent parts (IOAPIC and APIC tests).
Signed-off-by: default avatarSteve Rutherford <srutherford@google.com>
Message-Id: <1431482143-28018-1-git-send-email-srutherford@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 682045d3
......@@ -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
......
......@@ -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
......@@ -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");
......
......@@ -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);
......
......@@ -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();
......
......@@ -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; \
......
#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();
}
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment