|
@@ -291,6 +291,57 @@ const struct pv_cpu_asm_switch xen_cpu_asm_switch = {
|
|
|
.leave_kernel = (unsigned long)&xen_leave_kernel,
|
|
|
};
|
|
|
|
|
|
+/***************************************************************************
|
|
|
+ * pv_iosapic_ops
|
|
|
+ * iosapic read/write hooks.
|
|
|
+ */
|
|
|
+static void
|
|
|
+xen_pcat_compat_init(void)
|
|
|
+{
|
|
|
+ /* nothing */
|
|
|
+}
|
|
|
+
|
|
|
+static struct irq_chip*
|
|
|
+xen_iosapic_get_irq_chip(unsigned long trigger)
|
|
|
+{
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
+static unsigned int
|
|
|
+xen_iosapic_read(char __iomem *iosapic, unsigned int reg)
|
|
|
+{
|
|
|
+ struct physdev_apic apic_op;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ apic_op.apic_physbase = (unsigned long)iosapic -
|
|
|
+ __IA64_UNCACHED_OFFSET;
|
|
|
+ apic_op.reg = reg;
|
|
|
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ return apic_op.value;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
|
|
|
+{
|
|
|
+ struct physdev_apic apic_op;
|
|
|
+
|
|
|
+ apic_op.apic_physbase = (unsigned long)iosapic -
|
|
|
+ __IA64_UNCACHED_OFFSET;
|
|
|
+ apic_op.reg = reg;
|
|
|
+ apic_op.value = val;
|
|
|
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
|
|
|
+}
|
|
|
+
|
|
|
+static const struct pv_iosapic_ops xen_iosapic_ops __initdata = {
|
|
|
+ .pcat_compat_init = xen_pcat_compat_init,
|
|
|
+ .__get_irq_chip = xen_iosapic_get_irq_chip,
|
|
|
+
|
|
|
+ .__read = xen_iosapic_read,
|
|
|
+ .__write = xen_iosapic_write,
|
|
|
+};
|
|
|
+
|
|
|
/***************************************************************************
|
|
|
* pv_ops initialization
|
|
|
*/
|
|
@@ -302,6 +353,7 @@ xen_setup_pv_ops(void)
|
|
|
pv_info = xen_info;
|
|
|
pv_init_ops = xen_init_ops;
|
|
|
pv_cpu_ops = xen_cpu_ops;
|
|
|
+ pv_iosapic_ops = xen_iosapic_ops;
|
|
|
|
|
|
paravirt_cpu_asm_init(&xen_cpu_asm_switch);
|
|
|
}
|