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/smp.h> 13 #include <linux/threads.h> 14 #include <linux/cpumask.h> 15 16 void loongson3_smp_setup(void); 17 void loongson3_prepare_cpus(unsigned int max_cpus); 18 void loongson3_boot_secondary(int cpu, struct task_struct *idle); 19 void loongson3_init_secondary(void); 20 void loongson3_smp_finish(void); 21 void loongson3_send_ipi_single(int cpu, unsigned int action); 22 void loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action); 23 #ifdef CONFIG_HOTPLUG_CPU 24 int loongson3_cpu_disable(void); 25 void loongson3_cpu_die(unsigned int cpu); 26 #endif 27 28 #ifdef CONFIG_SMP 29 30 static inline void plat_smp_setup(void) 31 { 32 loongson3_smp_setup(); 33 } 34 35 #else /* !CONFIG_SMP */ 36 37 static inline void plat_smp_setup(void) { } 38 39 #endif /* !CONFIG_SMP */ 40 41 extern int smp_num_siblings; 42 extern int num_processors; 43 extern int disabled_cpus; 44 extern cpumask_t cpu_sibling_map[]; 45 extern cpumask_t cpu_core_map[]; 46 extern cpumask_t cpu_foreign_map[]; 47 48 static inline int raw_smp_processor_id(void) 49 { 50 #if defined(__VDSO__) 51 extern int vdso_smp_processor_id(void) 52 __compiletime_error("VDSO should not call smp_processor_id()"); 53 return vdso_smp_processor_id(); 54 #else 55 return current_thread_info()->cpu; 56 #endif 57 } 58 #define raw_smp_processor_id raw_smp_processor_id 59 60 /* Map from cpu id to sequential logical cpu number. This will only 61 * not be idempotent when cpus failed to come on-line. */ 62 extern int __cpu_number_map[NR_CPUS]; 63 #define cpu_number_map(cpu) __cpu_number_map[cpu] 64 65 /* The reverse map from sequential logical cpu number to cpu id. */ 66 extern int __cpu_logical_map[NR_CPUS]; 67 #define cpu_logical_map(cpu) __cpu_logical_map[cpu] 68 69 #define cpu_physical_id(cpu) cpu_logical_map(cpu) 70 71 #define SMP_BOOT_CPU 0x1 72 #define SMP_RESCHEDULE 0x2 73 #define SMP_CALL_FUNCTION 0x4 74 75 struct secondary_data { 76 unsigned long stack; 77 unsigned long thread_info; 78 }; 79 extern struct secondary_data cpuboot_data; 80 81 extern asmlinkage void smpboot_entry(void); 82 83 extern void calculate_cpu_foreign_map(void); 84 85 /* 86 * Generate IPI list text 87 */ 88 extern void show_ipi_list(struct seq_file *p, int prec); 89 90 /* 91 * This function sends a 'reschedule' IPI to another CPU. 92 * it goes straight through and wastes no time serializing 93 * anything. Worst case is that we lose a reschedule ... 94 */ 95 static inline void smp_send_reschedule(int cpu) 96 { 97 loongson3_send_ipi_single(cpu, SMP_RESCHEDULE); 98 } 99 100 static inline void arch_send_call_function_single_ipi(int cpu) 101 { 102 loongson3_send_ipi_single(cpu, SMP_CALL_FUNCTION); 103 } 104 105 static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) 106 { 107 loongson3_send_ipi_mask(mask, SMP_CALL_FUNCTION); 108 } 109 110 #ifdef CONFIG_HOTPLUG_CPU 111 static inline int __cpu_disable(void) 112 { 113 return loongson3_cpu_disable(); 114 } 115 116 static inline void __cpu_die(unsigned int cpu) 117 { 118 loongson3_cpu_die(cpu); 119 } 120 121 extern void play_dead(void); 122 #endif 123 124 #endif /* __ASM_SMP_H */ 125