1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Author: Huacai Chen <chenhuacai@loongson.cn> 4 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 5 */ 6 #ifndef __ASM_SMP_H 7 #define __ASM_SMP_H 8 9 #include <linux/atomic.h> 10 #include <linux/bitops.h> 11 #include <linux/linkage.h> 12 #include <linux/threads.h> 13 #include <linux/cpumask.h> 14 15 extern int smp_num_siblings; 16 extern int num_processors; 17 extern int disabled_cpus; 18 extern cpumask_t cpu_sibling_map[]; 19 extern cpumask_t cpu_core_map[]; 20 extern cpumask_t cpu_foreign_map[]; 21 22 void loongson_smp_setup(void); 23 void loongson_prepare_cpus(unsigned int max_cpus); 24 void loongson_boot_secondary(int cpu, struct task_struct *idle); 25 void loongson_init_secondary(void); 26 void loongson_smp_finish(void); 27 void loongson_send_ipi_single(int cpu, unsigned int action); 28 void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action); 29 #ifdef CONFIG_HOTPLUG_CPU 30 int loongson_cpu_disable(void); 31 void loongson_cpu_die(unsigned int cpu); 32 #endif 33 34 static inline void plat_smp_setup(void) 35 { 36 loongson_smp_setup(); 37 } 38 39 static inline int raw_smp_processor_id(void) 40 { 41 #if defined(__VDSO__) 42 extern int vdso_smp_processor_id(void) 43 __compiletime_error("VDSO should not call smp_processor_id()"); 44 return vdso_smp_processor_id(); 45 #else 46 return current_thread_info()->cpu; 47 #endif 48 } 49 #define raw_smp_processor_id raw_smp_processor_id 50 51 /* Map from cpu id to sequential logical cpu number. This will only 52 * not be idempotent when cpus failed to come on-line. */ 53 extern int __cpu_number_map[NR_CPUS]; 54 #define cpu_number_map(cpu) __cpu_number_map[cpu] 55 56 /* The reverse map from sequential logical cpu number to cpu id. */ 57 extern int __cpu_logical_map[NR_CPUS]; 58 #define cpu_logical_map(cpu) __cpu_logical_map[cpu] 59 60 #define cpu_physical_id(cpu) cpu_logical_map(cpu) 61 62 #define SMP_BOOT_CPU 0x1 63 #define SMP_RESCHEDULE 0x2 64 #define SMP_CALL_FUNCTION 0x4 65 66 struct secondary_data { 67 unsigned long stack; 68 unsigned long thread_info; 69 }; 70 extern struct secondary_data cpuboot_data; 71 72 extern asmlinkage void smpboot_entry(void); 73 74 extern void calculate_cpu_foreign_map(void); 75 76 /* 77 * Generate IPI list text 78 */ 79 extern void show_ipi_list(struct seq_file *p, int prec); 80 81 /* 82 * This function sends a 'reschedule' IPI to another CPU. 83 * it goes straight through and wastes no time serializing 84 * anything. Worst case is that we lose a reschedule ... 85 */ 86 static inline void smp_send_reschedule(int cpu) 87 { 88 loongson_send_ipi_single(cpu, SMP_RESCHEDULE); 89 } 90 91 static inline void arch_send_call_function_single_ipi(int cpu) 92 { 93 loongson_send_ipi_single(cpu, SMP_CALL_FUNCTION); 94 } 95 96 static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) 97 { 98 loongson_send_ipi_mask(mask, SMP_CALL_FUNCTION); 99 } 100 101 #ifdef CONFIG_HOTPLUG_CPU 102 static inline int __cpu_disable(void) 103 { 104 return loongson_cpu_disable(); 105 } 106 107 static inline void __cpu_die(unsigned int cpu) 108 { 109 loongson_cpu_die(cpu); 110 } 111 112 extern void play_dead(void); 113 #endif 114 115 #endif /* __ASM_SMP_H */ 116