cputhreads.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_POWERPC_CPUTHREADS_H
  3. #define _ASM_POWERPC_CPUTHREADS_H
  4. #ifndef __ASSEMBLY__
  5. #include <linux/cpumask.h>
  6. #include <asm/cpu_has_feature.h>
  7. /*
  8. * Mapping of threads to cores
  9. *
  10. * Note: This implementation is limited to a power of 2 number of
  11. * threads per core and the same number for each core in the system
  12. * (though it would work if some processors had less threads as long
  13. * as the CPU numbers are still allocated, just not brought online).
  14. *
  15. * However, the API allows for a different implementation in the future
  16. * if needed, as long as you only use the functions and not the variables
  17. * directly.
  18. */
  19. #ifdef CONFIG_SMP
  20. extern int threads_per_core;
  21. extern int threads_per_subcore;
  22. extern int threads_shift;
  23. extern cpumask_t threads_core_mask;
  24. #else
  25. #define threads_per_core 1
  26. #define threads_per_subcore 1
  27. #define threads_shift 0
  28. #define has_big_cores 0
  29. #define threads_core_mask (*get_cpu_mask(0))
  30. #endif
  31. static inline int cpu_nr_cores(void)
  32. {
  33. return nr_cpu_ids >> threads_shift;
  34. }
  35. #ifdef CONFIG_SMP
  36. int cpu_core_index_of_thread(int cpu);
  37. int cpu_first_thread_of_core(int core);
  38. #else
  39. static inline int cpu_core_index_of_thread(int cpu) { return cpu; }
  40. static inline int cpu_first_thread_of_core(int core) { return core; }
  41. #endif
  42. static inline int cpu_thread_in_core(int cpu)
  43. {
  44. return cpu & (threads_per_core - 1);
  45. }
  46. static inline int cpu_thread_in_subcore(int cpu)
  47. {
  48. return cpu & (threads_per_subcore - 1);
  49. }
  50. static inline int cpu_first_thread_sibling(int cpu)
  51. {
  52. return cpu & ~(threads_per_core - 1);
  53. }
  54. static inline int cpu_last_thread_sibling(int cpu)
  55. {
  56. return cpu | (threads_per_core - 1);
  57. }
  58. /*
  59. * tlb_thread_siblings are siblings which share a TLB. This is not
  60. * architected, is not something a hypervisor could emulate and a future
  61. * CPU may change behaviour even in compat mode, so this should only be
  62. * used on PowerNV, and only with care.
  63. */
  64. static inline int cpu_first_tlb_thread_sibling(int cpu)
  65. {
  66. if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8))
  67. return cpu & ~0x6; /* Big Core */
  68. else
  69. return cpu_first_thread_sibling(cpu);
  70. }
  71. static inline int cpu_last_tlb_thread_sibling(int cpu)
  72. {
  73. if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8))
  74. return cpu | 0x6; /* Big Core */
  75. else
  76. return cpu_last_thread_sibling(cpu);
  77. }
  78. static inline int cpu_tlb_thread_sibling_step(void)
  79. {
  80. if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8))
  81. return 2; /* Big Core */
  82. else
  83. return 1;
  84. }
  85. static inline u32 get_tensr(void)
  86. {
  87. #ifdef CONFIG_BOOKE
  88. if (cpu_has_feature(CPU_FTR_SMT))
  89. return mfspr(SPRN_TENSR);
  90. #endif
  91. return 1;
  92. }
  93. void book3e_start_thread(int thread, unsigned long addr);
  94. void book3e_stop_thread(int thread);
  95. #endif /* __ASSEMBLY__ */
  96. #define INVALID_THREAD_HWID 0x0fff
  97. #endif /* _ASM_POWERPC_CPUTHREADS_H */