xref: /linux/arch/riscv/include/asm/smp.h (revision 1ae91dc397eb1dbc0f4fc6b96f2481cbc02fe0f9)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2012 Regents of the University of California
4  */
5 
6 #ifndef _ASM_RISCV_SMP_H
7 #define _ASM_RISCV_SMP_H
8 
9 #include <linux/cpumask.h>
10 #include <linux/irqreturn.h>
11 #include <linux/thread_info.h>
12 
13 #define INVALID_HARTID ULONG_MAX
14 
15 struct seq_file;
16 extern unsigned long boot_cpu_hartid;
17 
18 enum ipi_message_type {
19 	IPI_RESCHEDULE,
20 	IPI_CALL_FUNC,
21 	IPI_CPU_STOP,
22 	IPI_CPU_CRASH_STOP,
23 	IPI_IRQ_WORK,
24 	IPI_TIMER,
25 	IPI_CPU_BACKTRACE,
26 	IPI_KGDB_ROUNDUP,
27 	IPI_MAX
28 };
29 
30 #ifdef CONFIG_SMP
31 
32 #include <linux/jump_label.h>
33 
34 /*
35  * Mapping between linux logical cpu index and hartid.
36  */
37 extern unsigned long __cpuid_to_hartid_map[NR_CPUS];
38 #define cpuid_to_hartid_map(cpu)    __cpuid_to_hartid_map[cpu]
39 
40 /* print IPI stats */
41 void show_ipi_stats(struct seq_file *p, int prec);
42 
43 /* SMP initialization hook for setup_arch */
44 void __init setup_smp(void);
45 
46 /* Hook for the generic smp_call_function_many() routine. */
47 void arch_send_call_function_ipi_mask(struct cpumask *mask);
48 
49 /* Hook for the generic smp_call_function_single() routine. */
50 void arch_send_call_function_single_ipi(int cpu);
51 
52 int riscv_hartid_to_cpuid(unsigned long hartid);
53 
54 /* Enable IPI for CPU hotplug */
55 void riscv_ipi_enable(void);
56 
57 /* Disable IPI for CPU hotplug */
58 void riscv_ipi_disable(void);
59 
60 /* Check if IPI interrupt numbers are available */
61 bool riscv_ipi_have_virq_range(void);
62 
63 /* Set the IPI interrupt numbers for arch (called by irqchip drivers) */
64 void riscv_ipi_set_virq_range(int virq, int nr);
65 
66 /* Check other CPUs stop or not */
67 bool smp_crash_stop_failed(void);
68 
69 /* Secondary hart entry */
70 asmlinkage void smp_callin(void);
71 
72 /*
73  * Obtains the hart ID of the currently executing task.  This relies on
74  * THREAD_INFO_IN_TASK, but we define that unconditionally.
75  */
76 #define raw_smp_processor_id() (current_thread_info()->cpu)
77 
78 #if defined CONFIG_HOTPLUG_CPU
79 int __cpu_disable(void);
80 static inline void __cpu_die(unsigned int cpu) { }
81 #endif /* CONFIG_HOTPLUG_CPU */
82 
83 #else
84 
85 static inline void show_ipi_stats(struct seq_file *p, int prec)
86 {
87 }
88 
89 static inline int riscv_hartid_to_cpuid(unsigned long hartid)
90 {
91 	if (hartid == boot_cpu_hartid)
92 		return 0;
93 
94 	return -1;
95 }
96 static inline unsigned long cpuid_to_hartid_map(int cpu)
97 {
98 	return boot_cpu_hartid;
99 }
100 
101 static inline void riscv_ipi_enable(void)
102 {
103 }
104 
105 static inline void riscv_ipi_disable(void)
106 {
107 }
108 
109 static inline bool riscv_ipi_have_virq_range(void)
110 {
111 	return false;
112 }
113 
114 static inline void riscv_ipi_set_virq_range(int virq, int nr)
115 {
116 }
117 
118 #endif /* CONFIG_SMP */
119 
120 #if defined(CONFIG_HOTPLUG_CPU)
121 bool cpu_has_hotplug(unsigned int cpu);
122 #else
123 static inline bool cpu_has_hotplug(unsigned int cpu)
124 {
125 	return false;
126 }
127 #endif
128 
129 #endif /* _ASM_RISCV_SMP_H */
130