aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2009-07-07 23:01:15 -0400
committerLen Brown <len.brown@intel.com>2009-08-28 19:57:27 -0400
commit2a4ab640d3c28c2952967e5f63ea495555bf2a5f (patch)
tree0dc9a613926da186286464379966f5c6afbd865f /arch/x86/kernel/apic
parent326ba5010a5429a5a528b268b36a5900d4ab0eba (diff)
ACPI, x86: expose some IO-APIC routines when CONFIG_ACPI=n
Some IO-APIC routines are ACPI specific now, but need to be exposed when CONFIG_ACPI=n for the benefit of SFI. Remove #ifdef ACPI around these routines: io_apic_get_unique_id(int ioapic, int apic_id); io_apic_get_version(int ioapic); io_apic_get_redir_entries(int ioapic); Move these routines from ACPI-specific boot.c to io_apic.c: uniq_ioapic_id(u8 id) mp_find_ioapic() mp_find_ioapic_pin() mp_register_ioapic() Also, since uniq_ioapic_id() is now no longer static, re-name it to io_apic_unique_id() for consistency with the other public io_apic routines. For simplicity, do not #ifdef the resulting code ACPI || SFI, thought that could be done in the future if it is important to optimize the !ACPI !SFI IO-APIC x86 kernel for size. Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com> Cc: x86@kernel.org
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r--arch/x86/kernel/apic/io_apic.c103
1 files changed, 97 insertions, 6 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index d2ed6c5ddc80..a8c0232b3893 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -85,6 +85,9 @@ int nr_ioapic_registers[MAX_IO_APICS];
85struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; 85struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
86int nr_ioapics; 86int nr_ioapics;
87 87
88/* IO APIC gsi routing info */
89struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
90
88/* MP IRQ source entries */ 91/* MP IRQ source entries */
89struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; 92struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
90 93
@@ -3941,11 +3944,28 @@ int io_apic_set_pci_routing(struct device *dev, int irq,
3941 return __io_apic_set_pci_routing(dev, irq, irq_attr); 3944 return __io_apic_set_pci_routing(dev, irq, irq_attr);
3942} 3945}
3943 3946
3944/* -------------------------------------------------------------------------- 3947u8 __init io_apic_unique_id(u8 id)
3945 ACPI-based IOAPIC Configuration 3948{
3946 -------------------------------------------------------------------------- */ 3949#ifdef CONFIG_X86_32
3950 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
3951 !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
3952 return io_apic_get_unique_id(nr_ioapics, id);
3953 else
3954 return id;
3955#else
3956 int i;
3957 DECLARE_BITMAP(used, 256);
3947 3958
3948#ifdef CONFIG_ACPI 3959 bitmap_zero(used, 256);
3960 for (i = 0; i < nr_ioapics; i++) {
3961 struct mpc_ioapic *ia = &mp_ioapics[i];
3962 __set_bit(ia->apicid, used);
3963 }
3964 if (!test_bit(id, used))
3965 return id;
3966 return find_first_zero_bit(used, 256);
3967#endif
3968}
3949 3969
3950#ifdef CONFIG_X86_32 3970#ifdef CONFIG_X86_32
3951int __init io_apic_get_unique_id(int ioapic, int apic_id) 3971int __init io_apic_get_unique_id(int ioapic, int apic_id)
@@ -4054,8 +4074,6 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
4054 return 0; 4074 return 0;
4055} 4075}
4056 4076
4057#endif /* CONFIG_ACPI */
4058
4059/* 4077/*
4060 * This function currently is only a helper for the i386 smp boot process where 4078 * This function currently is only a helper for the i386 smp boot process where
4061 * we need to reprogram the ioredtbls to cater for the cpus which have come online 4079 * we need to reprogram the ioredtbls to cater for the cpus which have come online
@@ -4201,3 +4219,76 @@ void __init ioapic_insert_resources(void)
4201 r++; 4219 r++;
4202 } 4220 }
4203} 4221}
4222
4223int mp_find_ioapic(int gsi)
4224{
4225 int i = 0;
4226
4227 /* Find the IOAPIC that manages this GSI. */
4228 for (i = 0; i < nr_ioapics; i++) {
4229 if ((gsi >= mp_gsi_routing[i].gsi_base)
4230 && (gsi <= mp_gsi_routing[i].gsi_end))
4231 return i;
4232 }
4233
4234 printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
4235 return -1;
4236}
4237
4238int mp_find_ioapic_pin(int ioapic, int gsi)
4239{
4240 if (WARN_ON(ioapic == -1))
4241 return -1;
4242 if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end))
4243 return -1;
4244
4245 return gsi - mp_gsi_routing[ioapic].gsi_base;
4246}
4247
4248static int bad_ioapic(unsigned long address)
4249{
4250 if (nr_ioapics >= MAX_IO_APICS) {
4251 printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded "
4252 "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics);
4253 return 1;
4254 }
4255 if (!address) {
4256 printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address"
4257 " found in table, skipping!\n");
4258 return 1;
4259 }
4260 return 0;
4261}
4262
4263void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
4264{
4265 int idx = 0;
4266
4267 if (bad_ioapic(address))
4268 return;
4269
4270 idx = nr_ioapics;
4271
4272 mp_ioapics[idx].type = MP_IOAPIC;
4273 mp_ioapics[idx].flags = MPC_APIC_USABLE;
4274 mp_ioapics[idx].apicaddr = address;
4275
4276 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
4277 mp_ioapics[idx].apicid = io_apic_unique_id(id);
4278 mp_ioapics[idx].apicver = io_apic_get_version(idx);
4279
4280 /*
4281 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
4282 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
4283 */
4284 mp_gsi_routing[idx].gsi_base = gsi_base;
4285 mp_gsi_routing[idx].gsi_end = gsi_base +
4286 io_apic_get_redir_entries(idx);
4287
4288 printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
4289 "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
4290 mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
4291 mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end);
4292
4293 nr_ioapics++;
4294}