coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
agesa_acpi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <acpi/acpi_crat.h>
5 #include <acpi/acpi_ivrs.h>
6 #include <arch/cpu.h>
7 #include <cpu/amd/cpuid.h>
8 #include <cpu/amd/msr.h>
9 #include <FspGuids.h>
10 #include <soc/acpi.h>
11 #include <stdint.h>
12 #include <device/device.h>
13 #include <device/pci_def.h>
14 #include <device/pci_ops.h>
15 #include <amdblocks/acpi.h>
16 #include <amdblocks/cpu.h>
17 #include <amdblocks/data_fabric.h>
18 #include <amdblocks/ioapic.h>
19 #include <soc/data_fabric.h>
20 #include <soc/pci_devs.h>
21 #include <arch/mmio.h>
22 
23 static unsigned long gen_crat_hsa_entry(struct acpi_crat_header *crat, unsigned long current)
24 {
25  struct crat_hsa_processing_unit *hsa_entry = (struct crat_hsa_processing_unit *)current;
26  memset(hsa_entry, 0, sizeof(struct crat_hsa_processing_unit));
27 
29  hsa_entry->wave_front_size = 4;
30  hsa_entry->num_cpu_cores = get_cpu_count();
31  hsa_entry->length = sizeof(struct crat_hsa_processing_unit);
32  crat->total_entries++;
33 
34  current += hsa_entry->length;
35  return current;
36 }
37 
38 static unsigned long create_crat_memory_entry(uint32_t domain, uint64_t region_base,
39  uint64_t region_size, unsigned long current)
40 {
41  struct crat_memory *mem_affinity = (struct crat_memory *)current;
42  memset(mem_affinity, 0, sizeof(struct crat_memory));
43 
44  mem_affinity->type = CRAT_MEMORY_TYPE;
45  mem_affinity->length = sizeof(struct crat_memory);
46  mem_affinity->proximity_domain = 0;
47  mem_affinity->base_address_low = region_base & 0xffffffff;
48  mem_affinity->base_address_high = (region_base >> 32) & 0xffffffff;
49  mem_affinity->length_low = region_size & 0xffffffff;
50  mem_affinity->length_high = (region_size >> 32) & 0xffffffff;
51  mem_affinity->flags = CRAT_MEM_FLAG_EN;
52  mem_affinity->width = 64;
53 
54  current += mem_affinity->length;
55  return current;
56 }
57 
58 static unsigned long gen_crat_memory_entries(struct acpi_crat_header *crat,
59  unsigned long current)
60 {
61  uint32_t dram_base_reg, dram_limit_reg, dram_hole_ctl;
62  uint64_t memory_length, memory_base, hole_base, size_below_hole;
63  size_t new_entries = 0;
64 
65  for (size_t dram_map_idx = 0; dram_map_idx < PICASSO_NUM_DRAM_REG;
66  dram_map_idx++) {
67  dram_base_reg =
69 
70  if (dram_base_reg & DRAM_BASE_REG_VALID) {
71  dram_limit_reg = data_fabric_read32(0, DF_DRAM_LIMIT(dram_map_idx),
73  memory_length =
74  ((dram_limit_reg & DRAM_LIMIT_ADDR) >> DRAM_LIMIT_ADDR_SHFT) + 1
75  - ((dram_base_reg & DRAM_BASE_ADDR) >> DRAM_BASE_ADDR_SHFT);
76  memory_length = memory_length << 28;
77  memory_base = (uint64_t)(dram_base_reg & DRAM_BASE_ADDR)
78  << (28 - DRAM_BASE_ADDR_SHFT);
79 
80  if (memory_base == 0) {
81  current =
82  create_crat_memory_entry(0, 0ull, 0xa0000ull, current);
83  memory_base = 1 * MiB;
84  memory_length = memory_base;
85  new_entries++;
86  }
87 
88  if (dram_base_reg & DRAM_BASE_HOLE_EN) {
89  dram_hole_ctl = data_fabric_read32(0, D18F0_DRAM_HOLE_CTL,
91  hole_base = (dram_hole_ctl & DRAM_HOLE_CTL_BASE);
92  size_below_hole = hole_base - memory_base;
93  current = create_crat_memory_entry(0, memory_base,
94  size_below_hole, current);
95  memory_length = (uint64_t)(((dram_limit_reg & DRAM_LIMIT_ADDR)
97  + 1 - 0x10)
98  << 28;
99  memory_base = 0x100000000;
100  new_entries++;
101  }
102 
103  current = create_crat_memory_entry(0, memory_base, memory_length,
104  current);
105  new_entries++;
106  }
107  }
108  crat->total_entries += new_entries;
109  return current;
110 }
111 
112 static unsigned long add_crat_cache_entry(struct crat_cache **cache_affinity,
113  unsigned long current)
114 {
115  *cache_affinity = (struct crat_cache *)current;
116  memset(*cache_affinity, 0, sizeof(struct crat_cache));
117 
118  (*cache_affinity)->type = CRAT_CACHE_TYPE;
119  (*cache_affinity)->length = sizeof(struct crat_cache);
120  (*cache_affinity)->flags = CRAT_CACHE_FLAG_EN | CRAT_CACHE_FLAG_CPU_CACHE;
121 
122  current += sizeof(struct crat_cache);
123  return current;
124 }
125 
126 static uint8_t get_associativity(uint32_t encoded_associativity)
127 {
129 
130  switch (encoded_associativity) {
131  case 0:
132  case 1:
133  case 2:
134  case 3:
135  case 4:
136  return encoded_associativity;
137  case 5:
138  associativity = 6;
139  break;
140  case 6:
141  associativity = 8;
142  break;
143  case 8:
144  associativity = 16;
145  break;
146  case 0xA:
147  associativity = 32;
148  break;
149  case 0xB:
150  associativity = 48;
151  break;
152  case 0xC:
153  associativity = 64;
154  break;
155  case 0xD:
156  associativity = 96;
157  break;
158  case 0xE:
159  associativity = 128;
160  break;
161  case 0xF:
162  associativity = 0xFF;
163  break;
164  default:
165  return 0;
166  }
167 
168  return associativity;
169 }
170 
171 static unsigned long gen_crat_cache_entry(struct acpi_crat_header *crat, unsigned long current)
172 {
173  size_t total_num_threads, num_threads_sharing0, num_threads_sharing1,
174  num_threads_sharing2, num_threads_sharing3, thread, new_entries;
175  struct cpuid_result cache_props0, cache_props1, cache_props2, cache_props3;
176  uint8_t sibling_mask = 0;
177  uint32_t l1_data_cache_ids, l1_inst_cache_ids, l2_cache_ids, l3_cache_ids;
178  struct crat_cache *cache_affinity = NULL;
179 
180  total_num_threads = get_cpu_count();
181 
182  cache_props0 = cpuid_ext(CPUID_CACHE_PROPS, CACHE_PROPS_0);
183  cache_props1 = cpuid_ext(CPUID_CACHE_PROPS, CACHE_PROPS_1);
184  cache_props2 = cpuid_ext(CPUID_CACHE_PROPS, CACHE_PROPS_2);
185  cache_props3 = cpuid_ext(CPUID_CACHE_PROPS, CACHE_PROPS_3);
186 
187  l1_data_cache_ids = cpuid_ecx(CPUID_L1_TLB_CACHE_IDS);
188  l1_inst_cache_ids = cpuid_edx(CPUID_L1_TLB_CACHE_IDS);
189  l2_cache_ids = cpuid_ecx(CPUID_L2_L3_CACHE_L2_TLB_IDS);
190  l3_cache_ids = cpuid_edx(CPUID_L2_L3_CACHE_L2_TLB_IDS);
191 
192  num_threads_sharing0 =
193  ((cache_props0.eax & NUM_SHARE_CACHE_MASK) >> NUM_SHARE_CACHE_SHFT) + 1;
194  num_threads_sharing1 =
195  ((cache_props1.eax & NUM_SHARE_CACHE_MASK) >> NUM_SHARE_CACHE_SHFT) + 1;
196  num_threads_sharing2 =
197  ((cache_props2.eax & NUM_SHARE_CACHE_MASK) >> NUM_SHARE_CACHE_SHFT) + 1;
198  num_threads_sharing3 =
199  ((cache_props3.eax & NUM_SHARE_CACHE_MASK) >> NUM_SHARE_CACHE_SHFT) + 1;
200 
201  new_entries = 0;
202  for (thread = 0; thread < total_num_threads; thread++) {
203  /* L1 data cache */
204  if (thread % num_threads_sharing0 == 0) {
205  current = add_crat_cache_entry(&cache_affinity, current);
206  new_entries++;
207 
208  cache_affinity->flags |= CRAT_CACHE_FLAG_DATA_CACHE;
209  cache_affinity->proc_id_low = thread;
210  sibling_mask = 1;
211  for (size_t sibling = 1; sibling < num_threads_sharing0; sibling++)
212  sibling_mask = (sibling_mask << 1) + 1;
213  cache_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
214  cache_affinity->cache_properties =
215  (cache_props0.edx & CACHE_INCLUSIVE_MASK) ? 2 : 0;
216  cache_affinity->cache_size =
217  (l1_data_cache_ids & L1_DC_SIZE_MASK) >> L1_DC_SIZE_SHFT;
218  cache_affinity->cache_level = CRAT_L1_CACHE;
219  cache_affinity->lines_per_tag =
220  (l1_data_cache_ids & L1_DC_LINE_TAG_MASK)
222  cache_affinity->cache_line_size =
223  (l1_data_cache_ids & L1_DC_LINE_SIZE_MASK)
225  cache_affinity->associativity =
226  (l1_data_cache_ids & L1_DC_ASSOC_MASK) >> L1_DC_ASSOC_SHFT;
227  cache_affinity->cache_latency = 1;
228  }
229 
230  /* L1 instruction cache */
231  if (thread % num_threads_sharing1 == 0) {
232  current = add_crat_cache_entry(&cache_affinity, current);
233  new_entries++;
234 
235  cache_affinity->flags |= CRAT_CACHE_FLAG_INSTR_CACHE;
236  cache_affinity->proc_id_low = thread;
237  sibling_mask = 1;
238  for (size_t sibling = 1; sibling < num_threads_sharing1; sibling++)
239  sibling_mask = (sibling_mask << 1) + 1;
240  cache_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
241  cache_affinity->cache_properties =
242  (cache_props1.edx & CACHE_INCLUSIVE_MASK) ? 2 : 0;
243  cache_affinity->cache_size =
244  (l1_inst_cache_ids & L1_IC_SIZE_MASK) >> L1_IC_SIZE_SHFT;
245  cache_affinity->cache_level = CRAT_L1_CACHE;
246  cache_affinity->lines_per_tag =
247  (l1_inst_cache_ids & L1_IC_LINE_TAG_MASK)
249  cache_affinity->cache_line_size =
250  (l1_inst_cache_ids & L1_IC_LINE_SIZE_MASK)
252  cache_affinity->associativity =
253  (l1_inst_cache_ids & L1_IC_ASSOC_MASK) >> L1_IC_ASSOC_SHFT;
254  cache_affinity->cache_latency = 1;
255  }
256 
257  /* L2 cache */
258  if (thread % num_threads_sharing2 == 0) {
259  current = add_crat_cache_entry(&cache_affinity, current);
260  new_entries++;
261 
262  cache_affinity->flags |=
264  cache_affinity->proc_id_low = thread;
265  sibling_mask = 1;
266  for (size_t sibling = 1; sibling < num_threads_sharing2; sibling++)
267  sibling_mask = (sibling_mask << 1) + 1;
268  cache_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
269  cache_affinity->cache_properties =
270  (cache_props2.edx & CACHE_INCLUSIVE_MASK) ? 2 : 0;
271  cache_affinity->cache_size =
272  (l2_cache_ids & L2_DC_SIZE_MASK) >> L2_DC_SIZE_SHFT;
273  cache_affinity->cache_level = CRAT_L2_CACHE;
274  cache_affinity->lines_per_tag =
275  (l2_cache_ids & L2_DC_LINE_TAG_MASK) >> L2_DC_LINE_TAG_SHFT;
276  cache_affinity->cache_line_size =
277  (l2_cache_ids & L2_DC_LINE_SIZE_MASK) >> L2_DC_LINE_SIZE_SHFT;
278  cache_affinity->associativity = get_associativity(
279  (l2_cache_ids & L2_DC_ASSOC_MASK) >> L2_DC_ASSOC_SHFT);
280  cache_affinity->cache_latency = 1;
281  }
282 
283  /* L3 cache */
284  if (thread % num_threads_sharing3 == 0) {
285  current = add_crat_cache_entry(&cache_affinity, current);
286  new_entries++;
287 
288  cache_affinity->flags |=
290  cache_affinity->proc_id_low = thread;
291  sibling_mask = 1;
292  for (size_t sibling = 1; sibling < num_threads_sharing3; sibling++)
293  sibling_mask = (sibling_mask << 1) + 1;
294  cache_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
295  cache_affinity->cache_properties =
296  (cache_props0.edx & CACHE_INCLUSIVE_MASK) ? 2 : 0;
297  cache_affinity->cache_size =
298  ((l3_cache_ids & L3_DC_SIZE_MASK) >> L3_DC_SIZE_SHFT) * 512;
299  cache_affinity->cache_level = CRAT_L3_CACHE;
300  cache_affinity->lines_per_tag =
301  (l3_cache_ids & L3_DC_LINE_TAG_MASK) >> L3_DC_LINE_TAG_SHFT;
302  cache_affinity->cache_line_size =
303  (l3_cache_ids & L3_DC_LINE_SIZE_MASK) >> L3_DC_LINE_SIZE_SHFT;
304  cache_affinity->associativity = get_associativity(
305  (l3_cache_ids & L3_DC_ASSOC_MASK) >> L3_DC_ASSOC_SHFT);
306  cache_affinity->cache_latency = 1;
307  }
308  }
309  crat->total_entries += new_entries;
310  return current;
311 }
312 
313 static uint8_t get_tlb_size(enum tlb_type type, struct crat_tlb *crat_tlb_entry,
314  uint16_t raw_assoc_size)
315 {
316  uint8_t tlbsize;
317 
318  if (raw_assoc_size >= 256) {
319  tlbsize = (uint8_t)(raw_assoc_size / 256);
320 
321  if (type == tlb_2m)
322  crat_tlb_entry->flags |= CRAT_TLB_FLAG_2MB_BASE_256;
323  else if (type == tlb_4k)
324  crat_tlb_entry->flags |= CRAT_TLB_FLAG_4K_BASE_256;
325  else if (type == tlb_1g)
326  crat_tlb_entry->flags |= CRAT_TLB_FLAG_1GB_BASE_256;
327  } else {
328  tlbsize = (uint8_t)(raw_assoc_size);
329  }
330  return tlbsize;
331 }
332 
333 static unsigned long add_crat_tlb_entry(struct crat_tlb **tlb_affinity, unsigned long current)
334 {
335  *tlb_affinity = (struct crat_tlb *)current;
336  memset(*tlb_affinity, 0, sizeof(struct crat_tlb));
337 
338  (*tlb_affinity)->type = CRAT_TLB_TYPE;
339  (*tlb_affinity)->length = sizeof(struct crat_tlb);
340  (*tlb_affinity)->flags = CRAT_TLB_FLAG_EN | CRAT_TLB_FLAG_CPU_TLB;
341 
342  current += sizeof(struct crat_tlb);
343  return current;
344 }
345 
346 static unsigned long gen_crat_tlb_entry(struct acpi_crat_header *crat, unsigned long current)
347 {
348  size_t total_num_threads, num_threads_sharing0, num_threads_sharing1,
349  num_threads_sharing2, thread, new_entries;
350  struct cpuid_result cache_props0, cache_props1, cache_props2;
351  uint8_t sibling_mask = 0;
352  uint32_t l1_tlb_2M4M_ids, l1_tlb_4K_ids, l2_tlb_2M4M_ids, l2_tlb_4K_ids, l1_tlb_1G_ids,
353  l2_tlb_1G_ids;
354  struct crat_tlb *tlb_affinity = NULL;
355 
356  total_num_threads = get_cpu_count();
357  cache_props0 = cpuid_ext(CPUID_CACHE_PROPS, CACHE_PROPS_0);
358  cache_props1 = cpuid_ext(CPUID_CACHE_PROPS, CACHE_PROPS_1);
359  cache_props2 = cpuid_ext(CPUID_CACHE_PROPS, CACHE_PROPS_2);
360 
361  l1_tlb_2M4M_ids = cpuid_eax(CPUID_L1_TLB_CACHE_IDS);
362  l2_tlb_2M4M_ids = cpuid_eax(CPUID_L2_L3_CACHE_L2_TLB_IDS);
363  l1_tlb_4K_ids = cpuid_ebx(CPUID_L1_TLB_CACHE_IDS);
364  l2_tlb_4K_ids = cpuid_ebx(CPUID_L2_L3_CACHE_L2_TLB_IDS);
365  l1_tlb_1G_ids = cpuid_eax(CPUID_TLB_L1L2_1G_IDS);
366  l2_tlb_1G_ids = cpuid_ebx(CPUID_TLB_L1L2_1G_IDS);
367 
368  num_threads_sharing0 =
369  ((cache_props0.eax & NUM_SHARE_CACHE_MASK) >> NUM_SHARE_CACHE_SHFT) + 1;
370  num_threads_sharing1 =
371  ((cache_props1.eax & NUM_SHARE_CACHE_MASK) >> NUM_SHARE_CACHE_SHFT) + 1;
372  num_threads_sharing2 =
373  ((cache_props2.eax & NUM_SHARE_CACHE_MASK) >> NUM_SHARE_CACHE_SHFT) + 1;
374 
375  new_entries = 0;
376  for (thread = 0; thread < total_num_threads; thread++) {
377 
378  /* L1 data TLB */
379  if (thread % num_threads_sharing0 == 0) {
380  current = add_crat_tlb_entry(&tlb_affinity, current);
381  new_entries++;
382 
383  tlb_affinity->flags |= CRAT_TLB_FLAG_DATA_TLB;
384  tlb_affinity->proc_id_low = thread;
385  sibling_mask = 1;
386  for (size_t sibling = 1; sibling < num_threads_sharing0; sibling++)
387  sibling_mask = (sibling_mask << 1) + 1;
388  tlb_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
389  tlb_affinity->tlb_level = CRAT_L1_CACHE;
390 
391  tlb_affinity->data_tlb_2mb_assoc =
392  (l1_tlb_2M4M_ids & L1_DAT_TLB_2M4M_ASSOC_MASK)
394  tlb_affinity->data_tlb_2mb_size =
395  get_tlb_size(tlb_2m, tlb_affinity,
396  (l1_tlb_2M4M_ids & L1_DAT_TLB_2M4M_SIZE_MASK)
398 
399  tlb_affinity->data_tlb_4k_assoc =
400  (l1_tlb_4K_ids & L1_DAT_TLB_4K_ASSOC_MASK)
402  tlb_affinity->data_tlb_4k_size =
403  get_tlb_size(tlb_4k, tlb_affinity,
404  (l1_tlb_4K_ids & L1_DAT_TLB_4K_SIZE_MASK)
406 
407  tlb_affinity->data_tlb_1g_assoc =
408  (l1_tlb_1G_ids & L1_DAT_TLB_1G_ASSOC_MASK)
410  tlb_affinity->data_tlb_1g_size =
411  get_tlb_size(tlb_1g, tlb_affinity,
412  (l1_tlb_1G_ids & L1_DAT_TLB_1G_SIZE_MASK)
414  }
415 
416  /* L1 instruction TLB */
417  if (thread % num_threads_sharing1 == 0) {
418  current = add_crat_tlb_entry(&tlb_affinity, current);
419  new_entries++;
420 
421  tlb_affinity->flags |= CRAT_TLB_FLAG_INSTR_TLB;
422  tlb_affinity->proc_id_low = thread;
423  sibling_mask = 1;
424  for (size_t sibling = 1; sibling < num_threads_sharing1; sibling++)
425  sibling_mask = (sibling_mask << 1) + 1;
426  tlb_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
427  tlb_affinity->tlb_level = CRAT_L1_CACHE;
428  tlb_affinity->instr_tlb_2mb_assoc =
429  (l1_tlb_2M4M_ids & L1_INST_TLB_2M4M_ASSOC_MASK)
431  tlb_affinity->instr_tlb_2mb_size =
432  get_tlb_size(tlb_2m, tlb_affinity,
433  (l1_tlb_2M4M_ids & L1_INST_TLB_2M4M_SIZE_MASK)
435 
436  tlb_affinity->instr_tlb_4k_assoc =
437  (l1_tlb_4K_ids & L1_INST_TLB_4K_ASSOC_MASK)
439  tlb_affinity->instr_tlb_4k_size =
440  get_tlb_size(tlb_4k, tlb_affinity,
441  (l1_tlb_4K_ids & L1_INST_TLB_4K_SIZE_MASK)
443 
444  tlb_affinity->instr_tlb_1g_assoc =
445  (l1_tlb_1G_ids & L1_INST_TLB_1G_ASSOC_MASK)
447  tlb_affinity->instr_tlb_1g_size =
448  get_tlb_size(tlb_1g, tlb_affinity,
449  (l1_tlb_1G_ids & L1_INST_TLB_1G_SIZE_MASK)
451  }
452 
453  /* L2 Data TLB */
454  if (thread % num_threads_sharing2 == 0) {
455  current = add_crat_tlb_entry(&tlb_affinity, current);
456  new_entries++;
457 
458  tlb_affinity->flags |= CRAT_TLB_FLAG_DATA_TLB;
459  tlb_affinity->proc_id_low = thread;
460  sibling_mask = 1;
461  for (size_t sibling = 1; sibling < num_threads_sharing2; sibling++)
462  sibling_mask = (sibling_mask << 1) + 1;
463  tlb_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
464  tlb_affinity->tlb_level = CRAT_L2_CACHE;
465  tlb_affinity->data_tlb_2mb_assoc =
466  (l2_tlb_2M4M_ids & L2_DAT_TLB_2M4M_ASSOC_MASK)
468  tlb_affinity->data_tlb_2mb_size =
469  get_tlb_size(tlb_2m, tlb_affinity,
470  (l2_tlb_2M4M_ids & L2_DAT_TLB_2M4M_SIZE_MASK)
472 
473  tlb_affinity->data_tlb_4k_assoc =
476  tlb_affinity->data_tlb_4k_size =
477  get_tlb_size(tlb_4k, tlb_affinity,
478  (l2_tlb_2M4M_ids & L2_DAT_TLB_4K_SIZE_MASK)
480 
481  tlb_affinity->data_tlb_1g_assoc =
484  tlb_affinity->data_tlb_1g_size =
485  get_tlb_size(tlb_1g, tlb_affinity,
486  (l2_tlb_1G_ids & L2_DAT_TLB_1G_SIZE_MASK)
488  }
489 
490  /* L2 Instruction TLB */
491  if (thread % num_threads_sharing2 == 0) {
492  current = add_crat_tlb_entry(&tlb_affinity, current);
493  new_entries++;
494 
495  tlb_affinity->flags |= CRAT_TLB_FLAG_INSTR_TLB;
496  tlb_affinity->proc_id_low = thread;
497  sibling_mask = 1;
498  for (size_t sibling = 1; sibling < num_threads_sharing2; sibling++)
499  sibling_mask = (sibling_mask << 1) + 1;
500  tlb_affinity->sibling_map[thread / 8] = sibling_mask << (thread % 8);
501  tlb_affinity->tlb_level = CRAT_L2_CACHE;
502  tlb_affinity->instr_tlb_2mb_assoc = get_associativity(
503  (l2_tlb_2M4M_ids & L2_INST_TLB_2M4M_ASSOC_MASK)
505  tlb_affinity->instr_tlb_2mb_size =
506  get_tlb_size(tlb_2m, tlb_affinity,
507  (l2_tlb_2M4M_ids & L2_INST_TLB_2M4M_SIZE_MASK)
509 
510  tlb_affinity->instr_tlb_4k_assoc =
513  tlb_affinity->instr_tlb_4k_size =
514  get_tlb_size(tlb_4k, tlb_affinity,
515  (l2_tlb_4K_ids & L2_INST_TLB_4K_SIZE_MASK)
517 
518  tlb_affinity->instr_tlb_1g_assoc =
521  tlb_affinity->instr_tlb_1g_size =
522  get_tlb_size(tlb_1g, tlb_affinity,
523  (l2_tlb_1G_ids & L2_INST_TLB_1G_SIZE_MASK)
525  }
526  }
527 
528  crat->total_entries += new_entries;
529  return current;
530 }
531 
532 static unsigned long acpi_fill_crat(struct acpi_crat_header *crat, unsigned long current)
533 {
534  current = gen_crat_hsa_entry(crat, current);
535  current = gen_crat_memory_entries(crat, current);
536  current = gen_crat_cache_entry(crat, current);
537  current = gen_crat_tlb_entry(crat, current);
538  crat->num_nodes++;
539 
540  return current;
541 }
542 
544  acpi_rsdp_t *rsdp)
545 {
546  acpi_ivrs_t *ivrs;
547  struct acpi_crat_header *crat;
548 
549  /* CRAT */
550  current = ALIGN(current, 8);
551  crat = (struct acpi_crat_header *)current;
553  current += crat->header.length;
554  acpi_add_table(rsdp, crat);
555 
556  /* add ALIB SSDT from HOB */
557  current = add_agesa_fsp_acpi_table(AMD_FSP_ACPI_ALIB_HOB_GUID, "ALIB", rsdp, current);
558 
559  /* IVRS */
560  current = ALIGN(current, 8);
561  ivrs = (acpi_ivrs_t *) current;
563  current += ivrs->header.length;
564  acpi_add_table(rsdp, ivrs);
565 
566  /* Add SRAT, MSCT, SLIT if needed in the future */
567 
568  return current;
569 }
void acpi_create_ivrs(acpi_ivrs_t *ivrs, unsigned long(*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct, unsigned long current))
Definition: acpi.c:1083
void acpi_add_table(acpi_rsdp_t *rsdp, void *table)
Add an ACPI table to the RSDT (and XSDT) structure, recalculate length and checksum.
Definition: acpi.c:49
void acpi_create_crat(struct acpi_crat_header *crat, unsigned long(*acpi_fill_crat)(struct acpi_crat_header *crat_struct, unsigned long current))
Definition: acpi.c:1112
#define CRAT_TLB_FLAG_1GB_BASE_256
Definition: acpi_crat.h:140
#define CRAT_TLB_FLAG_2MB_BASE_256
Definition: acpi_crat.h:138
#define CRAT_CACHE_FLAG_CPU_CACHE
Definition: acpi_crat.h:92
#define CRAT_L2_CACHE
Definition: acpi_crat.h:58
#define CRAT_HSA_PR_FLAG_CPU_PRES
Definition: acpi_crat.h:21
@ CRAT_CACHE_TYPE
Definition: acpi_crat.h:9
@ CRAT_MEMORY_TYPE
Definition: acpi_crat.h:8
@ CRAT_TLB_TYPE
Definition: acpi_crat.h:10
tlb_type
Definition: acpi_crat.h:118
@ tlb_2m
Definition: acpi_crat.h:119
@ tlb_1g
Definition: acpi_crat.h:121
@ tlb_4k
Definition: acpi_crat.h:120
#define CRAT_L1_CACHE
Definition: acpi_crat.h:57
#define CRAT_TLB_FLAG_EN
Definition: acpi_crat.h:126
#define CRAT_MEM_FLAG_EN
Definition: acpi_crat.h:62
#define CRAT_L3_CACHE
Definition: acpi_crat.h:59
#define CRAT_TLB_FLAG_CPU_TLB
Definition: acpi_crat.h:132
#define CRAT_CACHE_FLAG_EN
Definition: acpi_crat.h:86
#define CRAT_TLB_FLAG_INSTR_TLB
Definition: acpi_crat.h:130
#define CRAT_TLB_FLAG_DATA_TLB
Definition: acpi_crat.h:128
#define CRAT_HSA_PR_FLAG_EN
Definition: acpi_crat.h:17
#define CRAT_CACHE_FLAG_DATA_CACHE
Definition: acpi_crat.h:88
#define CRAT_CACHE_FLAG_INSTR_CACHE
Definition: acpi_crat.h:90
#define CRAT_TLB_FLAG_4K_BASE_256
Definition: acpi_crat.h:136
static unsigned int cpuid_edx(unsigned int op)
Definition: cpu.h:119
static unsigned int cpuid_ecx(unsigned int op)
Definition: cpu.h:106
static unsigned int cpuid_eax(unsigned int op)
Definition: cpu.h:79
static unsigned int cpuid_ebx(unsigned int op)
Definition: cpu.h:92
static struct cpuid_result cpuid_ext(int op, unsigned int ecx)
Definition: cpu.h:59
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
#define MiB
Definition: helpers.h:76
uintptr_t agesa_write_acpi_tables(const struct device *device, uintptr_t current, acpi_rsdp_t *rsdp)
Definition: agesa_acpi.c:10
#define IOMS0_FABRIC_ID
Definition: data_fabric.h:11
#define L1_DAT_TLB_4K_SIZE_MASK
Definition: cpuid.h:25
#define L1_DAT_TLB_2M4M_ASSOC_SHFT
Definition: cpuid.h:13
#define L2_DAT_TLB_1G_SIZE_SHFT
Definition: cpuid.h:103
#define L2_DC_LINE_TAG_MASK
Definition: cpuid.h:74
#define L2_DC_ASSOC_MASK
Definition: cpuid.h:72
#define L1_INST_TLB_2M4M_SIZE_SHFT
Definition: cpuid.h:19
#define L3_DC_SIZE_MASK
Definition: cpuid.h:79
#define L1_INST_TLB_4K_ASSOC_SHFT
Definition: cpuid.h:26
#define L2_DAT_TLB_2M4M_ASSOC_MASK
Definition: cpuid.h:52
#define L3_DC_ASSOC_MASK
Definition: cpuid.h:81
#define CACHE_PROPS_0
Definition: cpuid.h:111
#define L2_INST_TLB_4K_ASSOC_MASK
Definition: cpuid.h:65
#define CPUID_TLB_L1L2_1G_IDS
Definition: cpuid.h:90
#define L1_DAT_TLB_4K_ASSOC_SHFT
Definition: cpuid.h:22
#define CACHE_PROPS_2
Definition: cpuid.h:113
#define L1_INST_TLB_1G_SIZE_SHFT
Definition: cpuid.h:98
#define L2_INST_TLB_1G_ASSOC_SHFT
Definition: cpuid.h:105
#define L2_INST_TLB_2M4M_SIZE_MASK
Definition: cpuid.h:58
#define L1_INST_TLB_2M4M_SIZE_MASK
Definition: cpuid.h:20
#define L1_INST_TLB_4K_SIZE_SHFT
Definition: cpuid.h:28
#define L1_IC_ASSOC_SHFT
Definition: cpuid.h:42
#define L1_DAT_TLB_1G_ASSOC_MASK
Definition: cpuid.h:93
#define L1_INST_TLB_1G_ASSOC_SHFT
Definition: cpuid.h:96
#define L2_DAT_TLB_2M4M_SIZE_SHFT
Definition: cpuid.h:53
#define L2_DC_SIZE_MASK
Definition: cpuid.h:70
#define L1_INST_TLB_4K_ASSOC_MASK
Definition: cpuid.h:27
#define L1_DC_LINE_SIZE_SHFT
Definition: cpuid.h:37
#define L2_DAT_TLB_1G_ASSOC_MASK
Definition: cpuid.h:102
#define L1_INST_TLB_2M4M_ASSOC_SHFT
Definition: cpuid.h:17
#define L1_IC_SIZE_MASK
Definition: cpuid.h:41
#define L1_DAT_TLB_2M4M_SIZE_MASK
Definition: cpuid.h:16
#define L2_INST_TLB_2M4M_SIZE_SHFT
Definition: cpuid.h:57
#define L3_DC_LINE_TAG_SHFT
Definition: cpuid.h:82
#define L1_DC_ASSOC_SHFT
Definition: cpuid.h:33
#define L2_DC_LINE_SIZE_MASK
Definition: cpuid.h:76
#define L3_DC_LINE_SIZE_MASK
Definition: cpuid.h:85
#define L3_DC_LINE_SIZE_SHFT
Definition: cpuid.h:84
#define L1_DAT_TLB_4K_SIZE_SHFT
Definition: cpuid.h:24
#define L1_DC_ASSOC_MASK
Definition: cpuid.h:34
#define CPUID_CACHE_PROPS
Definition: cpuid.h:110
#define L1_DC_SIZE_SHFT
Definition: cpuid.h:31
#define L1_DAT_TLB_4K_ASSOC_MASK
Definition: cpuid.h:23
#define CACHE_INCLUSIVE_MASK
Definition: cpuid.h:118
#define L1_IC_LINE_SIZE_SHFT
Definition: cpuid.h:46
#define L2_DC_LINE_TAG_SHFT
Definition: cpuid.h:73
#define NUM_SHARE_CACHE_SHFT
Definition: cpuid.h:115
#define L1_IC_ASSOC_MASK
Definition: cpuid.h:43
#define L2_DC_SIZE_SHFT
Definition: cpuid.h:69
#define L2_DC_ASSOC_SHFT
Definition: cpuid.h:71
#define L1_INST_TLB_1G_ASSOC_MASK
Definition: cpuid.h:97
#define L2_INST_TLB_4K_SIZE_SHFT
Definition: cpuid.h:66
#define L1_INST_TLB_2M4M_ASSOC_MASK
Definition: cpuid.h:18
#define L2_DAT_TLB_1G_SIZE_MASK
Definition: cpuid.h:104
#define L2_DAT_TLB_4K_ASSOC_SHFT
Definition: cpuid.h:60
#define L1_IC_LINE_SIZE_MASK
Definition: cpuid.h:47
#define L1_DAT_TLB_1G_SIZE_SHFT
Definition: cpuid.h:94
#define L2_DAT_TLB_2M4M_ASSOC_SHFT
Definition: cpuid.h:51
#define L2_DAT_TLB_4K_SIZE_MASK
Definition: cpuid.h:63
#define L1_IC_LINE_TAG_MASK
Definition: cpuid.h:45
#define L2_INST_TLB_1G_SIZE_SHFT
Definition: cpuid.h:107
#define CACHE_PROPS_3
Definition: cpuid.h:114
#define L1_DC_LINE_TAG_MASK
Definition: cpuid.h:36
#define CPUID_L2_L3_CACHE_L2_TLB_IDS
Definition: cpuid.h:49
#define CPUID_L1_TLB_CACHE_IDS
Definition: cpuid.h:11
#define L1_DAT_TLB_1G_SIZE_MASK
Definition: cpuid.h:95
#define L2_INST_TLB_1G_SIZE_MASK
Definition: cpuid.h:108
#define L3_DC_ASSOC_SHFT
Definition: cpuid.h:80
#define L3_DC_LINE_TAG_MASK
Definition: cpuid.h:83
#define L1_DC_LINE_TAG_SHFT
Definition: cpuid.h:35
#define L2_INST_TLB_4K_SIZE_MASK
Definition: cpuid.h:67
#define L1_DAT_TLB_2M4M_SIZE_SHFT
Definition: cpuid.h:15
#define L2_DAT_TLB_4K_SIZE_SHFT
Definition: cpuid.h:62
#define L2_DAT_TLB_1G_ASSOC_SHFT
Definition: cpuid.h:101
#define L1_IC_LINE_TAG_SHFT
Definition: cpuid.h:44
#define L2_INST_TLB_2M4M_ASSOC_MASK
Definition: cpuid.h:56
#define L2_DC_LINE_SIZE_SHFT
Definition: cpuid.h:75
#define L1_INST_TLB_4K_SIZE_MASK
Definition: cpuid.h:29
#define L2_INST_TLB_2M4M_ASSOC_SHFT
Definition: cpuid.h:55
#define L1_INST_TLB_1G_SIZE_MASK
Definition: cpuid.h:99
#define L2_DAT_TLB_2M4M_SIZE_MASK
Definition: cpuid.h:54
#define L2_INST_TLB_4K_ASSOC_SHFT
Definition: cpuid.h:64
#define L2_INST_TLB_1G_ASSOC_MASK
Definition: cpuid.h:106
#define L1_DC_LINE_SIZE_MASK
Definition: cpuid.h:38
#define L1_IC_SIZE_SHFT
Definition: cpuid.h:40
#define L1_DAT_TLB_1G_ASSOC_SHFT
Definition: cpuid.h:92
#define CACHE_PROPS_1
Definition: cpuid.h:112
#define NUM_SHARE_CACHE_MASK
Definition: cpuid.h:116
#define L1_DAT_TLB_2M4M_ASSOC_MASK
Definition: cpuid.h:14
#define L1_DC_SIZE_MASK
Definition: cpuid.h:32
#define L3_DC_SIZE_SHFT
Definition: cpuid.h:78
uint32_t data_fabric_read32(uint8_t function, uint16_t reg, uint8_t instance_id)
static int get_cpu_count(void)
Definition: haswell_init.c:584
#define ALIGN
Definition: asm.h:22
unsigned int type
Definition: edid.c:57
static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current)
Definition: northbridge.c:467
static unsigned long gen_crat_cache_entry(struct acpi_crat_header *crat, unsigned long current)
Definition: agesa_acpi.c:171
static unsigned long acpi_fill_crat(struct acpi_crat_header *crat, unsigned long current)
Definition: agesa_acpi.c:532
static unsigned long add_crat_tlb_entry(struct crat_tlb **tlb_affinity, unsigned long current)
Definition: agesa_acpi.c:333
static unsigned long gen_crat_hsa_entry(struct acpi_crat_header *crat, unsigned long current)
Definition: agesa_acpi.c:23
static unsigned long create_crat_memory_entry(uint32_t domain, uint64_t region_base, uint64_t region_size, unsigned long current)
Definition: agesa_acpi.c:38
static uint8_t get_tlb_size(enum tlb_type type, struct crat_tlb *crat_tlb_entry, uint16_t raw_assoc_size)
Definition: agesa_acpi.c:313
static uint8_t get_associativity(uint32_t encoded_associativity)
Definition: agesa_acpi.c:126
static unsigned long add_crat_cache_entry(struct crat_cache **cache_affinity, unsigned long current)
Definition: agesa_acpi.c:112
static unsigned long gen_crat_tlb_entry(struct acpi_crat_header *crat, unsigned long current)
Definition: agesa_acpi.c:346
static unsigned long gen_crat_memory_entries(struct acpi_crat_header *crat, unsigned long current)
Definition: agesa_acpi.c:58
#define DF_DRAM_LIMIT(dram_map_pair)
Definition: data_fabric.h:49
#define PICASSO_NUM_DRAM_REG
Definition: data_fabric.h:45
#define DRAM_HOLE_CTL_BASE
Definition: data_fabric.h:23
#define D18F0_DRAM_HOLE_CTL
Definition: data_fabric.h:20
#define DRAM_BASE_ADDR
Definition: data_fabric.h:33
#define DRAM_BASE_REG_VALID
Definition: data_fabric.h:26
#define DRAM_LIMIT_ADDR
Definition: data_fabric.h:43
#define DRAM_BASE_HOLE_EN
Definition: data_fabric.h:27
#define DRAM_BASE_ADDR_SHFT
Definition: data_fabric.h:32
#define DRAM_LIMIT_ADDR_SHFT
Definition: data_fabric.h:42
#define DF_DRAM_BASE(dram_map_pair)
Definition: data_fabric.h:47
uintptr_t add_agesa_fsp_acpi_table(guid_t guid, const char *name, acpi_rsdp_t *rsdp, uintptr_t current)
Definition: fsp-acpi.c:18
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
unsigned long long uint64_t
Definition: stdint.h:17
unsigned char uint8_t
Definition: stdint.h:8
uint32_t total_entries
Definition: acpi.h:453
acpi_header_t header
Definition: acpi.h:452
uint16_t num_nodes
Definition: acpi.h:454
acpi_header_t header
Definition: acpi.h:444
Definition: acpi.h:82
uint32_t edx
Definition: cpu.h:33
uint32_t eax
Definition: cpu.h:30
uint32_t cache_size
Definition: acpi_crat.h:108
uint8_t cache_level
Definition: acpi_crat.h:109
uint32_t flags
Definition: acpi_crat.h:105
uint16_t cache_line_size
Definition: acpi_crat.h:111
uint16_t cache_latency
Definition: acpi_crat.h:114
uint8_t lines_per_tag
Definition: acpi_crat.h:110
uint8_t cache_properties
Definition: acpi_crat.h:113
uint8_t sibling_map[32]
Definition: acpi_crat.h:107
uint32_t proc_id_low
Definition: acpi_crat.h:106
uint8_t associativity
Definition: acpi_crat.h:112
uint32_t width
Definition: acpi_crat.h:81
uint32_t base_address_low
Definition: acpi_crat.h:77
uint8_t type
Definition: acpi_crat.h:72
uint32_t flags
Definition: acpi_crat.h:75
uint8_t length
Definition: acpi_crat.h:73
uint32_t proximity_domain
Definition: acpi_crat.h:76
uint32_t base_address_high
Definition: acpi_crat.h:78
uint32_t length_high
Definition: acpi_crat.h:80
uint32_t length_low
Definition: acpi_crat.h:79
uint8_t data_tlb_4k_assoc
Definition: acpi_crat.h:155
uint32_t tlb_level
Definition: acpi_crat.h:150
uint8_t data_tlb_2mb_assoc
Definition: acpi_crat.h:151
uint8_t instr_tlb_1g_assoc
Definition: acpi_crat.h:161
uint8_t data_tlb_4k_size
Definition: acpi_crat.h:156
uint8_t sibling_map[32]
Definition: acpi_crat.h:149
uint32_t proc_id_low
Definition: acpi_crat.h:148
uint8_t data_tlb_1g_size
Definition: acpi_crat.h:160
uint8_t instr_tlb_2mb_assoc
Definition: acpi_crat.h:153
uint8_t data_tlb_2mb_size
Definition: acpi_crat.h:152
uint8_t instr_tlb_2mb_size
Definition: acpi_crat.h:154
uint8_t instr_tlb_4k_assoc
Definition: acpi_crat.h:157
uint8_t instr_tlb_1g_size
Definition: acpi_crat.h:162
uint8_t instr_tlb_4k_size
Definition: acpi_crat.h:158
uint8_t data_tlb_1g_assoc
Definition: acpi_crat.h:159
uint32_t flags
Definition: acpi_crat.h:147
Definition: device.h:107