18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/arm/include/asm/smp.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2004-2005 ARM Ltd. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#ifndef __ASM_ARM_SMP_H 88c2ecf20Sopenharmony_ci#define __ASM_ARM_SMP_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/threads.h> 118c2ecf20Sopenharmony_ci#include <linux/cpumask.h> 128c2ecf20Sopenharmony_ci#include <linux/thread_info.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifndef CONFIG_SMP 158c2ecf20Sopenharmony_ci# error "<asm/smp.h> included in non-SMP build" 168c2ecf20Sopenharmony_ci#endif 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define raw_smp_processor_id() (current_thread_info()->cpu) 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistruct seq_file; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* 238c2ecf20Sopenharmony_ci * generate IPI list text 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ciextern void show_ipi_list(struct seq_file *, int); 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* 288c2ecf20Sopenharmony_ci * Called from assembly code, this handles an IPI. 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ciasmlinkage void do_IPI(int ipinr, struct pt_regs *regs); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* 338c2ecf20Sopenharmony_ci * Called from C code, this handles an IPI. 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_civoid handle_IPI(int ipinr, struct pt_regs *regs); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* 388c2ecf20Sopenharmony_ci * Setup the set of possible CPUs (via set_cpu_possible) 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_ciextern void smp_init_cpus(void); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* 438c2ecf20Sopenharmony_ci * Register IPI interrupts with the arch SMP code 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_ciextern void set_smp_ipi_range(int ipi_base, int nr_ipi); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* 488c2ecf20Sopenharmony_ci * Called from platform specific assembly code, this is the 498c2ecf20Sopenharmony_ci * secondary CPU entry point. 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ciasmlinkage void secondary_start_kernel(void); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/* 558c2ecf20Sopenharmony_ci * Initial data for bringing up a secondary CPU. 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_cistruct secondary_data { 588c2ecf20Sopenharmony_ci union { 598c2ecf20Sopenharmony_ci struct mpu_rgn_info *mpu_rgn_info; 608c2ecf20Sopenharmony_ci u64 pgdir; 618c2ecf20Sopenharmony_ci }; 628c2ecf20Sopenharmony_ci unsigned long swapper_pg_dir; 638c2ecf20Sopenharmony_ci void *stack; 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ciextern struct secondary_data secondary_data; 668c2ecf20Sopenharmony_ciextern void secondary_startup(void); 678c2ecf20Sopenharmony_ciextern void secondary_startup_arm(void); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ciextern int __cpu_disable(void); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ciextern void __cpu_die(unsigned int cpu); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ciextern void arch_send_call_function_single_ipi(int cpu); 748c2ecf20Sopenharmony_ciextern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 758c2ecf20Sopenharmony_ciextern void arch_send_wakeup_ipi_mask(const struct cpumask *mask); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ciextern int register_ipi_completion(struct completion *completion, int cpu); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistruct smp_operations { 808c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 818c2ecf20Sopenharmony_ci /* 828c2ecf20Sopenharmony_ci * Setup the set of possible CPUs (via set_cpu_possible) 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci void (*smp_init_cpus)(void); 858c2ecf20Sopenharmony_ci /* 868c2ecf20Sopenharmony_ci * Initialize cpu_possible map, and enable coherency 878c2ecf20Sopenharmony_ci */ 888c2ecf20Sopenharmony_ci void (*smp_prepare_cpus)(unsigned int max_cpus); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci /* 918c2ecf20Sopenharmony_ci * Perform platform specific initialisation of the specified CPU. 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_ci void (*smp_secondary_init)(unsigned int cpu); 948c2ecf20Sopenharmony_ci /* 958c2ecf20Sopenharmony_ci * Boot a secondary CPU, and assign it the specified idle task. 968c2ecf20Sopenharmony_ci * This also gives us the initial stack to use for this CPU. 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_ci int (*smp_boot_secondary)(unsigned int cpu, struct task_struct *idle); 998c2ecf20Sopenharmony_ci#ifdef CONFIG_HOTPLUG_CPU 1008c2ecf20Sopenharmony_ci int (*cpu_kill)(unsigned int cpu); 1018c2ecf20Sopenharmony_ci void (*cpu_die)(unsigned int cpu); 1028c2ecf20Sopenharmony_ci bool (*cpu_can_disable)(unsigned int cpu); 1038c2ecf20Sopenharmony_ci int (*cpu_disable)(unsigned int cpu); 1048c2ecf20Sopenharmony_ci#endif 1058c2ecf20Sopenharmony_ci#endif 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistruct of_cpu_method { 1098c2ecf20Sopenharmony_ci const char *method; 1108c2ecf20Sopenharmony_ci const struct smp_operations *ops; 1118c2ecf20Sopenharmony_ci}; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ 1148c2ecf20Sopenharmony_ci static const struct of_cpu_method __cpu_method_of_table_##name \ 1158c2ecf20Sopenharmony_ci __used __section("__cpu_method_of_table") \ 1168c2ecf20Sopenharmony_ci = { .method = _method, .ops = _ops } 1178c2ecf20Sopenharmony_ci/* 1188c2ecf20Sopenharmony_ci * set platform specific SMP operations 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ciextern void smp_set_ops(const struct smp_operations *); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#endif /* ifndef __ASM_ARM_SMP_H */ 123