1  /* SPDX-License-Identifier: GPL-2.0 */
2  #ifndef _LINUX_CACHEINFO_H
3  #define _LINUX_CACHEINFO_H
4  
5  #include <linux/bitops.h>
6  #include <linux/cpuhplock.h>
7  #include <linux/cpumask_types.h>
8  #include <linux/smp.h>
9  
10  struct device_node;
11  struct attribute;
12  
13  enum cache_type {
14  	CACHE_TYPE_NOCACHE = 0,
15  	CACHE_TYPE_INST = BIT(0),
16  	CACHE_TYPE_DATA = BIT(1),
17  	CACHE_TYPE_SEPARATE = CACHE_TYPE_INST | CACHE_TYPE_DATA,
18  	CACHE_TYPE_UNIFIED = BIT(2),
19  };
20  
21  extern unsigned int coherency_max_size;
22  
23  /**
24   * struct cacheinfo - represent a cache leaf node
25   * @id: This cache's id. It is unique among caches with the same (type, level).
26   * @type: type of the cache - data, inst or unified
27   * @level: represents the hierarchy in the multi-level cache
28   * @coherency_line_size: size of each cache line usually representing
29   *	the minimum amount of data that gets transferred from memory
30   * @number_of_sets: total number of sets, a set is a collection of cache
31   *	lines sharing the same index
32   * @ways_of_associativity: number of ways in which a particular memory
33   *	block can be placed in the cache
34   * @physical_line_partition: number of physical cache lines sharing the
35   *	same cachetag
36   * @size: Total size of the cache
37   * @shared_cpu_map: logical cpumask representing all the cpus sharing
38   *	this cache node
39   * @attributes: bitfield representing various cache attributes
40   * @fw_token: Unique value used to determine if different cacheinfo
41   *	structures represent a single hardware cache instance.
42   * @disable_sysfs: indicates whether this node is visible to the user via
43   *	sysfs or not
44   * @priv: pointer to any private data structure specific to particular
45   *	cache design
46   *
47   * While @of_node, @disable_sysfs and @priv are used for internal book
48   * keeping, the remaining members form the core properties of the cache
49   */
50  struct cacheinfo {
51  	unsigned int id;
52  	enum cache_type type;
53  	unsigned int level;
54  	unsigned int coherency_line_size;
55  	unsigned int number_of_sets;
56  	unsigned int ways_of_associativity;
57  	unsigned int physical_line_partition;
58  	unsigned int size;
59  	cpumask_t shared_cpu_map;
60  	unsigned int attributes;
61  #define CACHE_WRITE_THROUGH	BIT(0)
62  #define CACHE_WRITE_BACK	BIT(1)
63  #define CACHE_WRITE_POLICY_MASK		\
64  	(CACHE_WRITE_THROUGH | CACHE_WRITE_BACK)
65  #define CACHE_READ_ALLOCATE	BIT(2)
66  #define CACHE_WRITE_ALLOCATE	BIT(3)
67  #define CACHE_ALLOCATE_POLICY_MASK	\
68  	(CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE)
69  #define CACHE_ID		BIT(4)
70  	void *fw_token;
71  	bool disable_sysfs;
72  	void *priv;
73  };
74  
75  struct cpu_cacheinfo {
76  	struct cacheinfo *info_list;
77  	unsigned int per_cpu_data_slice_size;
78  	unsigned int num_levels;
79  	unsigned int num_leaves;
80  	bool cpu_map_populated;
81  	bool early_ci_levels;
82  };
83  
84  struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu);
85  int early_cache_level(unsigned int cpu);
86  int init_cache_level(unsigned int cpu);
87  int init_of_cache_level(unsigned int cpu);
88  int populate_cache_leaves(unsigned int cpu);
89  int cache_setup_acpi(unsigned int cpu);
90  bool last_level_cache_is_valid(unsigned int cpu);
91  bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y);
92  int fetch_cache_info(unsigned int cpu);
93  int detect_cache_attributes(unsigned int cpu);
94  #ifndef CONFIG_ACPI_PPTT
95  /*
96   * acpi_get_cache_info() is only called on ACPI enabled
97   * platforms using the PPTT for topology. This means that if
98   * the platform supports other firmware configuration methods
99   * we need to stub out the call when ACPI is disabled.
100   * ACPI enabled platforms not using PPTT won't be making calls
101   * to this function so we need not worry about them.
102   */
103  static inline
acpi_get_cache_info(unsigned int cpu,unsigned int * levels,unsigned int * split_levels)104  int acpi_get_cache_info(unsigned int cpu,
105  			unsigned int *levels, unsigned int *split_levels)
106  {
107  	return -ENOENT;
108  }
109  #else
110  int acpi_get_cache_info(unsigned int cpu,
111  			unsigned int *levels, unsigned int *split_levels);
112  #endif
113  
114  const struct attribute_group *cache_get_priv_group(struct cacheinfo *this_leaf);
115  
116  /*
117   * Get the cacheinfo structure for the cache associated with @cpu at
118   * level @level.
119   * cpuhp lock must be held.
120   */
get_cpu_cacheinfo_level(int cpu,int level)121  static inline struct cacheinfo *get_cpu_cacheinfo_level(int cpu, int level)
122  {
123  	struct cpu_cacheinfo *ci = get_cpu_cacheinfo(cpu);
124  	int i;
125  
126  	lockdep_assert_cpus_held();
127  
128  	for (i = 0; i < ci->num_leaves; i++) {
129  		if (ci->info_list[i].level == level) {
130  			if (ci->info_list[i].attributes & CACHE_ID)
131  				return &ci->info_list[i];
132  			return NULL;
133  		}
134  	}
135  
136  	return NULL;
137  }
138  
139  /*
140   * Get the id of the cache associated with @cpu at level @level.
141   * cpuhp lock must be held.
142   */
get_cpu_cacheinfo_id(int cpu,int level)143  static inline int get_cpu_cacheinfo_id(int cpu, int level)
144  {
145  	struct cacheinfo *ci = get_cpu_cacheinfo_level(cpu, level);
146  
147  	return ci ? ci->id : -1;
148  }
149  
150  #ifdef CONFIG_ARM64
151  #define use_arch_cache_info()	(true)
152  #else
153  #define use_arch_cache_info()	(false)
154  #endif
155  
156  #ifndef CONFIG_ARCH_HAS_CPU_CACHE_ALIASING
157  #define cpu_dcache_is_aliasing()	false
158  #else
159  #include <asm/cachetype.h>
160  #endif
161  
162  #endif /* _LINUX_CACHEINFO_H */
163