From: Steve Rutherford <srutherford@google.com>
To: kvm@vger.kernel.org
Subject: [PATCH 1/2] x86: Split APIC tests into IOAPIC/APIC tests
Date: Tue, 12 May 2015 18:55:42 -0700 [thread overview]
Message-ID: <1431482143-28018-1-git-send-email-srutherford@google.com> (raw)
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
--
2.2.0.rc0.207.ga3a616c
next reply other threads:[~2015-05-13 1:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-13 1:55 Steve Rutherford [this message]
2015-05-13 1:55 ` [PATCH 2/2] x86: extend IOAPIC tests Steve Rutherford
2015-05-13 8:07 ` [PATCH 1/2] x86: Split APIC tests into IOAPIC/APIC tests Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1431482143-28018-1-git-send-email-srutherford@google.com \
--to=srutherford@google.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox