162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_X86_SMP_H 362306a36Sopenharmony_ci#define _ASM_X86_SMP_H 462306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 562306a36Sopenharmony_ci#include <linux/cpumask.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <asm/cpumask.h> 862306a36Sopenharmony_ci#include <asm/current.h> 962306a36Sopenharmony_ci#include <asm/thread_info.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ciextern int smp_num_siblings; 1262306a36Sopenharmony_ciextern unsigned int num_processors; 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); 1562306a36Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); 1662306a36Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map); 1762306a36Sopenharmony_ci/* cpus sharing the last level cache: */ 1862306a36Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map); 1962306a36Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_l2c_shared_map); 2062306a36Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id); 2162306a36Sopenharmony_ciDECLARE_PER_CPU_READ_MOSTLY(u16, cpu_l2c_id); 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciDECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_cpu_to_apicid); 2462306a36Sopenharmony_ciDECLARE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistruct task_struct; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistruct smp_ops { 2962306a36Sopenharmony_ci void (*smp_prepare_boot_cpu)(void); 3062306a36Sopenharmony_ci void (*smp_prepare_cpus)(unsigned max_cpus); 3162306a36Sopenharmony_ci void (*smp_cpus_done)(unsigned max_cpus); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci void (*stop_other_cpus)(int wait); 3462306a36Sopenharmony_ci void (*crash_stop_other_cpus)(void); 3562306a36Sopenharmony_ci void (*smp_send_reschedule)(int cpu); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci void (*cleanup_dead_cpu)(unsigned cpu); 3862306a36Sopenharmony_ci void (*poll_sync_state)(void); 3962306a36Sopenharmony_ci int (*kick_ap_alive)(unsigned cpu, struct task_struct *tidle); 4062306a36Sopenharmony_ci int (*cpu_disable)(void); 4162306a36Sopenharmony_ci void (*cpu_die)(unsigned int cpu); 4262306a36Sopenharmony_ci void (*play_dead)(void); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci void (*send_call_func_ipi)(const struct cpumask *mask); 4562306a36Sopenharmony_ci void (*send_call_func_single_ipi)(int cpu); 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* Globals due to paravirt */ 4962306a36Sopenharmony_ciextern void set_cpu_sibling_map(int cpu); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#ifdef CONFIG_SMP 5262306a36Sopenharmony_ciextern struct smp_ops smp_ops; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistatic inline void smp_send_stop(void) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci smp_ops.stop_other_cpus(0); 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic inline void stop_other_cpus(void) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci smp_ops.stop_other_cpus(1); 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic inline void smp_prepare_boot_cpu(void) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci smp_ops.smp_prepare_boot_cpu(); 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic inline void smp_prepare_cpus(unsigned int max_cpus) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci smp_ops.smp_prepare_cpus(max_cpus); 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic inline void smp_cpus_done(unsigned int max_cpus) 7562306a36Sopenharmony_ci{ 7662306a36Sopenharmony_ci smp_ops.smp_cpus_done(max_cpus); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic inline int __cpu_disable(void) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci return smp_ops.cpu_disable(); 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic inline void __cpu_die(unsigned int cpu) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci if (smp_ops.cpu_die) 8762306a36Sopenharmony_ci smp_ops.cpu_die(cpu); 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic inline void __noreturn play_dead(void) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci smp_ops.play_dead(); 9362306a36Sopenharmony_ci BUG(); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic inline void arch_smp_send_reschedule(int cpu) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci smp_ops.smp_send_reschedule(cpu); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic inline void arch_send_call_function_single_ipi(int cpu) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci smp_ops.send_call_func_single_ipi(cpu); 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci smp_ops.send_call_func_ipi(mask); 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_civoid cpu_disable_common(void); 11262306a36Sopenharmony_civoid native_smp_prepare_boot_cpu(void); 11362306a36Sopenharmony_civoid smp_prepare_cpus_common(void); 11462306a36Sopenharmony_civoid native_smp_prepare_cpus(unsigned int max_cpus); 11562306a36Sopenharmony_civoid calculate_max_logical_packages(void); 11662306a36Sopenharmony_civoid native_smp_cpus_done(unsigned int max_cpus); 11762306a36Sopenharmony_ciint common_cpu_up(unsigned int cpunum, struct task_struct *tidle); 11862306a36Sopenharmony_ciint native_kick_ap(unsigned int cpu, struct task_struct *tidle); 11962306a36Sopenharmony_ciint native_cpu_disable(void); 12062306a36Sopenharmony_civoid __noreturn hlt_play_dead(void); 12162306a36Sopenharmony_civoid native_play_dead(void); 12262306a36Sopenharmony_civoid play_dead_common(void); 12362306a36Sopenharmony_civoid wbinvd_on_cpu(int cpu); 12462306a36Sopenharmony_ciint wbinvd_on_all_cpus(void); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_civoid smp_kick_mwait_play_dead(void); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_civoid native_smp_send_reschedule(int cpu); 12962306a36Sopenharmony_civoid native_send_call_func_ipi(const struct cpumask *mask); 13062306a36Sopenharmony_civoid native_send_call_func_single_ipi(int cpu); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_civoid smp_store_cpu_info(int id); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ciasmlinkage __visible void smp_reboot_interrupt(void); 13562306a36Sopenharmony_ci__visible void smp_reschedule_interrupt(struct pt_regs *regs); 13662306a36Sopenharmony_ci__visible void smp_call_function_interrupt(struct pt_regs *regs); 13762306a36Sopenharmony_ci__visible void smp_call_function_single_interrupt(struct pt_regs *r); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) 14062306a36Sopenharmony_ci#define cpu_acpi_id(cpu) per_cpu(x86_cpu_to_acpiid, cpu) 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/* 14362306a36Sopenharmony_ci * This function is needed by all SMP systems. It must _always_ be valid 14462306a36Sopenharmony_ci * from the initial startup. 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ci#define raw_smp_processor_id() this_cpu_read(pcpu_hot.cpu_number) 14762306a36Sopenharmony_ci#define __smp_processor_id() __this_cpu_read(pcpu_hot.cpu_number) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci#ifdef CONFIG_X86_32 15062306a36Sopenharmony_ciextern int safe_smp_processor_id(void); 15162306a36Sopenharmony_ci#else 15262306a36Sopenharmony_ci# define safe_smp_processor_id() smp_processor_id() 15362306a36Sopenharmony_ci#endif 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistatic inline struct cpumask *cpu_llc_shared_mask(int cpu) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci return per_cpu(cpu_llc_shared_map, cpu); 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic inline struct cpumask *cpu_l2c_shared_mask(int cpu) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci return per_cpu(cpu_l2c_shared_map, cpu); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci#else /* !CONFIG_SMP */ 16662306a36Sopenharmony_ci#define wbinvd_on_cpu(cpu) wbinvd() 16762306a36Sopenharmony_cistatic inline int wbinvd_on_all_cpus(void) 16862306a36Sopenharmony_ci{ 16962306a36Sopenharmony_ci wbinvd(); 17062306a36Sopenharmony_ci return 0; 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic inline struct cpumask *cpu_llc_shared_mask(int cpu) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci return (struct cpumask *)cpumask_of(0); 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci#endif /* CONFIG_SMP */ 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ciextern unsigned disabled_cpus; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_NMI_SELFTEST 18262306a36Sopenharmony_ciextern void nmi_selftest(void); 18362306a36Sopenharmony_ci#else 18462306a36Sopenharmony_ci#define nmi_selftest() do { } while (0) 18562306a36Sopenharmony_ci#endif 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ciextern unsigned int smpboot_control; 18862306a36Sopenharmony_ciextern unsigned long apic_mmio_base; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/* Control bits for startup_64 */ 19362306a36Sopenharmony_ci#define STARTUP_READ_APICID 0x80000000 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci/* Top 8 bits are reserved for control */ 19662306a36Sopenharmony_ci#define STARTUP_PARALLEL_MASK 0xFF000000 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci#endif /* _ASM_X86_SMP_H */ 199