1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Default generic APIC driver. This handles up to 8 CPUs. 4 * 5 * Copyright 2003 Andi Kleen, SuSE Labs. 6 * 7 * Generic x86 APIC driver probe layer. 8 */ 9 #include <linux/export.h> 10 #include <linux/errno.h> 11 #include <linux/smp.h> 12 13 #include <xen/xen.h> 14 15 #include <asm/io_apic.h> 16 #include <asm/apic.h> 17 #include <asm/acpi.h> 18 19 #include "local.h" 20 21 static u32 default_phys_pkg_id(u32 cpuid_apic, int index_msb) 22 { 23 return cpuid_apic >> index_msb; 24 } 25 26 static u32 default_get_apic_id(u32 x) 27 { 28 unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); 29 30 if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID)) 31 return (x >> 24) & 0xFF; 32 else 33 return (x >> 24) & 0x0F; 34 } 35 36 /* should be called last. */ 37 static int probe_default(void) 38 { 39 return 1; 40 } 41 42 static struct apic apic_default __ro_after_init = { 43 44 .name = "default", 45 .probe = probe_default, 46 .apic_id_registered = default_apic_id_registered, 47 48 .delivery_mode = APIC_DELIVERY_MODE_FIXED, 49 .dest_mode_logical = true, 50 51 .disable_esr = 0, 52 53 .check_apicid_used = default_check_apicid_used, 54 .init_apic_ldr = default_init_apic_ldr, 55 .ioapic_phys_id_map = default_ioapic_phys_id_map, 56 .cpu_present_to_apicid = default_cpu_present_to_apicid, 57 .phys_pkg_id = default_phys_pkg_id, 58 59 .max_apic_id = 0xFE, 60 .get_apic_id = default_get_apic_id, 61 62 .calc_dest_apicid = apic_flat_calc_apicid, 63 64 .send_IPI = default_send_IPI_single, 65 .send_IPI_mask = default_send_IPI_mask_logical, 66 .send_IPI_mask_allbutself = default_send_IPI_mask_allbutself_logical, 67 .send_IPI_allbutself = default_send_IPI_allbutself, 68 .send_IPI_all = default_send_IPI_all, 69 .send_IPI_self = default_send_IPI_self, 70 71 .read = native_apic_mem_read, 72 .write = native_apic_mem_write, 73 .eoi = native_apic_mem_eoi, 74 .icr_read = native_apic_icr_read, 75 .icr_write = native_apic_icr_write, 76 .wait_icr_idle = apic_mem_wait_icr_idle, 77 .safe_wait_icr_idle = apic_mem_wait_icr_idle_timeout, 78 }; 79 80 apic_driver(apic_default); 81 82 struct apic *apic __ro_after_init = &apic_default; 83 EXPORT_SYMBOL_GPL(apic); 84 85 static int cmdline_apic __initdata; 86 static int __init parse_apic(char *arg) 87 { 88 struct apic **drv; 89 90 if (!arg) 91 return -EINVAL; 92 93 for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) { 94 if (!strcmp((*drv)->name, arg)) { 95 apic_install_driver(*drv); 96 cmdline_apic = 1; 97 return 0; 98 } 99 } 100 101 /* Parsed again by __setup for debug/verbose */ 102 return 0; 103 } 104 early_param("apic", parse_apic); 105 106 void __init x86_32_probe_bigsmp_early(void) 107 { 108 if (nr_cpu_ids <= 8 || xen_pv_domain()) 109 return; 110 111 if (IS_ENABLED(CONFIG_X86_BIGSMP)) { 112 switch (boot_cpu_data.x86_vendor) { 113 case X86_VENDOR_INTEL: 114 if (!APIC_XAPIC(boot_cpu_apic_version)) 115 break; 116 /* P4 and above */ 117 fallthrough; 118 case X86_VENDOR_HYGON: 119 case X86_VENDOR_AMD: 120 if (apic_bigsmp_possible(cmdline_apic)) 121 return; 122 break; 123 } 124 } 125 pr_info("Limiting to 8 possible CPUs\n"); 126 set_nr_cpu_ids(8); 127 } 128 129 void __init x86_32_install_bigsmp(void) 130 { 131 if (nr_cpu_ids > 8 && !xen_pv_domain()) 132 apic_bigsmp_force(); 133 } 134 135 void __init x86_32_probe_apic(void) 136 { 137 if (!cmdline_apic) { 138 struct apic **drv; 139 140 for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) { 141 if ((*drv)->probe()) { 142 apic_install_driver(*drv); 143 break; 144 } 145 } 146 /* Not visible without early console */ 147 if (drv == __apicdrivers_end) 148 panic("Didn't find an APIC driver"); 149 } 150 } 151