aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/mpparse.c
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-07-21 15:50:11 +0000
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-07-21 15:50:11 +0000
commit55c771f676873ff66102be3826ed88f53ab57578 (patch)
tree8048471db0f4f844109ad2ad7ff7e3222805ae0e /xen/arch/x86/mpparse.c
parenteadf155ee317140c416c3f7b07fa06f9688dc9fb (diff)
downloadxen-55c771f676873ff66102be3826ed88f53ab57578.tar.gz
xen-55c771f676873ff66102be3826ed88f53ab57578.tar.bz2
xen-55c771f676873ff66102be3826ed88f53ab57578.zip
Here is a patch to enable Xen to run on a Unisys ES7000 x86_64 system.
Signed-off-by: Aravindh Puthiyaparambil <aravindh.puthiyaparambil@unisys.com>
Diffstat (limited to 'xen/arch/x86/mpparse.c')
-rw-r--r--xen/arch/x86/mpparse.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index 234b14106f..268c9cdf71 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -913,7 +913,10 @@ void __init mp_register_ioapic (
mp_ioapics[idx].mpc_apicaddr = address;
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
- mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
+ mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+ else
+ mp_ioapics[idx].mpc_apicid = id;
mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
/*
@@ -995,9 +998,9 @@ void __init mp_config_acpi_legacy_irqs (void)
Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
/*
- * ES7000 has no legacy identity mappings
+ * Older generations of ES7000 have no legacy identity mappings
*/
- if (es7000_plat)
+ if (es7000_plat == 1)
return;
/*
@@ -1053,11 +1056,20 @@ void __init mp_config_acpi_legacy_irqs (void)
}
}
+#define MAX_GSI_NUM 4096
+
int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
{
int ioapic = -1;
int ioapic_pin = 0;
int idx, bit = 0;
+ static int pci_irq = 16;
+ /*
+ * Mapping between Global System Interrups, which
+ * represent all possible interrupts, and IRQs
+ * assigned to actual devices.
+ */
+ static int gsi_to_irq[MAX_GSI_NUM];
#ifdef CONFIG_ACPI_BUS
/* Don't set up the ACPI SCI because it's already set up */
@@ -1092,11 +1104,26 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
- return gsi;
+ return gsi_to_irq[gsi];
}
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
+ if (edge_level) {
+ /*
+ * For PCI devices assign IRQs in order, avoiding gaps
+ * due to unused I/O APIC pins.
+ */
+ int irq = gsi;
+ if (gsi < MAX_GSI_NUM) {
+ gsi = pci_irq++;
+ gsi_to_irq[irq] = gsi;
+ } else {
+ printk(KERN_ERR "GSI %u is too high\n", gsi);
+ return gsi;
+ }
+ }
+
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);