146859ac8SHuacai Chen /* SPDX-License-Identifier: GPL-2.0 */ 246859ac8SHuacai Chen /* 346859ac8SHuacai Chen * Author: Huacai Chen <chenhuacai@loongson.cn> 446859ac8SHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 546859ac8SHuacai Chen */ 646859ac8SHuacai Chen #ifndef __ASM_SMP_H 746859ac8SHuacai Chen #define __ASM_SMP_H 846859ac8SHuacai Chen 946859ac8SHuacai Chen #include <linux/atomic.h> 1046859ac8SHuacai Chen #include <linux/bitops.h> 1146859ac8SHuacai Chen #include <linux/linkage.h> 1246859ac8SHuacai Chen #include <linux/threads.h> 1346859ac8SHuacai Chen #include <linux/cpumask.h> 1446859ac8SHuacai Chen 15255b4658SHuacai Chen extern int smp_num_siblings; 16255b4658SHuacai Chen extern int num_processors; 17255b4658SHuacai Chen extern int disabled_cpus; 18255b4658SHuacai Chen extern cpumask_t cpu_sibling_map[]; 19255b4658SHuacai Chen extern cpumask_t cpu_core_map[]; 20255b4658SHuacai Chen extern cpumask_t cpu_foreign_map[]; 21255b4658SHuacai Chen 22c56ab8e8SHuacai Chen void loongson_smp_setup(void); 23c56ab8e8SHuacai Chen void loongson_prepare_cpus(unsigned int max_cpus); 24c56ab8e8SHuacai Chen void loongson_boot_secondary(int cpu, struct task_struct *idle); 25c56ab8e8SHuacai Chen void loongson_init_secondary(void); 26c56ab8e8SHuacai Chen void loongson_smp_finish(void); 27c56ab8e8SHuacai Chen void loongson_send_ipi_single(int cpu, unsigned int action); 28c56ab8e8SHuacai Chen void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action); 2946859ac8SHuacai Chen #ifdef CONFIG_HOTPLUG_CPU 30c56ab8e8SHuacai Chen int loongson_cpu_disable(void); 31c56ab8e8SHuacai Chen void loongson_cpu_die(unsigned int cpu); 3246859ac8SHuacai Chen #endif 3346859ac8SHuacai Chen plat_smp_setup(void)3446859ac8SHuacai Chenstatic inline void plat_smp_setup(void) 3546859ac8SHuacai Chen { 36c56ab8e8SHuacai Chen loongson_smp_setup(); 3746859ac8SHuacai Chen } 3846859ac8SHuacai Chen raw_smp_processor_id(void)3946859ac8SHuacai Chenstatic inline int raw_smp_processor_id(void) 4046859ac8SHuacai Chen { 4146859ac8SHuacai Chen #if defined(__VDSO__) 4246859ac8SHuacai Chen extern int vdso_smp_processor_id(void) 4346859ac8SHuacai Chen __compiletime_error("VDSO should not call smp_processor_id()"); 4446859ac8SHuacai Chen return vdso_smp_processor_id(); 4546859ac8SHuacai Chen #else 4646859ac8SHuacai Chen return current_thread_info()->cpu; 4746859ac8SHuacai Chen #endif 4846859ac8SHuacai Chen } 4946859ac8SHuacai Chen #define raw_smp_processor_id raw_smp_processor_id 5046859ac8SHuacai Chen 5146859ac8SHuacai Chen /* Map from cpu id to sequential logical cpu number. This will only 5246859ac8SHuacai Chen * not be idempotent when cpus failed to come on-line. */ 5346859ac8SHuacai Chen extern int __cpu_number_map[NR_CPUS]; 5446859ac8SHuacai Chen #define cpu_number_map(cpu) __cpu_number_map[cpu] 5546859ac8SHuacai Chen 5646859ac8SHuacai Chen /* The reverse map from sequential logical cpu number to cpu id. */ 5746859ac8SHuacai Chen extern int __cpu_logical_map[NR_CPUS]; 5846859ac8SHuacai Chen #define cpu_logical_map(cpu) __cpu_logical_map[cpu] 5946859ac8SHuacai Chen 6046859ac8SHuacai Chen #define cpu_physical_id(cpu) cpu_logical_map(cpu) 6146859ac8SHuacai Chen 6246859ac8SHuacai Chen #define SMP_BOOT_CPU 0x1 6346859ac8SHuacai Chen #define SMP_RESCHEDULE 0x2 6446859ac8SHuacai Chen #define SMP_CALL_FUNCTION 0x4 6546859ac8SHuacai Chen 6646859ac8SHuacai Chen struct secondary_data { 6746859ac8SHuacai Chen unsigned long stack; 6846859ac8SHuacai Chen unsigned long thread_info; 6946859ac8SHuacai Chen }; 7046859ac8SHuacai Chen extern struct secondary_data cpuboot_data; 7146859ac8SHuacai Chen 7246859ac8SHuacai Chen extern asmlinkage void smpboot_entry(void); 73*c718a0baSBibo Mao extern asmlinkage void start_secondary(void); 7446859ac8SHuacai Chen 7546859ac8SHuacai Chen extern void calculate_cpu_foreign_map(void); 7646859ac8SHuacai Chen 7746859ac8SHuacai Chen /* 7846859ac8SHuacai Chen * Generate IPI list text 7946859ac8SHuacai Chen */ 8046859ac8SHuacai Chen extern void show_ipi_list(struct seq_file *p, int prec); 8146859ac8SHuacai Chen arch_send_call_function_single_ipi(int cpu)8246859ac8SHuacai Chenstatic inline void arch_send_call_function_single_ipi(int cpu) 8346859ac8SHuacai Chen { 84c56ab8e8SHuacai Chen loongson_send_ipi_single(cpu, SMP_CALL_FUNCTION); 8546859ac8SHuacai Chen } 8646859ac8SHuacai Chen arch_send_call_function_ipi_mask(const struct cpumask * mask)8746859ac8SHuacai Chenstatic inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) 8846859ac8SHuacai Chen { 89c56ab8e8SHuacai Chen loongson_send_ipi_mask(mask, SMP_CALL_FUNCTION); 9046859ac8SHuacai Chen } 9146859ac8SHuacai Chen 9246859ac8SHuacai Chen #ifdef CONFIG_HOTPLUG_CPU __cpu_disable(void)9346859ac8SHuacai Chenstatic inline int __cpu_disable(void) 9446859ac8SHuacai Chen { 95c56ab8e8SHuacai Chen return loongson_cpu_disable(); 9646859ac8SHuacai Chen } 9746859ac8SHuacai Chen __cpu_die(unsigned int cpu)9846859ac8SHuacai Chenstatic inline void __cpu_die(unsigned int cpu) 9946859ac8SHuacai Chen { 100c56ab8e8SHuacai Chen loongson_cpu_die(cpu); 10146859ac8SHuacai Chen } 10246859ac8SHuacai Chen #endif 10346859ac8SHuacai Chen 10446859ac8SHuacai Chen #endif /* __ASM_SMP_H */ 105