1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <arch/cache.h>
7 #include <console/console.h>
9 #define CACHE_NODE_FLAGS 0xd7 // everything valid except, write-policy and allocation type
10 #define CLUSTER_FLAGS 0x11 // physical package, ID invalid, no thread, no leaf, identical impl.
11 #define CORE_FLAGS 0x0a // no physical package, ID valid, no thread, leaf.
12 #define CORE_FLAGS_1 0x12 // no physical package, ID valid, no thread, identical i.
17 struct pptt_cache l2
= {
25 struct pptt_cache l1d
= {
32 struct pptt_cache l1i
= {
38 * private resources of a cpu core. Same for
39 * each core, thus we can reuse this struture
40 * instead of creating it dynamically.
42 struct pptt_cpu_resources core_resources
= {
46 struct pptt_topology root_topology
= {
48 .flags
.raw
= CLUSTER_FLAGS
,
52 .child
= &(struct pptt_topology
) {
55 .flags
.raw
= CORE_FLAGS_1
,
59 .child
= &(struct pptt_topology
) {
61 .flags
.raw
= CORE_FLAGS
,
63 .resources
= &(struct pptt_cpu_resources
) {
72 .sibling
= NULL
, // updated in runtime
78 static u8
cache_attributes(const enum cache_type type
)
81 * 'write-policy' and 'allocation type' currently
82 * unsupported. cache flags set accordingly.
84 * maybe a todo for the future.
89 if (type
== CACHE_INSTRUCTION
)
91 else if (type
== CACHE_UNIFIED
)
97 /* --- ACPI hook --- */
99 struct pptt_topology
*acpi_get_pptt_topology(void)
101 struct cache_info info
;
103 /* Dump Cache info */
104 for (int cache_level
= CACHE_L1
; cache_level
<= CACHE_L7
; cache_level
++) {
105 int cache_type
= cpu_get_cache_type(cache_level
);
106 if (cache_type
== NO_CACHE
)
109 if (cache_type
== CACHE_SEPARATE
) {
110 printk(BIOS_DEBUG
, "Fetching cache info for: level:%d, type:%d\n",
111 cache_level
, cache_type
);
112 cpu_get_cache_info(cache_level
, cache_type
, &info
);
113 printk(BIOS_DEBUG
, "Size: %lld, associativity: %lld\n", info
.size
,
116 cache_type
= CACHE_INSTRUCTION
;
118 printk(BIOS_DEBUG
, "Fetching cache info for: level:%d, type:%d\n",
119 cache_level
, cache_type
);
120 cpu_get_cache_info(cache_level
, cache_type
, &info
);
121 printk(BIOS_DEBUG
, "Size: %lld, associativity: %lld\n", info
.size
,
124 cache_type
= CACHE_DATA
;
127 printk(BIOS_DEBUG
, "Fetching cache info for: level:%d, type:%d\n", cache_level
,
129 cpu_get_cache_info(cache_level
, cache_type
, &info
);
130 printk(BIOS_DEBUG
, "Size: %lld, associativity: %lld\n", info
.size
,
134 /* update cache information (L1I) */
136 cpu_get_cache_info(CACHE_L1
, CACHE_INSTRUCTION
, &info
);
138 l1i
.size
= info
.size
;
139 l1i
.associativity
= info
.associativity
;
140 l1i
.numsets
= info
.numsets
;
141 l1i
.line_size
= info
.line_bytes
;
142 l1i
.attributes
= cache_attributes(CACHE_INSTRUCTION
);
143 l1i
.flags
.raw
= CACHE_NODE_FLAGS
| 0xff;
145 /* update cache information (L1D) */
147 cpu_get_cache_info(CACHE_L1
, CACHE_DATA
, &info
);
149 l1d
.size
= info
.size
;
150 l1d
.associativity
= info
.associativity
;
151 l1d
.numsets
= info
.numsets
;
152 l1d
.line_size
= info
.line_bytes
;
153 l1d
.attributes
= cache_attributes(CACHE_DATA
) | (0x2);
154 l1d
.flags
.raw
= CACHE_NODE_FLAGS
| 0xff;
156 /* update cache information (L2) */
158 cpu_get_cache_info(CACHE_L2
, CACHE_UNIFIED
, &info
);
161 l2
.associativity
= info
.associativity
;
162 l2
.numsets
= info
.numsets
;
163 l2
.line_size
= info
.line_bytes
;
164 l2
.attributes
= cache_attributes(CACHE_UNIFIED
) | (0x2);
165 l2
.flags
.raw
= CACHE_NODE_FLAGS
| 0xff;
167 /* add secondary CPUs */
171 struct device
*dev
= NULL
;
172 struct pptt_topology
**it
= &root_topology
.child
->sibling
;
173 struct pptt_topology
**sibling
;
175 while ((dev
= dev_find_path(dev
, DEVICE_PATH_GICC_V3
))) {
182 if ((*it
= malloc(sizeof(struct pptt_topology
))) == NULL
) {
184 printk(BIOS_ERR
, "Could not allocate pptt structure!\n");
188 memset(*it
, 0, sizeof(struct pptt_topology
));
190 (*it
)->processor_id
= cpu_id
;
191 (*it
)->flags
.raw
= CORE_FLAGS_1
;
192 (*it
)->resources
= NULL
;
194 //sibling = (*it)->sibling;
195 sibling
= &(*it
)->sibling
;
199 if ((*it
= malloc(sizeof(struct pptt_topology
))) == NULL
) {
201 printk(BIOS_ERR
, "Could not allocate pptt structure!\n");
205 memset(*it
, 0, sizeof(struct pptt_topology
));
207 (*it
)->processor_id
= cpu_id
;
208 (*it
)->flags
.raw
= CORE_FLAGS
;
209 (*it
)->resources
= &core_resources
;
211 //it = &(*it)->sibling;
217 return &root_topology
;