linux/arch/powerpc/include/asm/cputhreads.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _ASM_POWERPC_CPUTHREADS_H
   3#define _ASM_POWERPC_CPUTHREADS_H
   4
   5#ifndef __ASSEMBLY__
   6#include <linux/cpumask.h>
   7#include <asm/cpu_has_feature.h>
   8
   9/*
  10 * Mapping of threads to cores
  11 *
  12 * Note: This implementation is limited to a power of 2 number of
  13 * threads per core and the same number for each core in the system
  14 * (though it would work if some processors had less threads as long
  15 * as the CPU numbers are still allocated, just not brought online).
  16 *
  17 * However, the API allows for a different implementation in the future
  18 * if needed, as long as you only use the functions and not the variables
  19 * directly.
  20 */
  21
  22#ifdef CONFIG_SMP
  23extern int threads_per_core;
  24extern int threads_per_subcore;
  25extern int threads_shift;
  26extern bool has_big_cores;
  27extern cpumask_t threads_core_mask;
  28#else
  29#define threads_per_core        1
  30#define threads_per_subcore     1
  31#define threads_shift           0
  32#define has_big_cores           0
  33#define threads_core_mask       (*get_cpu_mask(0))
  34#endif
  35
  36/* cpu_thread_mask_to_cores - Return a cpumask of one per cores
  37 *                            hit by the argument
  38 *
  39 * @threads:    a cpumask of online threads
  40 *
  41 * This function returns a cpumask which will have one online cpu's
  42 * bit set for each core that has at least one thread set in the argument.
  43 *
  44 * This can typically be used for things like IPI for tlb invalidations
  45 * since those need to be done only once per core/TLB
  46 */
  47static inline cpumask_t cpu_thread_mask_to_cores(const struct cpumask *threads)
  48{
  49        cpumask_t       tmp, res;
  50        int             i, cpu;
  51
  52        cpumask_clear(&res);
  53        for (i = 0; i < NR_CPUS; i += threads_per_core) {
  54                cpumask_shift_left(&tmp, &threads_core_mask, i);
  55                if (cpumask_intersects(threads, &tmp)) {
  56                        cpu = cpumask_next_and(-1, &tmp, cpu_online_mask);
  57                        if (cpu < nr_cpu_ids)
  58                                cpumask_set_cpu(cpu, &res);
  59                }
  60        }
  61        return res;
  62}
  63
  64static inline int cpu_nr_cores(void)
  65{
  66        return nr_cpu_ids >> threads_shift;
  67}
  68
  69static inline cpumask_t cpu_online_cores_map(void)
  70{
  71        return cpu_thread_mask_to_cores(cpu_online_mask);
  72}
  73
  74#ifdef CONFIG_SMP
  75int cpu_core_index_of_thread(int cpu);
  76int cpu_first_thread_of_core(int core);
  77#else
  78static inline int cpu_core_index_of_thread(int cpu) { return cpu; }
  79static inline int cpu_first_thread_of_core(int core) { return core; }
  80#endif
  81
  82static inline int cpu_thread_in_core(int cpu)
  83{
  84        return cpu & (threads_per_core - 1);
  85}
  86
  87static inline int cpu_thread_in_subcore(int cpu)
  88{
  89        return cpu & (threads_per_subcore - 1);
  90}
  91
  92static inline int cpu_first_thread_sibling(int cpu)
  93{
  94        return cpu & ~(threads_per_core - 1);
  95}
  96
  97static inline int cpu_last_thread_sibling(int cpu)
  98{
  99        return cpu | (threads_per_core - 1);
 100}
 101
 102static inline u32 get_tensr(void)
 103{
 104#ifdef  CONFIG_BOOKE
 105        if (cpu_has_feature(CPU_FTR_SMT))
 106                return mfspr(SPRN_TENSR);
 107#endif
 108        return 1;
 109}
 110
 111void book3e_start_thread(int thread, unsigned long addr);
 112void book3e_stop_thread(int thread);
 113
 114#endif /* __ASSEMBLY__ */
 115
 116#define INVALID_THREAD_HWID     0x0fff
 117
 118#endif /* _ASM_POWERPC_CPUTHREADS_H */
 119
 120