x2apic_phys.c revision 0ab711ae6ab0db7696b43c74f9ba9de4d7fc1deb
12d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha#include <linux/threads.h> 22d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha#include <linux/cpumask.h> 32d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha#include <linux/string.h> 42d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha#include <linux/kernel.h> 52d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha#include <linux/ctype.h> 62d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha#include <linux/init.h> 71b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu#include <linux/dmar.h> 81b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu 92d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha#include <asm/smp.h> 1079deb8e511bd6fc8e40add4da75b19df085d9453Cyrill Gorcunov#include <asm/x2apic.h> 112d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 12ef1f87aa7ba6224bef1b750b3272ba281d8f43edSuresh Siddhaint x2apic_phys; 131b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu 141a8880a14270814dae0d226a2ad065d30587e60aSuresh Siddhastatic struct apic apic_x2apic_phys; 151a8880a14270814dae0d226a2ad065d30587e60aSuresh Siddha 161b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lustatic int set_x2apic_phys_mode(char *arg) 171b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu{ 181b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu x2apic_phys = 1; 191b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu return 0; 201b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu} 211b9b89e7f163336ad84200b66a17284dbf26acedYinghai Luearly_param("x2apic_phys", set_x2apic_phys_mode); 221b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu 233cfba0892585d4c8e7b4122b5dc0d206a76936deMarcin Slusarzstatic int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) 241b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu{ 25ef1f87aa7ba6224bef1b750b3272ba281d8f43edSuresh Siddha if (x2apic_phys) 26ef1f87aa7ba6224bef1b750b3272ba281d8f43edSuresh Siddha return x2apic_enabled(); 27ea0dcf903e7d76aa5d483d876215fedcfdfe140fGreg Pearson else if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) && 28ea0dcf903e7d76aa5d483d876215fedcfdfe140fGreg Pearson (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) && 29ea0dcf903e7d76aa5d483d876215fedcfdfe140fGreg Pearson x2apic_enabled()) { 30ea0dcf903e7d76aa5d483d876215fedcfdfe140fGreg Pearson printk(KERN_DEBUG "System requires x2apic physical mode\n"); 31ea0dcf903e7d76aa5d483d876215fedcfdfe140fGreg Pearson return 1; 32ea0dcf903e7d76aa5d483d876215fedcfdfe140fGreg Pearson } 33ef1f87aa7ba6224bef1b750b3272ba281d8f43edSuresh Siddha else 34ef1f87aa7ba6224bef1b750b3272ba281d8f43edSuresh Siddha return 0; 351b9b89e7f163336ad84200b66a17284dbf26acedYinghai Lu} 362d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 37a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddhastatic void 38a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha__x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest) 392d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha{ 402d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha unsigned long query_cpu; 41a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha unsigned long this_cpu; 42dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar unsigned long flags; 432d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 44ce4e240c279a31096f74afa6584a62d64a1ba8c8Suresh Siddha x2apic_wrmsr_fence(); 45ce4e240c279a31096f74afa6584a62d64a1ba8c8Suresh Siddha 462d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha local_irq_save(flags); 47a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha 48a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha this_cpu = smp_processor_id(); 49bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travis for_each_cpu(query_cpu, mask) { 50a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha if (apic_dest == APIC_DEST_ALLBUT && this_cpu == query_cpu) 51a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha continue; 522d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha __x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu), 532d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha vector, APIC_DEST_PHYSICAL); 542d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha } 552d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha local_irq_restore(flags); 562d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha} 572d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 58a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddhastatic void x2apic_send_IPI_mask(const struct cpumask *mask, int vector) 59a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha{ 60a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLINC); 61a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha} 62a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha 63dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnarstatic void 64dac5f4121df3c39fdb2ea57acd669a0ae19e46f8Ingo Molnar x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector) 652d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha{ 66a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha __x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT); 67e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis} 682d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 69e7986739a76cde5079da08809d8bbc6878387ae0Mike Travisstatic void x2apic_send_IPI_allbutself(int vector) 70e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis{ 71a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLBUT); 722d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha} 732d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 742d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddhastatic void x2apic_send_IPI_all(int vector) 752d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha{ 76a27d0b5e7d913b38880678ac05690f1dc737c4fdSuresh Siddha __x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC); 772d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha} 782d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 79bcda016eddd7a8b374bb371473c821a91ff1d8ccMike Travisstatic unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask) 802d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha{ 812d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha /* 822d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha * We're using fixed IRQ delivery, can only return one phys APIC ID. 832d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha * May as well be the first. 842d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha */ 85debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar int cpu = cpumask_first(cpumask); 86debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar 87e7986739a76cde5079da08809d8bbc6878387ae0Mike Travis if ((unsigned)cpu < nr_cpu_ids) 882d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha return per_cpu(x86_cpu_to_apicid, cpu); 892d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha else 902d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha return BAD_APICID; 912d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha} 922d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 93debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnarstatic unsigned int 94debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnarx2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask, 95debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar const struct cpumask *andmask) 9695d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis{ 9795d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis int cpu; 9895d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis 9995d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis /* 10095d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis * We're using fixed IRQ delivery, can only return one phys APIC ID. 10195d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis * May as well be the first. 10295d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis */ 103debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar for_each_cpu_and(cpu, cpumask, andmask) { 104a775a38b1353161a6d7af86b667d6523c12c1a37Mike Travis if (cpumask_test_cpu(cpu, cpu_online_mask)) 105a775a38b1353161a6d7af86b667d6523c12c1a37Mike Travis break; 106debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar } 107debccb3e77be52cfc26c5a99e123c114c5c72aebIngo Molnar 10818374d89e5fe96772102f44f535efb1198d9be08Suresh Siddha return per_cpu(x86_cpu_to_apicid, cpu); 10995d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis} 11095d313cf1c1ecedc8bec5727b09bdacbf67dfc45Mike Travis 1114d08d97f5262dab4482af5bc91b30af4ca02269eJaswinder Singh Rajputstatic void init_x2apic_ldr(void) 1122d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha{ 1132d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha} 1142d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha 1159ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddhastatic int x2apic_phys_probe(void) 1169ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha{ 1179ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha if (x2apic_mode && x2apic_phys) 1189ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha return 1; 1199ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha 1209ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha return apic == &apic_x2apic_phys; 1219ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha} 1229ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha 1231a8880a14270814dae0d226a2ad065d30587e60aSuresh Siddhastatic struct apic apic_x2apic_phys = { 12405c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 12505c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .name = "physical x2apic", 1269ebd680bd029a9fc47399ca61c950f8b6730ac40Suresh Siddha .probe = x2apic_phys_probe, 12705c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, 128b7157acf429e6aef690646ba964b9ebd25049ec2Steffen Persvold .apic_id_valid = x2apic_apic_id_valid, 12905c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .apic_id_registered = x2apic_apic_id_registered, 13005c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 131f8987a1093cc7a896137e264c24e04d4048e9f95Ingo Molnar .irq_delivery_mode = dest_Fixed, 1320b06e734bff7554c31eac4aad2fc9be4adb7c1c1Ingo Molnar .irq_dest_mode = 0, /* physical */ 13305c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 13405c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .target_cpus = x2apic_target_cpus, 13508125d3edab90644724652eedec3e219e3e0f2e7Ingo Molnar .disable_esr = 0, 136bdb1a9b62fc182d4da3143e346f7a0925d243352Ingo Molnar .dest_logical = 0, 13705c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .check_apicid_used = NULL, 13805c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .check_apicid_present = NULL, 13905c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 14005c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .vector_allocation_domain = x2apic_vector_allocation_domain, 14105c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .init_apic_ldr = init_x2apic_ldr, 14205c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 14305c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .ioapic_phys_id_map = NULL, 14405c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .setup_apic_routing = NULL, 14505c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .multi_timer_check = NULL, 146a21769a4461801454930a06bc18bd8249cd9e993Ingo Molnar .cpu_present_to_apicid = default_cpu_present_to_apicid, 14705c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .apicid_to_cpu_present = NULL, 14805c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .setup_portio_remap = NULL, 149a27a621001f4c3e57caf47feff4b014577fd01c6Ingo Molnar .check_phys_apicid_present = default_check_phys_apicid_present, 15005c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .enable_apic_mode = NULL, 151d4c9a9f3d416cfa1f5ffbe09d864d069467fe693Ingo Molnar .phys_pkg_id = x2apic_phys_pkg_id, 15205c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .mps_oem_check = NULL, 15305c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 15479deb8e511bd6fc8e40add4da75b19df085d9453Cyrill Gorcunov .get_apic_id = x2apic_get_apic_id, 15579deb8e511bd6fc8e40add4da75b19df085d9453Cyrill Gorcunov .set_apic_id = x2apic_set_apic_id, 15605c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .apic_id_mask = 0xFFFFFFFFu, 15705c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 15805c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .cpu_mask_to_apicid = x2apic_cpu_mask_to_apicid, 15905c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .cpu_mask_to_apicid_and = x2apic_cpu_mask_to_apicid_and, 16005c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 16105c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .send_IPI_mask = x2apic_send_IPI_mask, 16205c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .send_IPI_mask_allbutself = x2apic_send_IPI_mask_allbutself, 16305c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .send_IPI_allbutself = x2apic_send_IPI_allbutself, 16405c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .send_IPI_all = x2apic_send_IPI_all, 16505c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .send_IPI_self = x2apic_send_IPI_self, 16605c155c235c757329ec89ad591516538ed8352c0Ingo Molnar 167abfa584c8df8b691cf18f51c7d4af27e5b32be4aIngo Molnar .trampoline_phys_low = DEFAULT_TRAMPOLINE_PHYS_LOW, 168abfa584c8df8b691cf18f51c7d4af27e5b32be4aIngo Molnar .trampoline_phys_high = DEFAULT_TRAMPOLINE_PHYS_HIGH, 16905c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .wait_for_init_deassert = NULL, 17005c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .smp_callin_clear_local_apic = NULL, 17105c155c235c757329ec89ad591516538ed8352c0Ingo Molnar .inquire_remote_apic = NULL, 172c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu 173c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu .read = native_apic_msr_read, 174c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu .write = native_apic_msr_write, 1750ab711ae6ab0db7696b43c74f9ba9de4d7fc1debMichael S. Tsirkin .eoi_write = native_apic_msr_eoi_write, 176c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu .icr_read = native_x2apic_icr_read, 177c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu .icr_write = native_x2apic_icr_write, 178c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu .wait_icr_idle = native_x2apic_wait_icr_idle, 179c1eeb2de41d7015678bdd412b48a5f071b84e29aYinghai Lu .safe_wait_icr_idle = native_safe_x2apic_wait_icr_idle, 1802d9579a124d746a3e0e0ba45e57d80800ee80807Suresh Siddha}; 181107e0e0cd85beeee05af7ea374fda14d037ee500Suresh Siddha 182107e0e0cd85beeee05af7ea374fda14d037ee500Suresh Siddhaapic_driver(apic_x2apic_phys); 183