summaryrefslogtreecommitdiffstats
path: root/sys/x86/include/apicvar.h
diff options
context:
space:
mode:
authorroyger <royger@FreeBSD.org>2014-06-16 08:43:03 +0000
committerroyger <royger@FreeBSD.org>2014-06-16 08:43:03 +0000
commit7c7f3fb2d000c0584e6a496d374e00f708ed9844 (patch)
treebad88a87c2bb4d2feaa6b0de59821f5c2a2f1465 /sys/x86/include/apicvar.h
parent6a8d0be3956efd157e8cae29391bc54ab94faaec (diff)
downloadFreeBSD-src-7c7f3fb2d000c0584e6a496d374e00f708ed9844.zip
FreeBSD-src-7c7f3fb2d000c0584e6a496d374e00f708ed9844.tar.gz
amd64/i386: introduce APIC hooks for different APIC implementations.
This is needed for Xen PV(H) guests, since there's no hardware lapic available on this kind of domains. This commit should not change functionality. Sponsored by: Citrix Systems R&D Reviewed by: jhb Approved by: gibbs amd64/include/cpu.h: amd64/amd64/mp_machdep.c: i386/include/cpu.h: i386/i386/mp_machdep.c: - Remove lapic_ipi_vectored hook from cpu_ops, since it's now implemented in the lapic hooks. amd64/amd64/mp_machdep.c: i386/i386/mp_machdep.c: - Use lapic_ipi_vectored directly, since it's now an inline function that will call the appropiate hook. x86/x86/local_apic.c: - Prefix bare metal public lapic functions with native_ and mark them as static. - Define default implementation of apic_ops. x86/include/apicvar.h: - Declare the apic_ops structure and create inline functions to access the hooks, so the change is transparent to existing users of the lapic_ functions. x86/xen/hvm.c: - Switch to use the new apic_ops.
Diffstat (limited to 'sys/x86/include/apicvar.h')
-rw-r--r--sys/x86/include/apicvar.h261
1 files changed, 230 insertions, 31 deletions
diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h
index 62e3e91..35603e8 100644
--- a/sys/x86/include/apicvar.h
+++ b/sys/x86/include/apicvar.h
@@ -168,15 +168,7 @@ inthand_t
extern vm_paddr_t lapic_paddr;
extern int apic_cpuids[];
-u_int apic_alloc_vector(u_int apic_id, u_int irq);
-u_int apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count,
- u_int align);
-void apic_disable_vector(u_int apic_id, u_int vector);
-void apic_enable_vector(u_int apic_id, u_int vector);
-void apic_free_vector(u_int apic_id, u_int vector, u_int irq);
-u_int apic_idt_to_irq(u_int apic_id, u_int vector);
void apic_register_enumerator(struct apic_enumerator *enumerator);
-u_int apic_cpuid(u_int apic_id);
void *ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase);
int ioapic_disable_pin(void *cookie, u_int pin);
int ioapic_get_vector(void *cookie, u_int pin);
@@ -189,33 +181,240 @@ int ioapic_set_polarity(void *cookie, u_int pin, enum intr_polarity pol);
int ioapic_set_triggermode(void *cookie, u_int pin,
enum intr_trigger trigger);
int ioapic_set_smi(void *cookie, u_int pin);
-void lapic_create(u_int apic_id, int boot_cpu);
-void lapic_disable(void);
-void lapic_disable_pmc(void);
-void lapic_dump(const char *str);
-void lapic_enable_cmc(void);
-int lapic_enable_pmc(void);
-void lapic_eoi(void);
-int lapic_id(void);
-void lapic_init(vm_paddr_t addr);
-int lapic_intr_pending(u_int vector);
-void lapic_ipi_raw(register_t icrlo, u_int dest);
-void lapic_ipi_vectored(u_int vector, int dest);
-int lapic_ipi_wait(int delay);
+
+/*
+ * Struct containing pointers to APIC functions whose
+ * implementation is run time selectable.
+ */
+struct apic_ops {
+ void (*create)(u_int, int);
+ void (*init)(vm_paddr_t);
+ void (*setup)(int);
+ void (*dump)(const char *);
+ void (*disable)(void);
+ void (*eoi)(void);
+ int (*id)(void);
+ int (*intr_pending)(u_int);
+ void (*set_logical_id)(u_int, u_int, u_int);
+ u_int (*cpuid)(u_int);
+
+ /* Vectors */
+ u_int (*alloc_vector)(u_int, u_int);
+ u_int (*alloc_vectors)(u_int, u_int *, u_int, u_int);
+ void (*enable_vector)(u_int, u_int);
+ void (*disable_vector)(u_int, u_int);
+ void (*free_vector)(u_int, u_int, u_int);
+
+
+ /* PMC */
+ int (*enable_pmc)(void);
+ void (*disable_pmc)(void);
+ void (*reenable_pmc)(void);
+
+ /* CMC */
+ void (*enable_cmc)(void);
+
+ /* IPI */
+ void (*ipi_raw)(register_t, u_int);
+ void (*ipi_vectored)(u_int, int);
+ int (*ipi_wait)(int);
+
+ /* LVT */
+ int (*set_lvt_mask)(u_int, u_int, u_char);
+ int (*set_lvt_mode)(u_int, u_int, u_int32_t);
+ int (*set_lvt_polarity)(u_int, u_int, enum intr_polarity);
+ int (*set_lvt_triggermode)(u_int, u_int, enum intr_trigger);
+};
+
+extern struct apic_ops apic_ops;
+
+static inline void
+lapic_create(u_int apic_id, int boot_cpu)
+{
+
+ apic_ops.create(apic_id, boot_cpu);
+}
+
+static inline void
+lapic_init(vm_paddr_t addr)
+{
+
+ apic_ops.init(addr);
+}
+
+static inline void
+lapic_setup(int boot)
+{
+
+ apic_ops.setup(boot);
+}
+
+static inline void
+lapic_dump(const char *str)
+{
+
+ apic_ops.dump(str);
+}
+
+static inline void
+lapic_disable(void)
+{
+
+ apic_ops.disable();
+}
+
+static inline void
+lapic_eoi(void)
+{
+
+ apic_ops.eoi();
+}
+
+static inline int
+lapic_id(void)
+{
+
+ return (apic_ops.id());
+}
+
+static inline int
+lapic_intr_pending(u_int vector)
+{
+
+ return (apic_ops.intr_pending(vector));
+}
+
+/* XXX: UNUSED */
+static inline void
+lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id)
+{
+
+ apic_ops.set_logical_id(apic_id, cluster, cluster_id);
+}
+
+static inline u_int
+apic_cpuid(u_int apic_id)
+{
+
+ return (apic_ops.cpuid(apic_id));
+}
+
+static inline u_int
+apic_alloc_vector(u_int apic_id, u_int irq)
+{
+
+ return (apic_ops.alloc_vector(apic_id, irq));
+}
+
+static inline u_int
+apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
+{
+
+ return (apic_ops.alloc_vectors(apic_id, irqs, count, align));
+}
+
+static inline void
+apic_enable_vector(u_int apic_id, u_int vector)
+{
+
+ apic_ops.enable_vector(apic_id, vector);
+}
+
+static inline void
+apic_disable_vector(u_int apic_id, u_int vector)
+{
+
+ apic_ops.disable_vector(apic_id, vector);
+}
+
+static inline void
+apic_free_vector(u_int apic_id, u_int vector, u_int irq)
+{
+
+ apic_ops.free_vector(apic_id, vector, irq);
+}
+
+static inline int
+lapic_enable_pmc(void)
+{
+
+ return (apic_ops.enable_pmc());
+}
+
+static inline void
+lapic_disable_pmc(void)
+{
+
+ apic_ops.disable_pmc();
+}
+
+static inline void
+lapic_reenable_pmc(void)
+{
+
+ apic_ops.reenable_pmc();
+}
+
+static inline void
+lapic_enable_cmc(void)
+{
+
+ apic_ops.enable_cmc();
+}
+
+static inline void
+lapic_ipi_raw(register_t icrlo, u_int dest)
+{
+
+ apic_ops.ipi_raw(icrlo, dest);
+}
+
+static inline void
+lapic_ipi_vectored(u_int vector, int dest)
+{
+
+ apic_ops.ipi_vectored(vector, dest);
+}
+
+static inline int
+lapic_ipi_wait(int delay)
+{
+
+ return (apic_ops.ipi_wait(delay));
+}
+
+static inline int
+lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked)
+{
+
+ return (apic_ops.set_lvt_mask(apic_id, lvt, masked));
+}
+
+static inline int
+lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode)
+{
+
+ return (apic_ops.set_lvt_mode(apic_id, lvt, mode));
+}
+
+static inline int
+lapic_set_lvt_polarity(u_int apic_id, u_int lvt, enum intr_polarity pol)
+{
+
+ return (apic_ops.set_lvt_polarity(apic_id, lvt, pol));
+}
+
+static inline int
+lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger)
+{
+
+ return (apic_ops.set_lvt_triggermode(apic_id, lvt, trigger));
+}
+
void lapic_handle_cmc(void);
void lapic_handle_error(void);
void lapic_handle_intr(int vector, struct trapframe *frame);
void lapic_handle_timer(struct trapframe *frame);
-void lapic_reenable_pmc(void);
-void lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id);
-int lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked);
-int lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode);
-int lapic_set_lvt_polarity(u_int apic_id, u_int lvt,
- enum intr_polarity pol);
-int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
- enum intr_trigger trigger);
-void lapic_set_tpr(u_int vector);
-void lapic_setup(int boot);
void xen_intr_handle_upcall(struct trapframe *frame);
#endif /* !LOCORE */
OpenPOWER on IntegriCloud