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 struct smp_ops { 16 void (*init_ipi)(void); 17 void (*send_ipi_single)(int cpu, unsigned int action); 18 void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action); 19 }; 20 extern struct smp_ops mp_ops; 21 22 extern int smp_num_siblings; 23 extern int num_processors; 24 extern int disabled_cpus; 25 extern cpumask_t cpu_sibling_map[]; 26 extern cpumask_t cpu_core_map[]; 27 extern cpumask_t cpu_foreign_map[]; 28 29 void loongson_smp_setup(void); 30 void loongson_prepare_cpus(unsigned int max_cpus); 31 void loongson_boot_secondary(int cpu, struct task_struct *idle); 32 void loongson_init_secondary(void); 33 void loongson_smp_finish(void); 34 #ifdef CONFIG_HOTPLUG_CPU 35 int loongson_cpu_disable(void); 36 void loongson_cpu_die(unsigned int cpu); 37 #endif 38 39 static inline void plat_smp_setup(void) 40 { 41 loongson_smp_setup(); 42 } 43 44 static inline int raw_smp_processor_id(void) 45 { 46 #if defined(__VDSO__) 47 extern int vdso_smp_processor_id(void) 48 __compiletime_error("VDSO should not call smp_processor_id()"); 49 return vdso_smp_processor_id(); 50 #else 51 return current_thread_info()->cpu; 52 #endif 53 } 54 #define raw_smp_processor_id raw_smp_processor_id 55 56 /* Map from cpu id to sequential logical cpu number. This will only 57 * not be idempotent when cpus failed to come on-line. */ 58 extern int __cpu_number_map[NR_CPUS]; 59 #define cpu_number_map(cpu) __cpu_number_map[cpu] 60 61 /* The reverse map from sequential logical cpu number to cpu id. */ 62 extern int __cpu_logical_map[NR_CPUS]; 63 #define cpu_logical_map(cpu) __cpu_logical_map[cpu] 64 65 #define cpu_physical_id(cpu) cpu_logical_map(cpu) 66 67 #define ACTION_BOOT_CPU 0 68 #define ACTION_RESCHEDULE 1 69 #define ACTION_CALL_FUNCTION 2 70 #define SMP_BOOT_CPU BIT(ACTION_BOOT_CPU) 71 #define SMP_RESCHEDULE BIT(ACTION_RESCHEDULE) 72 #define SMP_CALL_FUNCTION BIT(ACTION_CALL_FUNCTION) 73 74 struct secondary_data { 75 unsigned long stack; 76 unsigned long thread_info; 77 }; 78 extern struct secondary_data cpuboot_data; 79 80 extern asmlinkage void smpboot_entry(void); 81 extern asmlinkage void start_secondary(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 static inline void arch_send_call_function_single_ipi(int cpu) 91 { 92 mp_ops.send_ipi_single(cpu, ACTION_CALL_FUNCTION); 93 } 94 95 static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) 96 { 97 mp_ops.send_ipi_mask(mask, ACTION_CALL_FUNCTION); 98 } 99 100 #ifdef CONFIG_HOTPLUG_CPU 101 static inline int __cpu_disable(void) 102 { 103 return loongson_cpu_disable(); 104 } 105 106 static inline void __cpu_die(unsigned int cpu) 107 { 108 loongson_cpu_die(cpu); 109 } 110 #endif 111 112 #endif /* __ASM_SMP_H */ 113