From mboxrd@z Thu Jan 1 00:00:00 1970 From: Roger Pau Monne Subject: [PATCH RFC 02/13] ioapic: introduce hooks for some ioapic ops Date: Tue, 24 Dec 2013 12:20:51 +0100 Message-ID: <1387884062-41154-3-git-send-email-roger.pau__17360.9793106609$1387884246$gmane$org@citrix.com> References: <1387884062-41154-1-git-send-email-roger.pau@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1VvQ4F-0001EO-IQ for xen-devel@lists.xenproject.org; Tue, 24 Dec 2013 11:22:31 +0000 In-Reply-To: <1387884062-41154-1-git-send-email-roger.pau@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: freebsd-xen@freebsd.org, freebsd-current@freebsd.org, xen-devel@lists.xenproject.org, gibbs@freebsd.org, jhb@freebsd.org, kib@freebsd.org, julien.grall@citrix.com Cc: Roger Pau Monne List-Id: xen-devel@lists.xenproject.org Create some hooks for IO APIC operations that will diverge from bare metal when implemented for Xen Dom0. This patch should not introduce any changes in functionality, it's a preparatory patch for the implementation of the Xen IO APIC hooks. --- sys/amd64/include/apicvar.h | 13 ++++++++ sys/i386/include/apicvar.h | 13 ++++++++ sys/x86/include/apicreg.h | 12 ++++++++ sys/x86/x86/io_apic.c | 65 ++++++++++++++++++++++--------------------- 4 files changed, 71 insertions(+), 32 deletions(-) diff --git a/sys/amd64/include/apicvar.h b/sys/amd64/include/apicvar.h index 84e01d4..a48a76b 100644 --- a/sys/amd64/include/apicvar.h +++ b/sys/amd64/include/apicvar.h @@ -161,6 +161,19 @@ struct apic_enumerator { SLIST_ENTRY(apic_enumerator) apic_next; }; +struct ioapic_intsrc { + struct intsrc io_intsrc; + u_int io_irq; + u_int io_intpin:8; + u_int io_vector:8; + u_int io_cpu:8; + u_int io_activehi:1; + u_int io_edgetrigger:1; + u_int io_masked:1; + int io_bus:4; + uint32_t io_lowreg; +}; + inthand_t IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3), IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6), diff --git a/sys/i386/include/apicvar.h b/sys/i386/include/apicvar.h index 24c99f0..c8ee9bc 100644 --- a/sys/i386/include/apicvar.h +++ b/sys/i386/include/apicvar.h @@ -160,6 +160,19 @@ struct apic_enumerator { SLIST_ENTRY(apic_enumerator) apic_next; }; +struct ioapic_intsrc { + struct intsrc io_intsrc; + u_int io_irq; + u_int io_intpin:8; + u_int io_vector:8; + u_int io_cpu:8; + u_int io_activehi:1; + u_int io_edgetrigger:1; + u_int io_masked:1; + int io_bus:4; + uint32_t io_lowreg; +}; + inthand_t IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3), IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6), diff --git a/sys/x86/include/apicreg.h b/sys/x86/include/apicreg.h index 283d50e..4629470 100644 --- a/sys/x86/include/apicreg.h +++ b/sys/x86/include/apicreg.h @@ -204,6 +204,18 @@ struct IOAPIC { typedef struct IOAPIC ioapic_t; +struct ioapic_intsrc; +/* + * Struct containing pointers to IO APIC management functions whose + * implementation is run time selectable. + */ +struct ioapic_ops { + u_int (*read)(volatile ioapic_t *, int); + void (*write)(volatile ioapic_t *, int, u_int); + void (*register_intr)(struct ioapic_intsrc *); +}; +extern struct ioapic_ops ioapic_ops; + #undef PAD4 #undef PAD3 diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c index 6d62b1e..125d06a 100644 --- a/sys/x86/x86/io_apic.c +++ b/sys/x86/x86/io_apic.c @@ -81,19 +81,6 @@ static MALLOC_DEFINE(M_IOAPIC, "io_apic", "I/O APIC structures"); * ftp://download.intel.com/design/chipsets/datashts/29056601.pdf */ -struct ioapic_intsrc { - struct intsrc io_intsrc; - u_int io_irq; - u_int io_intpin:8; - u_int io_vector:8; - u_int io_cpu:8; - u_int io_activehi:1; - u_int io_edgetrigger:1; - u_int io_masked:1; - int io_bus:4; - uint32_t io_lowreg; -}; - struct ioapic { struct pic io_pic; u_int io_id:8; /* logical ID */ @@ -106,8 +93,9 @@ struct ioapic { struct ioapic_intsrc io_pins[0]; }; -static u_int ioapic_read(volatile ioapic_t *apic, int reg); -static void ioapic_write(volatile ioapic_t *apic, int reg, u_int val); +static u_int native_ioapic_read(volatile ioapic_t *apic, int reg); +static void native_ioapic_write(volatile ioapic_t *apic, int reg, u_int val); +static void native_ioapic_register_intr(struct ioapic_intsrc *pin); static const char *ioapic_bus_string(int bus_type); static void ioapic_print_irq(struct ioapic_intsrc *intpin); static void ioapic_enable_source(struct intsrc *isrc); @@ -139,6 +127,13 @@ SYSCTL_INT(_hw_apic, OID_AUTO, enable_extint, CTLFLAG_RDTUN, &enable_extint, 0, "Enable the ExtINT pin in the first I/O APIC"); TUNABLE_INT("hw.apic.enable_extint", &enable_extint); +/* Default ioapic_ops implementation. */ +struct ioapic_ops ioapic_ops = { + .read = native_ioapic_read, + .write = native_ioapic_write, + .register_intr = native_ioapic_register_intr, +}; + static __inline void _ioapic_eoi_source(struct intsrc *isrc) { @@ -146,7 +141,7 @@ _ioapic_eoi_source(struct intsrc *isrc) } static u_int -ioapic_read(volatile ioapic_t *apic, int reg) +native_ioapic_read(volatile ioapic_t *apic, int reg) { mtx_assert(&icu_lock, MA_OWNED); @@ -155,7 +150,7 @@ ioapic_read(volatile ioapic_t *apic, int reg) } static void -ioapic_write(volatile ioapic_t *apic, int reg, u_int val) +native_ioapic_write(volatile ioapic_t *apic, int reg, u_int val) { mtx_assert(&icu_lock, MA_OWNED); @@ -163,6 +158,12 @@ ioapic_write(volatile ioapic_t *apic, int reg, u_int val) apic->iowin = val; } +static void +native_ioapic_register_intr(struct ioapic_intsrc *pin) +{ + intr_register_source(&pin->io_intsrc); +} + static const char * ioapic_bus_string(int bus_type) { @@ -212,7 +213,7 @@ ioapic_enable_source(struct intsrc *isrc) mtx_lock_spin(&icu_lock); if (intpin->io_masked) { flags = intpin->io_lowreg & ~IOART_INTMASK; - ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), + ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), flags); intpin->io_masked = 0; } @@ -229,7 +230,7 @@ ioapic_disable_source(struct intsrc *isrc, int eoi) mtx_lock_spin(&icu_lock); if (!intpin->io_masked && !intpin->io_edgetrigger) { flags = intpin->io_lowreg | IOART_INTMSET; - ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), + ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), flags); intpin->io_masked = 1; } @@ -264,10 +265,10 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin) mtx_assert(&icu_lock, MA_OWNED); if (intpin->io_irq == IRQ_DISABLED || (intpin->io_irq < NUM_IO_INTS && intpin->io_vector == 0)) { - low = ioapic_read(io->io_addr, + low = ioapic_ops.read(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin)); if ((low & IOART_INTMASK) == IOART_INTMCLR) - ioapic_write(io->io_addr, + ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low | IOART_INTMSET); return; @@ -311,12 +312,12 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin) } /* Write the values to the APIC. */ - value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin)); + value = ioapic_ops.read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin)); value &= ~IOART_DEST; value |= high; - ioapic_write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value); + ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin), value); intpin->io_lowreg = low; - ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low); + ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low); } static int @@ -357,7 +358,7 @@ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id) */ mtx_lock_spin(&icu_lock); if (!intpin->io_masked && !intpin->io_edgetrigger) { - ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), + ioapic_ops.write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), intpin->io_lowreg | IOART_INTMSET); mtx_unlock_spin(&icu_lock); DELAY(100); @@ -512,7 +513,7 @@ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase) /* Map the register window so we can access the device. */ apic = pmap_mapdev(addr, IOAPIC_MEM_REGION); mtx_lock_spin(&icu_lock); - value = ioapic_read(apic, IOAPIC_VER); + value = ioapic_ops.read(apic, IOAPIC_VER); mtx_unlock_spin(&icu_lock); /* If it's version register doesn't seem to work, punt. */ @@ -528,9 +529,9 @@ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase) io->io_pic = ioapic_template; mtx_lock_spin(&icu_lock); io->io_id = next_id++; - io->io_apic_id = ioapic_read(apic, IOAPIC_ID) >> APIC_ID_SHIFT; + io->io_apic_id = ioapic_ops.read(apic, IOAPIC_ID) >> APIC_ID_SHIFT; if (apic_id != -1 && io->io_apic_id != apic_id) { - ioapic_write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT); + ioapic_ops.write(apic, IOAPIC_ID, apic_id << APIC_ID_SHIFT); mtx_unlock_spin(&icu_lock); io->io_apic_id = apic_id; printf("ioapic%u: Changing APIC ID to %d\n", io->io_id, @@ -586,8 +587,8 @@ ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase) * be routed to other CPUs later after they are enabled. */ intpin->io_cpu = PCPU_GET(apic_id); - value = ioapic_read(apic, IOAPIC_REDTBL_LO(i)); - ioapic_write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET); + value = ioapic_ops.read(apic, IOAPIC_REDTBL_LO(i)); + ioapic_ops.write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET); } mtx_unlock_spin(&icu_lock); @@ -788,7 +789,7 @@ ioapic_register(void *cookie) io = (struct ioapic *)cookie; apic = io->io_addr; mtx_lock_spin(&icu_lock); - flags = ioapic_read(apic, IOAPIC_VER) & IOART_VER_VERSION; + flags = ioapic_ops.read(apic, IOAPIC_VER) & IOART_VER_VERSION; STAILQ_INSERT_TAIL(&ioapic_list, io, io_next); mtx_unlock_spin(&icu_lock); printf("ioapic%u irqs %u-%u on motherboard\n", @@ -799,7 +800,7 @@ ioapic_register(void *cookie) intr_register_pic(&io->io_pic); for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++) if (pin->io_irq < NUM_IO_INTS) - intr_register_source(&pin->io_intsrc); + ioapic_ops.register_intr(pin); } /* A simple new-bus driver to consume PCI I/O APIC devices. */ -- 1.7.7.5 (Apple Git-26)