Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Feng Tang and committed by
Len Brown
2a4ab640 326ba501

+109 -109
+11 -2
arch/x86/include/asm/io_apic.h
··· 150 150 #define io_apic_assign_pci_irqs \ 151 151 (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) 152 152 153 - #ifdef CONFIG_ACPI 153 + extern u8 io_apic_unique_id(u8 id); 154 154 extern int io_apic_get_unique_id(int ioapic, int apic_id); 155 155 extern int io_apic_get_version(int ioapic); 156 156 extern int io_apic_get_redir_entries(int ioapic); 157 - #endif /* CONFIG_ACPI */ 158 157 159 158 struct io_apic_irq_attr; 160 159 extern int io_apic_set_pci_routing(struct device *dev, int irq, ··· 176 177 int polarity, int vector, int pin); 177 178 extern void ioapic_write_entry(int apic, int pin, 178 179 struct IO_APIC_route_entry e); 180 + 181 + struct mp_ioapic_gsi{ 182 + int gsi_base; 183 + int gsi_end; 184 + }; 185 + extern struct mp_ioapic_gsi mp_gsi_routing[]; 186 + int mp_find_ioapic(int gsi); 187 + int mp_find_ioapic_pin(int ioapic, int gsi); 188 + void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); 189 + 179 190 #else /* !CONFIG_X86_IO_APIC */ 180 191 #define io_apic_assign_pci_irqs 0 181 192 static const int timer_through_8259 = 0;
+1 -101
arch/x86/kernel/acpi/boot.c
··· 833 833 extern int es7000_plat; 834 834 #endif 835 835 836 - static struct { 837 - int gsi_base; 838 - int gsi_end; 839 - } mp_ioapic_routing[MAX_IO_APICS]; 840 - 841 - int mp_find_ioapic(int gsi) 842 - { 843 - int i = 0; 844 - 845 - /* Find the IOAPIC that manages this GSI. */ 846 - for (i = 0; i < nr_ioapics; i++) { 847 - if ((gsi >= mp_ioapic_routing[i].gsi_base) 848 - && (gsi <= mp_ioapic_routing[i].gsi_end)) 849 - return i; 850 - } 851 - 852 - printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); 853 - return -1; 854 - } 855 - 856 - int mp_find_ioapic_pin(int ioapic, int gsi) 857 - { 858 - if (WARN_ON(ioapic == -1)) 859 - return -1; 860 - if (WARN_ON(gsi > mp_ioapic_routing[ioapic].gsi_end)) 861 - return -1; 862 - 863 - return gsi - mp_ioapic_routing[ioapic].gsi_base; 864 - } 865 - 866 - static u8 __init uniq_ioapic_id(u8 id) 867 - { 868 - #ifdef CONFIG_X86_32 869 - if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && 870 - !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) 871 - return io_apic_get_unique_id(nr_ioapics, id); 872 - else 873 - return id; 874 - #else 875 - int i; 876 - DECLARE_BITMAP(used, 256); 877 - bitmap_zero(used, 256); 878 - for (i = 0; i < nr_ioapics; i++) { 879 - struct mpc_ioapic *ia = &mp_ioapics[i]; 880 - __set_bit(ia->apicid, used); 881 - } 882 - if (!test_bit(id, used)) 883 - return id; 884 - return find_first_zero_bit(used, 256); 885 - #endif 886 - } 887 - 888 - static int bad_ioapic(unsigned long address) 889 - { 890 - if (nr_ioapics >= MAX_IO_APICS) { 891 - printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " 892 - "(found %d)\n", MAX_IO_APICS, nr_ioapics); 893 - panic("Recompile kernel with bigger MAX_IO_APICS!\n"); 894 - } 895 - if (!address) { 896 - printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" 897 - " found in table, skipping!\n"); 898 - return 1; 899 - } 900 - return 0; 901 - } 902 - 903 - void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) 904 - { 905 - int idx = 0; 906 - 907 - if (bad_ioapic(address)) 908 - return; 909 - 910 - idx = nr_ioapics; 911 - 912 - mp_ioapics[idx].type = MP_IOAPIC; 913 - mp_ioapics[idx].flags = MPC_APIC_USABLE; 914 - mp_ioapics[idx].apicaddr = address; 915 - 916 - set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 917 - mp_ioapics[idx].apicid = uniq_ioapic_id(id); 918 - mp_ioapics[idx].apicver = io_apic_get_version(idx); 919 - 920 - /* 921 - * Build basic GSI lookup table to facilitate gsi->io_apic lookups 922 - * and to prevent reprogramming of IOAPIC pins (PCI GSIs). 923 - */ 924 - mp_ioapic_routing[idx].gsi_base = gsi_base; 925 - mp_ioapic_routing[idx].gsi_end = gsi_base + 926 - io_apic_get_redir_entries(idx); 927 - 928 - printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " 929 - "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, 930 - mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, 931 - mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end); 932 - 933 - nr_ioapics++; 934 - } 935 - 936 836 int __init acpi_probe_gsi(void) 937 837 { 938 838 int idx; ··· 847 947 848 948 max_gsi = 0; 849 949 for (idx = 0; idx < nr_ioapics; idx++) { 850 - gsi = mp_ioapic_routing[idx].gsi_end; 950 + gsi = mp_gsi_routing[idx].gsi_end; 851 951 852 952 if (gsi > max_gsi) 853 953 max_gsi = gsi;
+97 -6
arch/x86/kernel/apic/io_apic.c
··· 85 85 struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; 86 86 int nr_ioapics; 87 87 88 + /* IO APIC gsi routing info */ 89 + struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; 90 + 88 91 /* MP IRQ source entries */ 89 92 struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; 90 93 ··· 3944 3941 return __io_apic_set_pci_routing(dev, irq, irq_attr); 3945 3942 } 3946 3943 3947 - /* -------------------------------------------------------------------------- 3948 - ACPI-based IOAPIC Configuration 3949 - -------------------------------------------------------------------------- */ 3944 + u8 __init io_apic_unique_id(u8 id) 3945 + { 3946 + #ifdef CONFIG_X86_32 3947 + if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && 3948 + !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) 3949 + return io_apic_get_unique_id(nr_ioapics, id); 3950 + else 3951 + return id; 3952 + #else 3953 + int i; 3954 + DECLARE_BITMAP(used, 256); 3950 3955 3951 - #ifdef CONFIG_ACPI 3956 + bitmap_zero(used, 256); 3957 + for (i = 0; i < nr_ioapics; i++) { 3958 + struct mpc_ioapic *ia = &mp_ioapics[i]; 3959 + __set_bit(ia->apicid, used); 3960 + } 3961 + if (!test_bit(id, used)) 3962 + return id; 3963 + return find_first_zero_bit(used, 256); 3964 + #endif 3965 + } 3952 3966 3953 3967 #ifdef CONFIG_X86_32 3954 3968 int __init io_apic_get_unique_id(int ioapic, int apic_id) ··· 4073 4053 *polarity = irq_polarity(i); 4074 4054 return 0; 4075 4055 } 4076 - 4077 - #endif /* CONFIG_ACPI */ 4078 4056 4079 4057 /* 4080 4058 * This function currently is only a helper for the i386 smp boot process where ··· 4218 4200 insert_resource(&iomem_resource, r); 4219 4201 r++; 4220 4202 } 4203 + } 4204 + 4205 + int mp_find_ioapic(int gsi) 4206 + { 4207 + int i = 0; 4208 + 4209 + /* Find the IOAPIC that manages this GSI. */ 4210 + for (i = 0; i < nr_ioapics; i++) { 4211 + if ((gsi >= mp_gsi_routing[i].gsi_base) 4212 + && (gsi <= mp_gsi_routing[i].gsi_end)) 4213 + return i; 4214 + } 4215 + 4216 + printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); 4217 + return -1; 4218 + } 4219 + 4220 + int mp_find_ioapic_pin(int ioapic, int gsi) 4221 + { 4222 + if (WARN_ON(ioapic == -1)) 4223 + return -1; 4224 + if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end)) 4225 + return -1; 4226 + 4227 + return gsi - mp_gsi_routing[ioapic].gsi_base; 4228 + } 4229 + 4230 + static int bad_ioapic(unsigned long address) 4231 + { 4232 + if (nr_ioapics >= MAX_IO_APICS) { 4233 + printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded " 4234 + "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics); 4235 + return 1; 4236 + } 4237 + if (!address) { 4238 + printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address" 4239 + " found in table, skipping!\n"); 4240 + return 1; 4241 + } 4242 + return 0; 4243 + } 4244 + 4245 + void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) 4246 + { 4247 + int idx = 0; 4248 + 4249 + if (bad_ioapic(address)) 4250 + return; 4251 + 4252 + idx = nr_ioapics; 4253 + 4254 + mp_ioapics[idx].type = MP_IOAPIC; 4255 + mp_ioapics[idx].flags = MPC_APIC_USABLE; 4256 + mp_ioapics[idx].apicaddr = address; 4257 + 4258 + set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 4259 + mp_ioapics[idx].apicid = io_apic_unique_id(id); 4260 + mp_ioapics[idx].apicver = io_apic_get_version(idx); 4261 + 4262 + /* 4263 + * Build basic GSI lookup table to facilitate gsi->io_apic lookups 4264 + * and to prevent reprogramming of IOAPIC pins (PCI GSIs). 4265 + */ 4266 + mp_gsi_routing[idx].gsi_base = gsi_base; 4267 + mp_gsi_routing[idx].gsi_end = gsi_base + 4268 + io_apic_get_redir_entries(idx); 4269 + 4270 + printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " 4271 + "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, 4272 + mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, 4273 + mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end); 4274 + 4275 + nr_ioapics++; 4221 4276 }