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@xxxxxxxxxx> > --- > 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@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html