1 /* 2 * Copyright 2004 James Cleverdon, IBM. 3 * Subject to the GNU Public License, v.2 4 * 5 * Generic APIC sub-arch probe layer. 6 * 7 * Hacked for x86-64 by James Cleverdon from i386 architecture code by 8 * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and 9 * James Cleverdon. 10 */ 11 #include <linux/threads.h> 12 #include <linux/cpumask.h> 13 #include <linux/string.h> 14 #include <linux/module.h> 15 #include <linux/kernel.h> 16 #include <linux/ctype.h> 17 #include <linux/init.h> 18 #include <linux/hardirq.h> 19 #include <linux/dmar.h> 20 21 #include <asm/smp.h> 22 #include <asm/apic.h> 23 #include <asm/ipi.h> 24 #include <asm/setup.h> 25 26 static int apicid_phys_pkg_id(int initial_apic_id, int index_msb) 27 { 28 return hard_smp_processor_id() >> index_msb; 29 } 30 31 /* 32 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. 33 */ 34 void __init default_setup_apic_routing(void) 35 { 36 struct apic **drv; 37 38 enable_IR_x2apic(); 39 40 for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) { 41 if ((*drv)->probe && (*drv)->probe()) { 42 if (apic != *drv) { 43 apic = *drv; 44 pr_info("Switched APIC routing to %s.\n", 45 apic->name); 46 } 47 break; 48 } 49 } 50 51 if (is_vsmp_box()) { 52 /* need to update phys_pkg_id */ 53 apic->phys_pkg_id = apicid_phys_pkg_id; 54 } 55 } 56 57 /* Same for both flat and physical. */ 58 59 void apic_send_IPI_self(int vector) 60 { 61 __default_send_IPI_shortcut(APIC_DEST_SELF, vector, APIC_DEST_PHYSICAL); 62 } 63 64 int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id) 65 { 66 struct apic **drv; 67 68 for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) { 69 if ((*drv)->acpi_madt_oem_check(oem_id, oem_table_id)) { 70 if (apic != *drv) { 71 apic = *drv; 72 pr_info("Setting APIC routing to %s.\n", 73 apic->name); 74 } 75 return 1; 76 } 77 } 78 return 0; 79 } 80