smp.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Author: Huacai Chen <chenhuacai@loongson.cn>
  4. * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  5. */
  6. #ifndef __ASM_SMP_H
  7. #define __ASM_SMP_H
  8. #ifdef CONFIG_SMP
  9. #include <linux/atomic.h>
  10. #include <linux/bitops.h>
  11. #include <linux/linkage.h>
  12. #include <linux/threads.h>
  13. #include <linux/cpumask.h>
  14. struct smp_ops {
  15. void (*init_ipi)(void);
  16. void (*send_ipi_single)(int cpu, unsigned int action);
  17. void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
  18. };
  19. extern struct smp_ops mp_ops;
  20. extern int smp_num_siblings;
  21. extern int num_processors;
  22. extern int disabled_cpus;
  23. extern cpumask_t cpu_sibling_map[];
  24. extern cpumask_t cpu_llc_shared_map[];
  25. extern cpumask_t cpu_core_map[];
  26. extern cpumask_t cpu_foreign_map[];
  27. void loongson_smp_setup(void);
  28. void loongson_prepare_cpus(unsigned int max_cpus);
  29. void loongson_boot_secondary(int cpu, struct task_struct *idle);
  30. void loongson_init_secondary(void);
  31. void loongson_smp_finish(void);
  32. #ifdef CONFIG_HOTPLUG_CPU
  33. int loongson_cpu_disable(void);
  34. void loongson_cpu_die(unsigned int cpu);
  35. #endif
  36. static inline void __init plat_smp_setup(void)
  37. {
  38. loongson_smp_setup();
  39. }
  40. static inline int raw_smp_processor_id(void)
  41. {
  42. #if defined(__VDSO__)
  43. extern int vdso_smp_processor_id(void)
  44. __compiletime_error("VDSO should not call smp_processor_id()");
  45. return vdso_smp_processor_id();
  46. #else
  47. return current_thread_info()->cpu;
  48. #endif
  49. }
  50. #define raw_smp_processor_id raw_smp_processor_id
  51. /* Map from cpu id to sequential logical cpu number. This will only
  52. * not be idempotent when cpus failed to come on-line. */
  53. extern int __cpu_number_map[NR_CPUS];
  54. #define cpu_number_map(cpu) __cpu_number_map[cpu]
  55. /* The reverse map from sequential logical cpu number to cpu id. */
  56. extern int __cpu_logical_map[NR_CPUS];
  57. #define cpu_logical_map(cpu) __cpu_logical_map[cpu]
  58. #define cpu_physical_id(cpu) cpu_logical_map(cpu)
  59. #define ACTION_BOOT_CPU 0
  60. #define ACTION_RESCHEDULE 1
  61. #define ACTION_CALL_FUNCTION 2
  62. #define ACTION_IRQ_WORK 3
  63. #define ACTION_CLEAR_VECTOR 4
  64. #define SMP_BOOT_CPU BIT(ACTION_BOOT_CPU)
  65. #define SMP_RESCHEDULE BIT(ACTION_RESCHEDULE)
  66. #define SMP_CALL_FUNCTION BIT(ACTION_CALL_FUNCTION)
  67. #define SMP_IRQ_WORK BIT(ACTION_IRQ_WORK)
  68. #define SMP_CLEAR_VECTOR BIT(ACTION_CLEAR_VECTOR)
  69. struct seq_file;
  70. struct secondary_data {
  71. unsigned long stack;
  72. unsigned long thread_info;
  73. };
  74. extern struct secondary_data cpuboot_data;
  75. extern asmlinkage void smpboot_entry(void);
  76. extern asmlinkage void start_secondary(void);
  77. extern void calculate_cpu_foreign_map(void);
  78. /*
  79. * Generate IPI list text
  80. */
  81. extern void show_ipi_list(struct seq_file *p, int prec);
  82. static inline void arch_send_call_function_single_ipi(int cpu)
  83. {
  84. mp_ops.send_ipi_single(cpu, ACTION_CALL_FUNCTION);
  85. }
  86. static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
  87. {
  88. mp_ops.send_ipi_mask(mask, ACTION_CALL_FUNCTION);
  89. }
  90. #ifdef CONFIG_HOTPLUG_CPU
  91. static inline int __cpu_disable(void)
  92. {
  93. return loongson_cpu_disable();
  94. }
  95. static inline void __cpu_die(unsigned int cpu)
  96. {
  97. loongson_cpu_die(cpu);
  98. }
  99. #endif
  100. #else /* !CONFIG_SMP */
  101. #define cpu_logical_map(cpu) 0
  102. #endif /* CONFIG_SMP */
  103. #endif /* __ASM_SMP_H */