xref: /openbmc/linux/arch/powerpc/include/asm/smp.h (revision 5e00d69c)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2b8b572e1SStephen Rothwell /*
3b8b572e1SStephen Rothwell  * smp.h: PowerPC-specific SMP code.
4b8b572e1SStephen Rothwell  *
5b8b572e1SStephen Rothwell  * Original was a copy of sparc smp.h.  Now heavily modified
6b8b572e1SStephen Rothwell  * for PPC.
7b8b572e1SStephen Rothwell  *
8b8b572e1SStephen Rothwell  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
9b8b572e1SStephen Rothwell  * Copyright (C) 1996-2001 Cort Dougan <cort@fsmlabs.com>
10b8b572e1SStephen Rothwell  */
11b8b572e1SStephen Rothwell 
12b8b572e1SStephen Rothwell #ifndef _ASM_POWERPC_SMP_H
13b8b572e1SStephen Rothwell #define _ASM_POWERPC_SMP_H
14b8b572e1SStephen Rothwell #ifdef __KERNEL__
15b8b572e1SStephen Rothwell 
16b8b572e1SStephen Rothwell #include <linux/threads.h>
17b8b572e1SStephen Rothwell #include <linux/cpumask.h>
18b8b572e1SStephen Rothwell #include <linux/kernel.h>
1923d72bfdSMilton Miller #include <linux/irqreturn.h>
20b8b572e1SStephen Rothwell 
21b8b572e1SStephen Rothwell #ifndef __ASSEMBLY__
22b8b572e1SStephen Rothwell 
23b8b572e1SStephen Rothwell #ifdef CONFIG_PPC64
24b8b572e1SStephen Rothwell #include <asm/paca.h>
25b8b572e1SStephen Rothwell #endif
26b8b572e1SStephen Rothwell #include <asm/percpu.h>
27b8b572e1SStephen Rothwell 
28b8b572e1SStephen Rothwell extern int boot_cpuid;
29dc222fa7SNicholas Piggin extern int boot_cpu_hwid; /* PPC64 only */
307ac87abbSMatt Evans extern int spinning_secondaries;
319f593f13SNicholas Piggin extern u32 *cpu_to_phys_id;
32f9f130ffSSrikar Dronamraju extern bool coregroup_enabled;
33b8b572e1SStephen Rothwell 
343eb906c6SMichael Ellerman extern int cpu_to_chip_id(int cpu);
35c1e53367SSrikar Dronamraju extern int *chip_id_lookup_table;
36b8b572e1SStephen Rothwell 
37a4bec516SGautham R. Shenoy DECLARE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map);
38a4bec516SGautham R. Shenoy DECLARE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map);
39e9ef81e1SParth Shah DECLARE_PER_CPU(cpumask_var_t, thread_group_l3_cache_map);
40a4bec516SGautham R. Shenoy 
41b8b572e1SStephen Rothwell #ifdef CONFIG_SMP
42b8b572e1SStephen Rothwell 
4317f9c8a7SMilton Miller struct smp_ops_t {
4417f9c8a7SMilton Miller 	void  (*message_pass)(int cpu, int msg);
451ece355bSMilton Miller #ifdef CONFIG_PPC_SMP_MUXED_IPI
46b866cc21SNicholas Piggin 	void  (*cause_ipi)(int cpu);
471ece355bSMilton Miller #endif
48c64af645SNicholas Piggin 	int   (*cause_nmi_ipi)(int cpu);
49a7f4ee1fSMichael Ellerman 	void  (*probe)(void);
5017f9c8a7SMilton Miller 	int   (*kick_cpu)(int nr);
5114d4ae5cSBenjamin Herrenschmidt 	int   (*prepare_cpu)(int nr);
5217f9c8a7SMilton Miller 	void  (*setup_cpu)(int nr);
5317f9c8a7SMilton Miller 	void  (*bringup_done)(void);
5417f9c8a7SMilton Miller 	void  (*take_timebase)(void);
5517f9c8a7SMilton Miller 	void  (*give_timebase)(void);
5617f9c8a7SMilton Miller 	int   (*cpu_disable)(void);
5717f9c8a7SMilton Miller 	void  (*cpu_die)(unsigned int nr);
5817f9c8a7SMilton Miller 	int   (*cpu_bootable)(unsigned int nr);
5939f87561SMichael Ellerman #ifdef CONFIG_HOTPLUG_CPU
6039f87561SMichael Ellerman 	void  (*cpu_offline_self)(void);
6139f87561SMichael Ellerman #endif
6217f9c8a7SMilton Miller };
6317f9c8a7SMilton Miller 
6476222808SChristophe Leroy extern struct task_struct *secondary_current;
6576222808SChristophe Leroy 
6676222808SChristophe Leroy void start_secondary(void *unused);
672104180aSNicholas Piggin extern int smp_send_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us);
686ba55716SMichael Ellerman extern int smp_send_safe_nmi_ipi(int cpu, void (*fn)(struct pt_regs *), u64 delay_us);
69e0476371SMilton Miller extern void smp_send_debugger_break(void);
70*5e00d69cSJosh Poimboeuf extern void __noreturn start_secondary_resume(void);
71cad5cef6SGreg Kroah-Hartman extern void smp_generic_give_timebase(void);
72cad5cef6SGreg Kroah-Hartman extern void smp_generic_take_timebase(void);
73b8b572e1SStephen Rothwell 
746b7487fcSTejun Heo DECLARE_PER_CPU(unsigned int, cpu_pvr);
75b8b572e1SStephen Rothwell 
76b8b572e1SStephen Rothwell #ifdef CONFIG_HOTPLUG_CPU
77b8b572e1SStephen Rothwell int generic_cpu_disable(void);
78b8b572e1SStephen Rothwell void generic_cpu_die(unsigned int cpu);
79105765f4SBenjamin Herrenschmidt void generic_set_cpu_dead(unsigned int cpu);
80ae5cab47SZhao Chenhui void generic_set_cpu_up(unsigned int cpu);
81fb82b839SBenjamin Herrenschmidt int generic_check_cpu_restart(unsigned int cpu);
822f4f1f81Schenhui zhao int is_cpu_dead(unsigned int cpu);
832f4f1f81Schenhui zhao #else
842f4f1f81Schenhui zhao #define generic_set_cpu_up(i)	do { } while (0)
85b8b572e1SStephen Rothwell #endif
86b8b572e1SStephen Rothwell 
87b8b572e1SStephen Rothwell #ifdef CONFIG_PPC64
88b8b572e1SStephen Rothwell #define raw_smp_processor_id()	(local_paca->paca_index)
89b8b572e1SStephen Rothwell #define hard_smp_processor_id() (get_paca()->hw_cpu_id)
90b8b572e1SStephen Rothwell #else
91b8b572e1SStephen Rothwell /* 32-bit */
92b8b572e1SStephen Rothwell extern int smp_hw_index[];
93b8b572e1SStephen Rothwell 
94336868afSArd Biesheuvel #define raw_smp_processor_id()		(current_thread_info()->cpu)
95b8b572e1SStephen Rothwell #define hard_smp_processor_id() 	(smp_hw_index[smp_processor_id()])
9641eba0adSBenjamin Herrenschmidt 
get_hard_smp_processor_id(int cpu)9741eba0adSBenjamin Herrenschmidt static inline int get_hard_smp_processor_id(int cpu)
9841eba0adSBenjamin Herrenschmidt {
9941eba0adSBenjamin Herrenschmidt 	return smp_hw_index[cpu];
10041eba0adSBenjamin Herrenschmidt }
10141eba0adSBenjamin Herrenschmidt 
set_hard_smp_processor_id(int cpu,int phys)10241eba0adSBenjamin Herrenschmidt static inline void set_hard_smp_processor_id(int cpu, int phys)
10341eba0adSBenjamin Herrenschmidt {
10441eba0adSBenjamin Herrenschmidt 	smp_hw_index[cpu] = phys;
10541eba0adSBenjamin Herrenschmidt }
106b8b572e1SStephen Rothwell #endif
107b8b572e1SStephen Rothwell 
108cc1ba8eaSAnton Blanchard DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
1092a636a56SOliver O'Halloran DECLARE_PER_CPU(cpumask_var_t, cpu_l2_cache_map);
110cc1ba8eaSAnton Blanchard DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
111425752c6SGautham R. Shenoy DECLARE_PER_CPU(cpumask_var_t, cpu_smallcore_map);
112cc1ba8eaSAnton Blanchard 
cpu_sibling_mask(int cpu)113cc1ba8eaSAnton Blanchard static inline struct cpumask *cpu_sibling_mask(int cpu)
114cc1ba8eaSAnton Blanchard {
115cc1ba8eaSAnton Blanchard 	return per_cpu(cpu_sibling_map, cpu);
116cc1ba8eaSAnton Blanchard }
117cc1ba8eaSAnton Blanchard 
cpu_core_mask(int cpu)118c47f892dSSrikar Dronamraju static inline struct cpumask *cpu_core_mask(int cpu)
119c47f892dSSrikar Dronamraju {
120c47f892dSSrikar Dronamraju 	return per_cpu(cpu_core_map, cpu);
121c47f892dSSrikar Dronamraju }
122c47f892dSSrikar Dronamraju 
cpu_l2_cache_mask(int cpu)1232a636a56SOliver O'Halloran static inline struct cpumask *cpu_l2_cache_mask(int cpu)
1242a636a56SOliver O'Halloran {
1252a636a56SOliver O'Halloran 	return per_cpu(cpu_l2_cache_map, cpu);
1262a636a56SOliver O'Halloran }
1272a636a56SOliver O'Halloran 
cpu_smallcore_mask(int cpu)128425752c6SGautham R. Shenoy static inline struct cpumask *cpu_smallcore_mask(int cpu)
129425752c6SGautham R. Shenoy {
130425752c6SGautham R. Shenoy 	return per_cpu(cpu_smallcore_map, cpu);
131425752c6SGautham R. Shenoy }
132425752c6SGautham R. Shenoy 
133b8b572e1SStephen Rothwell extern int cpu_to_core_id(int cpu);
134b8b572e1SStephen Rothwell 
135f3232321SSrikar Dronamraju extern bool has_big_cores;
1369538abeeSGautham R. Shenoy extern bool thread_group_shares_l2;
137e9ef81e1SParth Shah extern bool thread_group_shares_l3;
138f3232321SSrikar Dronamraju 
139f3232321SSrikar Dronamraju #define cpu_smt_mask cpu_smt_mask
140f3232321SSrikar Dronamraju #ifdef CONFIG_SCHED_SMT
cpu_smt_mask(int cpu)141f3232321SSrikar Dronamraju static inline const struct cpumask *cpu_smt_mask(int cpu)
142f3232321SSrikar Dronamraju {
143f3232321SSrikar Dronamraju 	if (has_big_cores)
144f3232321SSrikar Dronamraju 		return per_cpu(cpu_smallcore_map, cpu);
145f3232321SSrikar Dronamraju 
146f3232321SSrikar Dronamraju 	return per_cpu(cpu_sibling_map, cpu);
147f3232321SSrikar Dronamraju }
148f3232321SSrikar Dronamraju #endif /* CONFIG_SCHED_SMT */
149f3232321SSrikar Dronamraju 
150b8b572e1SStephen Rothwell /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
151b8b572e1SStephen Rothwell  *
152b8b572e1SStephen Rothwell  * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
153b8b572e1SStephen Rothwell  * in /proc/interrupts will be wrong!!! --Troy */
154b8b572e1SStephen Rothwell #define PPC_MSG_CALL_FUNCTION	0
155b8b572e1SStephen Rothwell #define PPC_MSG_RESCHEDULE	1
1561b67bee1SSrivatsa S. Bhat #define PPC_MSG_TICK_BROADCAST	2
157ddd703caSNicholas Piggin #define PPC_MSG_NMI_IPI		3
158b8b572e1SStephen Rothwell 
159bd7f561fSSuresh Warrier /* This is only used by the powernv kernel */
160bd7f561fSSuresh Warrier #define PPC_MSG_RM_HOST_ACTION	4
161bd7f561fSSuresh Warrier 
162ddd703caSNicholas Piggin #define NMI_IPI_ALL_OTHERS		-2
163ddd703caSNicholas Piggin 
164ddd703caSNicholas Piggin #ifdef CONFIG_NMI_IPI
165ddd703caSNicholas Piggin extern int smp_handle_nmi_ipi(struct pt_regs *regs);
166ddd703caSNicholas Piggin #else
smp_handle_nmi_ipi(struct pt_regs * regs)167ddd703caSNicholas Piggin static inline int smp_handle_nmi_ipi(struct pt_regs *regs) { return 0; }
168ddd703caSNicholas Piggin #endif
169ddd703caSNicholas Piggin 
17023d72bfdSMilton Miller /* for irq controllers that have dedicated ipis per message (4) */
17125ddd738SMilton Miller extern int smp_request_message_ipi(int virq, int message);
17225ddd738SMilton Miller extern const char *smp_ipi_name[];
17325ddd738SMilton Miller 
17423d72bfdSMilton Miller /* for irq controllers with only a single ipi */
17523d72bfdSMilton Miller extern void smp_muxed_ipi_message_pass(int cpu, int msg);
17631639c77SSuresh Warrier extern void smp_muxed_ipi_set_message(int cpu, int msg);
17723d72bfdSMilton Miller extern irqreturn_t smp_ipi_demux(void);
178b87ac021SNicholas Piggin extern irqreturn_t smp_ipi_demux_relaxed(void);
17923d72bfdSMilton Miller 
180b8b572e1SStephen Rothwell void smp_init_pSeries(void);
181b8b572e1SStephen Rothwell void smp_init_cell(void);
182b8b572e1SStephen Rothwell void smp_setup_cpu_maps(void);
183b8b572e1SStephen Rothwell 
184b8b572e1SStephen Rothwell extern int __cpu_disable(void);
185b8b572e1SStephen Rothwell extern void __cpu_die(unsigned int cpu);
186b8b572e1SStephen Rothwell 
187b8b572e1SStephen Rothwell #else
188b8b572e1SStephen Rothwell /* for UP */
18978b5b626SKumar Gala #define hard_smp_processor_id()		get_hard_smp_processor_id(0)
190b8b572e1SStephen Rothwell #define smp_setup_cpu_maps()
1919538abeeSGautham R. Shenoy #define thread_group_shares_l2  0
192e9ef81e1SParth Shah #define thread_group_shares_l3	0
cpu_sibling_mask(int cpu)1933be7db6aSRobert Jennings static inline const struct cpumask *cpu_sibling_mask(int cpu)
1943be7db6aSRobert Jennings {
1953be7db6aSRobert Jennings 	return cpumask_of(cpu);
1963be7db6aSRobert Jennings }
197b8b572e1SStephen Rothwell 
cpu_smallcore_mask(int cpu)198425752c6SGautham R. Shenoy static inline const struct cpumask *cpu_smallcore_mask(int cpu)
199425752c6SGautham R. Shenoy {
200425752c6SGautham R. Shenoy 	return cpumask_of(cpu);
201425752c6SGautham R. Shenoy }
202425752c6SGautham R. Shenoy 
cpu_l2_cache_mask(int cpu)2030be47634SGautham R. Shenoy static inline const struct cpumask *cpu_l2_cache_mask(int cpu)
2040be47634SGautham R. Shenoy {
2050be47634SGautham R. Shenoy 	return cpumask_of(cpu);
2060be47634SGautham R. Shenoy }
207b8b572e1SStephen Rothwell #endif /* CONFIG_SMP */
208b8b572e1SStephen Rothwell 
209b8b572e1SStephen Rothwell #ifdef CONFIG_PPC64
get_hard_smp_processor_id(int cpu)21041eba0adSBenjamin Herrenschmidt static inline int get_hard_smp_processor_id(int cpu)
21141eba0adSBenjamin Herrenschmidt {
212d2e60075SNicholas Piggin 	return paca_ptrs[cpu]->hw_cpu_id;
21341eba0adSBenjamin Herrenschmidt }
21441eba0adSBenjamin Herrenschmidt 
set_hard_smp_processor_id(int cpu,int phys)21541eba0adSBenjamin Herrenschmidt static inline void set_hard_smp_processor_id(int cpu, int phys)
21641eba0adSBenjamin Herrenschmidt {
217d2e60075SNicholas Piggin 	paca_ptrs[cpu]->hw_cpu_id = phys;
21841eba0adSBenjamin Herrenschmidt }
219b8b572e1SStephen Rothwell #else
220b8b572e1SStephen Rothwell /* 32-bit */
221b8b572e1SStephen Rothwell #ifndef CONFIG_SMP
222b8b572e1SStephen Rothwell extern int boot_cpuid_phys;
get_hard_smp_processor_id(int cpu)22341eba0adSBenjamin Herrenschmidt static inline int get_hard_smp_processor_id(int cpu)
22441eba0adSBenjamin Herrenschmidt {
22541eba0adSBenjamin Herrenschmidt 	return boot_cpuid_phys;
22641eba0adSBenjamin Herrenschmidt }
22741eba0adSBenjamin Herrenschmidt 
set_hard_smp_processor_id(int cpu,int phys)22841eba0adSBenjamin Herrenschmidt static inline void set_hard_smp_processor_id(int cpu, int phys)
22941eba0adSBenjamin Herrenschmidt {
23078b5b626SKumar Gala 	boot_cpuid_phys = phys;
23141eba0adSBenjamin Herrenschmidt }
23241eba0adSBenjamin Herrenschmidt #endif /* !CONFIG_SMP */
23341eba0adSBenjamin Herrenschmidt #endif /* !CONFIG_PPC64 */
234b8b572e1SStephen Rothwell 
235da665885SThiago Jung Bauermann #if defined(CONFIG_PPC64) && (defined(CONFIG_SMP) || defined(CONFIG_KEXEC_CORE))
236b1923caaSBenjamin Herrenschmidt extern void smp_release_cpus(void);
237b1923caaSBenjamin Herrenschmidt #else
smp_release_cpus(void)2386c6fdbb2SChengyang Fan static inline void smp_release_cpus(void) { }
239b1923caaSBenjamin Herrenschmidt #endif
240b1923caaSBenjamin Herrenschmidt 
241b8b572e1SStephen Rothwell extern int smt_enabled_at_boot;
242b8b572e1SStephen Rothwell 
243a7f4ee1fSMichael Ellerman extern void smp_mpic_probe(void);
244b8b572e1SStephen Rothwell extern void smp_mpic_setup_cpu(int cpu);
245de300974SMichael Ellerman extern int smp_generic_kick_cpu(int nr);
2463cd85250SAndy Fleming extern int smp_generic_cpu_bootable(unsigned int nr);
2473cd85250SAndy Fleming 
248b8b572e1SStephen Rothwell 
249b8b572e1SStephen Rothwell extern void smp_generic_give_timebase(void);
250b8b572e1SStephen Rothwell extern void smp_generic_take_timebase(void);
251b8b572e1SStephen Rothwell 
252b8b572e1SStephen Rothwell extern struct smp_ops_t *smp_ops;
253b8b572e1SStephen Rothwell 
254b8b572e1SStephen Rothwell extern void arch_send_call_function_single_ipi(int cpu);
255f063ea02SRusty Russell extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
256b8b572e1SStephen Rothwell 
257cf54dc7cSBenjamin Herrenschmidt /* Definitions relative to the secondary CPU spin loop
258cf54dc7cSBenjamin Herrenschmidt  * and entry point. Not all of them exist on both 32 and
259cf54dc7cSBenjamin Herrenschmidt  * 64-bit but defining them all here doesn't harm
260cf54dc7cSBenjamin Herrenschmidt  */
261cf54dc7cSBenjamin Herrenschmidt extern void generic_secondary_smp_init(void);
262cf54dc7cSBenjamin Herrenschmidt extern unsigned long __secondary_hold_spinloop;
263cf54dc7cSBenjamin Herrenschmidt extern unsigned long __secondary_hold_acknowledge;
264cf54dc7cSBenjamin Herrenschmidt extern char __secondary_hold;
2656becef7eSchenhui zhao extern unsigned int booting_thread_hwid;
266cf54dc7cSBenjamin Herrenschmidt 
267d0832a75SZhao Chenhui extern void __early_start(void);
268b8b572e1SStephen Rothwell #endif /* __ASSEMBLY__ */
269b8b572e1SStephen Rothwell 
270b8b572e1SStephen Rothwell #endif /* __KERNEL__ */
271b8b572e1SStephen Rothwell #endif /* _ASM_POWERPC_SMP_H) */
272