xref: /openbmc/linux/arch/x86/kernel/apic/probe_32.c (revision 3af1e415)
17e300dabSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
22a05180fSIngo Molnar /*
32a05180fSIngo Molnar  * Default generic APIC driver. This handles up to 8 CPUs.
42a05180fSIngo Molnar  *
52a05180fSIngo Molnar  * Copyright 2003 Andi Kleen, SuSE Labs.
62a05180fSIngo Molnar  *
72a05180fSIngo Molnar  * Generic x86 APIC driver probe layer.
82a05180fSIngo Molnar  */
9186f4360SPaul Gortmaker #include <linux/export.h>
102a05180fSIngo Molnar #include <linux/errno.h>
112a05180fSIngo Molnar #include <linux/smp.h>
122a05180fSIngo Molnar 
1379c9a17cSThomas Gleixner #include <xen/xen.h>
1479c9a17cSThomas Gleixner 
1513c01139SIngo Molnar #include <asm/io_apic.h>
162a05180fSIngo Molnar #include <asm/apic.h>
172a05180fSIngo Molnar #include <asm/acpi.h>
182a05180fSIngo Molnar 
19c94f0718SThomas Gleixner #include "local.h"
202a05180fSIngo Molnar 
default_phys_pkg_id(int cpuid_apic,int index_msb)210801bbaaSThomas Gleixner static int default_phys_pkg_id(int cpuid_apic, int index_msb)
220801bbaaSThomas Gleixner {
230801bbaaSThomas Gleixner 	return cpuid_apic >> index_msb;
240801bbaaSThomas Gleixner }
250801bbaaSThomas Gleixner 
262a05180fSIngo Molnar /* should be called last. */
probe_default(void)272a05180fSIngo Molnar static int probe_default(void)
282a05180fSIngo Molnar {
292a05180fSIngo Molnar 	return 1;
302a05180fSIngo Molnar }
312a05180fSIngo Molnar 
32404f6aacSKees Cook static struct apic apic_default __ro_after_init = {
332a05180fSIngo Molnar 
342a05180fSIngo Molnar 	.name				= "default",
352a05180fSIngo Molnar 	.probe				= probe_default,
362a05180fSIngo Molnar 	.apic_id_registered		= default_apic_id_registered,
372a05180fSIngo Molnar 
3872161299SThomas Gleixner 	.delivery_mode			= APIC_DELIVERY_MODE_FIXED,
398c44963bSThomas Gleixner 	.dest_mode_logical		= true,
402a05180fSIngo Molnar 
412a05180fSIngo Molnar 	.disable_esr			= 0,
42e57d04e5SThomas Gleixner 
432a05180fSIngo Molnar 	.check_apicid_used		= default_check_apicid_used,
442a05180fSIngo Molnar 	.init_apic_ldr			= default_init_apic_ldr,
452a05180fSIngo Molnar 	.ioapic_phys_id_map		= default_ioapic_phys_id_map,
462a05180fSIngo Molnar 	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
472a05180fSIngo Molnar 	.phys_pkg_id			= default_phys_pkg_id,
482a05180fSIngo Molnar 
49d92e5e7cSThomas Gleixner 	.max_apic_id			= 0xFE,
502a05180fSIngo Molnar 	.get_apic_id			= default_get_apic_id,
512a05180fSIngo Molnar 
529f9e3bb1SThomas Gleixner 	.calc_dest_apicid		= apic_flat_calc_apicid,
532a05180fSIngo Molnar 
546153058aSThomas Gleixner 	.send_IPI			= default_send_IPI_single,
552a05180fSIngo Molnar 	.send_IPI_mask			= default_send_IPI_mask_logical,
562a05180fSIngo Molnar 	.send_IPI_mask_allbutself	= default_send_IPI_mask_allbutself_logical,
572a05180fSIngo Molnar 	.send_IPI_allbutself		= default_send_IPI_allbutself,
582a05180fSIngo Molnar 	.send_IPI_all			= default_send_IPI_all,
592a05180fSIngo Molnar 	.send_IPI_self			= default_send_IPI_self,
602a05180fSIngo Molnar 
612a05180fSIngo Molnar 	.read				= native_apic_mem_read,
622a05180fSIngo Molnar 	.write				= native_apic_mem_write,
63185c8f33SThomas Gleixner 	.eoi				= native_apic_mem_eoi,
642a05180fSIngo Molnar 	.icr_read			= native_apic_icr_read,
652a05180fSIngo Molnar 	.icr_write			= native_apic_icr_write,
66cfebd007SThomas Gleixner 	.wait_icr_idle			= apic_mem_wait_icr_idle,
67e7b6a023SThomas Gleixner 	.safe_wait_icr_idle		= apic_mem_wait_icr_idle_timeout,
682a05180fSIngo Molnar };
692a05180fSIngo Molnar 
70107e0e0cSSuresh Siddha apic_driver(apic_default);
71107e0e0cSSuresh Siddha 
72404f6aacSKees Cook struct apic *apic __ro_after_init = &apic_default;
732a05180fSIngo Molnar EXPORT_SYMBOL_GPL(apic);
742a05180fSIngo Molnar 
752a05180fSIngo Molnar static int cmdline_apic __initdata;
parse_apic(char * arg)762a05180fSIngo Molnar static int __init parse_apic(char *arg)
772a05180fSIngo Molnar {
788b37e880SSuresh Siddha 	struct apic **drv;
792a05180fSIngo Molnar 
802a05180fSIngo Molnar 	if (!arg)
812a05180fSIngo Molnar 		return -EINVAL;
822a05180fSIngo Molnar 
838b37e880SSuresh Siddha 	for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
848b37e880SSuresh Siddha 		if (!strcmp((*drv)->name, arg)) {
85*3af1e415SThomas Gleixner 			apic_install_driver(*drv);
862a05180fSIngo Molnar 			cmdline_apic = 1;
872a05180fSIngo Molnar 			return 0;
882a05180fSIngo Molnar 		}
892a05180fSIngo Molnar 	}
902a05180fSIngo Molnar 
912a05180fSIngo Molnar 	/* Parsed again by __setup for debug/verbose */
922a05180fSIngo Molnar 	return 0;
932a05180fSIngo Molnar }
942a05180fSIngo Molnar early_param("apic", parse_apic);
952a05180fSIngo Molnar 
x86_32_probe_bigsmp_early(void)9679c9a17cSThomas Gleixner void __init x86_32_probe_bigsmp_early(void)
972a05180fSIngo Molnar {
9879c9a17cSThomas Gleixner 	if (nr_cpu_ids <= 8 || xen_pv_domain())
9979c9a17cSThomas Gleixner 		return;
10069c252ffSSuresh Siddha 
10179c9a17cSThomas Gleixner 	if (IS_ENABLED(CONFIG_X86_BIGSMP)) {
10269c252ffSSuresh Siddha 		switch (boot_cpu_data.x86_vendor) {
10369c252ffSSuresh Siddha 		case X86_VENDOR_INTEL:
10479c9a17cSThomas Gleixner 			if (!APIC_XAPIC(boot_cpu_apic_version))
10569c252ffSSuresh Siddha 				break;
1065785675dSBorislav Petkov 			/* P4 and above */
107df561f66SGustavo A. R. Silva 			fallthrough;
108da33dfefSPu Wen 		case X86_VENDOR_HYGON:
10969c252ffSSuresh Siddha 		case X86_VENDOR_AMD:
11079c9a17cSThomas Gleixner 			if (apic_bigsmp_possible(cmdline_apic))
11179c9a17cSThomas Gleixner 				return;
11279c9a17cSThomas Gleixner 			break;
11369c252ffSSuresh Siddha 		}
11469c252ffSSuresh Siddha 	}
11579c9a17cSThomas Gleixner 	pr_info("Limiting to 8 possible CPUs\n");
11679c9a17cSThomas Gleixner 	set_nr_cpu_ids(8);
11779c9a17cSThomas Gleixner }
11869c252ffSSuresh Siddha 
x86_32_install_bigsmp(void)1199d87f5b6SThomas Gleixner void __init x86_32_install_bigsmp(void)
12079c9a17cSThomas Gleixner {
12179c9a17cSThomas Gleixner 	if (nr_cpu_ids > 8 && !xen_pv_domain())
12279c9a17cSThomas Gleixner 		apic_bigsmp_force();
1232a05180fSIngo Molnar }
1242a05180fSIngo Molnar 
x86_32_probe_apic(void)1259d87f5b6SThomas Gleixner void __init x86_32_probe_apic(void)
1262a05180fSIngo Molnar {
1272a05180fSIngo Molnar 	if (!cmdline_apic) {
1288b37e880SSuresh Siddha 		struct apic **drv;
1298b37e880SSuresh Siddha 
1308b37e880SSuresh Siddha 		for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
1318b37e880SSuresh Siddha 			if ((*drv)->probe()) {
132*3af1e415SThomas Gleixner 				apic_install_driver(*drv);
1332a05180fSIngo Molnar 				break;
1342a05180fSIngo Molnar 			}
1352a05180fSIngo Molnar 		}
1362a05180fSIngo Molnar 		/* Not visible without early console */
1378b37e880SSuresh Siddha 		if (drv == __apicdrivers_end)
1382a05180fSIngo Molnar 			panic("Didn't find an APIC driver");
1392a05180fSIngo Molnar 	}
1402a05180fSIngo Molnar }
141