18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2012 Regents of the University of California
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _ASM_RISCV_SMP_H
78c2ecf20Sopenharmony_ci#define _ASM_RISCV_SMP_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/cpumask.h>
108c2ecf20Sopenharmony_ci#include <linux/irqreturn.h>
118c2ecf20Sopenharmony_ci#include <linux/thread_info.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#define INVALID_HARTID ULONG_MAX
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistruct seq_file;
168c2ecf20Sopenharmony_ciextern unsigned long boot_cpu_hartid;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistruct riscv_ipi_ops {
198c2ecf20Sopenharmony_ci	void (*ipi_inject)(const struct cpumask *target);
208c2ecf20Sopenharmony_ci	void (*ipi_clear)(void);
218c2ecf20Sopenharmony_ci};
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP
248c2ecf20Sopenharmony_ci/*
258c2ecf20Sopenharmony_ci * Mapping between linux logical cpu index and hartid.
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_ciextern unsigned long __cpuid_to_hartid_map[NR_CPUS];
288c2ecf20Sopenharmony_ci#define cpuid_to_hartid_map(cpu)    __cpuid_to_hartid_map[cpu]
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/* print IPI stats */
318c2ecf20Sopenharmony_civoid show_ipi_stats(struct seq_file *p, int prec);
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/* SMP initialization hook for setup_arch */
348c2ecf20Sopenharmony_civoid __init setup_smp(void);
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* Called from C code, this handles an IPI. */
378c2ecf20Sopenharmony_civoid handle_IPI(struct pt_regs *regs);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/* Hook for the generic smp_call_function_many() routine. */
408c2ecf20Sopenharmony_civoid arch_send_call_function_ipi_mask(struct cpumask *mask);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/* Hook for the generic smp_call_function_single() routine. */
438c2ecf20Sopenharmony_civoid arch_send_call_function_single_ipi(int cpu);
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ciint riscv_hartid_to_cpuid(int hartid);
468c2ecf20Sopenharmony_civoid riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out);
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/* Set custom IPI operations */
498c2ecf20Sopenharmony_civoid riscv_set_ipi_ops(struct riscv_ipi_ops *ops);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci/* Clear IPI for current CPU */
528c2ecf20Sopenharmony_civoid riscv_clear_ipi(void);
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/* Secondary hart entry */
558c2ecf20Sopenharmony_ciasmlinkage void smp_callin(void);
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci/*
588c2ecf20Sopenharmony_ci * Obtains the hart ID of the currently executing task.  This relies on
598c2ecf20Sopenharmony_ci * THREAD_INFO_IN_TASK, but we define that unconditionally.
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_ci#define raw_smp_processor_id() (current_thread_info()->cpu)
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci#if defined CONFIG_HOTPLUG_CPU
648c2ecf20Sopenharmony_ciint __cpu_disable(void);
658c2ecf20Sopenharmony_civoid __cpu_die(unsigned int cpu);
668c2ecf20Sopenharmony_civoid cpu_stop(void);
678c2ecf20Sopenharmony_ci#else
688c2ecf20Sopenharmony_ci#endif /* CONFIG_HOTPLUG_CPU */
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#else
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic inline void show_ipi_stats(struct seq_file *p, int prec)
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic inline int riscv_hartid_to_cpuid(int hartid)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	if (hartid == boot_cpu_hartid)
798c2ecf20Sopenharmony_ci		return 0;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	return -1;
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_cistatic inline unsigned long cpuid_to_hartid_map(int cpu)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	return boot_cpu_hartid;
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistatic inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in,
898c2ecf20Sopenharmony_ci					      struct cpumask *out)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	cpumask_clear(out);
928c2ecf20Sopenharmony_ci	cpumask_set_cpu(boot_cpu_hartid, out);
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistatic inline void riscv_set_ipi_ops(struct riscv_ipi_ops *ops)
968c2ecf20Sopenharmony_ci{
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_cistatic inline void riscv_clear_ipi(void)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci}
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci#endif /* CONFIG_SMP */
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci#if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP)
1068c2ecf20Sopenharmony_cibool cpu_has_hotplug(unsigned int cpu);
1078c2ecf20Sopenharmony_ci#else
1088c2ecf20Sopenharmony_cistatic inline bool cpu_has_hotplug(unsigned int cpu)
1098c2ecf20Sopenharmony_ci{
1108c2ecf20Sopenharmony_ci	return false;
1118c2ecf20Sopenharmony_ci}
1128c2ecf20Sopenharmony_ci#endif
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci#endif /* _ASM_RISCV_SMP_H */
115