From: Andrew Cooper Date: Fri, 13 Apr 2018 13:41:21 +0000 (+0000) Subject: Introduce some basic IO-APIC infrastructure X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=69bfb2687dc1b52edcb61948f4cff70c2ddb2f02;p=xtf.git Introduce some basic IO-APIC infrastructure Replace some opencoded IOAPIC_DEFAULT_BASE constants. Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/include/arch/io-apic.h b/arch/x86/include/arch/io-apic.h new file mode 100644 index 0000000..ec88865 --- /dev/null +++ b/arch/x86/include/arch/io-apic.h @@ -0,0 +1,67 @@ +/** + * @file arch/x86/include/arch/io-apic.h + * + * %x86 IO-APIC register definitions and utility functions. + * + * The IO-APIC MMIO window is expected to be in its default location for the + * benefit of unpaged environments. + */ + +#ifndef XTF_X86_IO_APIC_H +#define XTF_X86_IO_APIC_H + +#include +#include + +/* MMIO window registers. */ +#define IOAPIC_REGSEL 0x00 +#define IOAPIC_IOWIN 0x10 + +/* IO-APIC registers. */ +#define IOAPIC_ID 0x0 + + +#define IOAPIC_DEFAULT_BASE 0xfec00000 + +/** + * Discover and initialise the IO-APIC. May fail if there is no IO-APIC. + */ +int ioapic_init(void); + +static inline uint32_t ioapic_read32(unsigned int reg) +{ + *(volatile uint32_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_REGSEL) = reg; + + return *(volatile uint32_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_IOWIN); +} + +static inline uint64_t ioapic_read64(unsigned int reg) +{ + *(volatile uint64_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_REGSEL) = reg; + + return *(volatile uint64_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_IOWIN); +} + +static inline void ioapic_write32(unsigned int reg, uint32_t val) +{ + *(volatile uint32_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_REGSEL) = reg; + *(volatile uint32_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_IOWIN) = val; +} + +static inline void ioapic_write64(unsigned int reg, uint64_t val) +{ + *(volatile uint64_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_REGSEL) = reg; + *(volatile uint64_t *)_p(IOAPIC_DEFAULT_BASE + IOAPIC_IOWIN) = val; +} + +#endif /* !XTF_X86_IO_APIC_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/arch/x86/include/arch/xtf.h b/arch/x86/include/arch/xtf.h index deaed17..3609d5d 100644 --- a/arch/x86/include/arch/xtf.h +++ b/arch/x86/include/arch/xtf.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/io-apic.c b/arch/x86/io-apic.c new file mode 100644 index 0000000..05aea34 --- /dev/null +++ b/arch/x86/io-apic.c @@ -0,0 +1,32 @@ +/** + * @file arch/x86/io-apic.c + * + * Basic x86 IO-APIC driver. + */ + +#include + +#include + +#include + +int ioapic_init(void) +{ + uint32_t id = ioapic_read32(IOAPIC_ID); + + /* Bare MMIO? */ + if ( id == ~0u ) + return -ENODEV; + + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/build/files.mk b/build/files.mk index 3000239..dfa27e4 100644 --- a/build/files.mk +++ b/build/files.mk @@ -32,6 +32,7 @@ obj-hvm += $(ROOT)/arch/x86/apic.o obj-hvm += $(ROOT)/arch/x86/hpet.o obj-hvm += $(ROOT)/arch/x86/hvm/pagetables.o obj-hvm += $(ROOT)/arch/x86/hvm/traps.o +obj-hvm += $(ROOT)/arch/x86/io-apic.o # Arguably common objects, but PV guests will have no interest in them. obj-hvm += $(ROOT)/arch/x86/vmx.o diff --git a/tests/selftest/main.c b/tests/selftest/main.c index 51196b4..4309755 100644 --- a/tests/selftest/main.c +++ b/tests/selftest/main.c @@ -326,6 +326,10 @@ static void test_driver_init(void) rc = hpet_init(); if ( rc && rc != -ENODEV ) xtf_failure("Fail: hpet_init() returned %d\n", rc); + + rc = ioapic_init(); + if ( rc && rc != -ENODEV ) + xtf_failure("Fail: ioapic_init() returned %d\n", rc); } rc = xenstore_init(); diff --git a/tests/xsa-239/main.c b/tests/xsa-239/main.c index 1035089..79f6810 100644 --- a/tests/xsa-239/main.c +++ b/tests/xsa-239/main.c @@ -21,8 +21,8 @@ const char test_title[] = "XSA-239 PoC"; void test_main(void) { - uint32_t *io_apic_32 = _p(0xfec00000); - uint8_t *io_apic_8 = _p(0xfec00000); + uint32_t *io_apic_32 = _p(IOAPIC_DEFAULT_BASE); + uint8_t *io_apic_8 = _p(IOAPIC_DEFAULT_BASE); unsigned int i; /*