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