coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
northbridge.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/pci_ops.h>
5 #include <acpi/acpi.h>
6 #include <acpi/acpigen.h>
7 #include <stdint.h>
8 #include <device/device.h>
9 #include <device/pci.h>
10 #include <device/pci_ids.h>
11 #include <string.h>
12 #include <lib.h>
13 #include <cpu/cpu.h>
14 #include <AGESA.h>
15 #include <cpu/x86/lapic.h>
16 #include <cpu/amd/msr.h>
17 #include <cpu/amd/mtrr.h>
18 #include <Porting.h>
19 #include <Options.h>
20 #include <Topology.h>
24 
25 #define MAX_NODE_NUMS MAX_NODES
26 
27 static unsigned int node_nums;
28 static unsigned int sblink;
29 static struct device *__f0_dev[MAX_NODE_NUMS];
30 static struct device *__f1_dev[MAX_NODE_NUMS];
31 static struct device *__f2_dev[MAX_NODE_NUMS];
32 static struct device *__f4_dev[MAX_NODE_NUMS];
33 static unsigned int fx_devs = 0;
34 
35 static void set_io_addr_reg(struct device *dev, u32 nodeid, u32 linkn, u32 reg,
36  u32 io_min, u32 io_max)
37 {
38  u32 i;
39  u32 tempreg;
40  /* io range allocation */
41  tempreg = (nodeid&0xf) | ((nodeid & 0x30)<<(8-4)) | (linkn << 4) | ((io_max&0xf0)<<(12-4)); //limit
42  for (i = 0; i < node_nums; i++)
43  pci_write_config32(__f1_dev[i], reg+4, tempreg);
44  tempreg = 3 /*| (3 << 4)*/ | ((io_min&0xf0)<<(12-4)); //base :ISA and VGA ?
45  for (i = 0; i < node_nums; i++)
46  pci_write_config32(__f1_dev[i], reg, tempreg);
47 }
48 
49 static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index, u32 mmio_min, u32 mmio_max, u32 nodes)
50 {
51  u32 i;
52  u32 tempreg;
53  /* io range allocation */
54  tempreg = (nodeid&0xf) | (linkn << 4) | (mmio_max&0xffffff00); //limit
55  for (i = 0; i < nodes; i++)
56  pci_write_config32(__f1_dev[i], reg+4, tempreg);
57  tempreg = 3 | (nodeid & 0x30) | (mmio_min&0xffffff00);
58  for (i = 0; i < node_nums; i++)
59  pci_write_config32(__f1_dev[i], reg, tempreg);
60 }
61 
62 static struct device *get_node_pci(u32 nodeid, u32 fn)
63 {
64  return pcidev_on_root(DEV_CDB + nodeid, fn);
65 }
66 
67 static void get_fx_devs(void)
68 {
69  int i;
70  for (i = 0; i < MAX_NODE_NUMS; i++) {
71  __f0_dev[i] = get_node_pci(i, 0);
72  __f1_dev[i] = get_node_pci(i, 1);
73  __f2_dev[i] = get_node_pci(i, 2);
74  __f4_dev[i] = get_node_pci(i, 4);
75  if (__f0_dev[i] != NULL && __f1_dev[i] != NULL)
76  fx_devs = i+1;
77  }
78  if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) {
79  die("Cannot find 0:0x18.[0|1]\n");
80  }
81  printk(BIOS_DEBUG, "fx_devs=0x%x\n", fx_devs);
82 }
83 
84 static u32 f1_read_config32(unsigned int reg)
85 {
86  if (fx_devs == 0)
87  get_fx_devs();
88  return pci_read_config32(__f1_dev[0], reg);
89 }
90 
91 static void f1_write_config32(unsigned int reg, u32 value)
92 {
93  int i;
94  if (fx_devs == 0)
95  get_fx_devs();
96  for (i = 0; i < fx_devs; i++) {
97  struct device *dev;
98  dev = __f1_dev[i];
99  if (dev && dev->enabled) {
100  pci_write_config32(dev, reg, value);
101  }
102  }
103 }
104 
105 static int get_dram_base_limit(u32 nodeid, resource_t *basek, resource_t *limitk)
106 {
107  u32 temp;
108 
109  if (fx_devs == 0)
110  get_fx_devs();
111 
112 
113  temp = pci_read_config32(__f1_dev[nodeid], 0x40 + (nodeid << 3)); //[39:24] at [31:16]
114  if (!(temp & 1))
115  return 0; // this memory range is not enabled
116  /*
117  * BKDG: {DramBase[47:24], 00_0000h} <= address[47:0] so shift left by 8 bits
118  * for physical address and the convert to KiB by shifting 10 bits left
119  */
120  *basek = ((temp & 0xffff0000)) >> (10 - 8);
121  /* Now high bits [47:40] */
122  temp = pci_read_config32(__f1_dev[nodeid], 0x140 + (nodeid << 3)); //[47:40] at [7:0]
123  *basek = *basek | ((resource_t)temp << (40 - 10));
124  /*
125  * BKDG address[39:0] <= {DramLimit[47:24], FF_FFFFh} converted as above but
126  * ORed with 0xffff to get real limit before shifting.
127  */
128  temp = pci_read_config32(__f1_dev[nodeid], 0x44 + (nodeid << 3)); //[39:24] at [31:16]
129  *limitk = ((temp & 0xffff0000) | 0xffff) >> (10 - 8);
130  /* Now high bits [47:40] */
131  temp = pci_read_config32(__f1_dev[nodeid], 0x144 + (nodeid << 3)); //[47:40] at [7:0]
132  *limitk = *limitk | ((resource_t)temp << (40 - 10));
133  *limitk += 1; // round up last byte
134 
135  return 1;
136 }
137 
138 static u32 amdfam15_nodeid(struct device *dev)
139 {
140  return (dev->path.pci.devfn >> 3) - DEV_CDB;
141 }
142 
143 static void set_vga_enable_reg(u32 nodeid, u32 linkn)
144 {
145  u32 val;
146 
147  val = 1 | (nodeid << 4) | (linkn << 12);
148  /* it will routing
149  * (1)mmio 0xa0000:0xbffff
150  * (2)io 0x3b0:0x3bb, 0x3c0:0x3df
151  */
152  f1_write_config32(0xf4, val);
153 
154 }
155 
156 /**
157  * @return
158  * @retval 2 resource does not exist, usable
159  * @retval 0 resource exists, not usable
160  * @retval 1 resource exist, resource has been allocated before
161  */
162 static int reg_useable(unsigned int reg, struct device *goal_dev,
163  unsigned int goal_nodeid, unsigned int goal_link)
164 {
165  struct resource *res;
166  unsigned int nodeid, link = 0;
167  int result;
168  res = 0;
169  for (nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
170  struct device *dev;
171  dev = __f0_dev[nodeid];
172  if (!dev)
173  continue;
174  for (link = 0; !res && (link < 8); link++) {
175  res = probe_resource(dev, IOINDEX(0x1000 + reg, link));
176  }
177  }
178  result = 2;
179  if (res) {
180  result = 0;
181  if ((goal_link == (link - 1)) &&
182  (goal_nodeid == (nodeid - 1)) &&
183  (res->flags <= 1)) {
184  result = 1;
185  }
186  }
187  return result;
188 }
189 
190 static struct resource *amdfam15_find_iopair(struct device *dev,
191  unsigned int nodeid, unsigned int link)
192 {
193  struct resource *resource;
194  u32 free_reg, reg;
195  resource = 0;
196  free_reg = 0;
197  for (reg = 0xc0; reg <= 0xd8; reg += 0x8) {
198  int result;
199  result = reg_useable(reg, dev, nodeid, link);
200  if (result == 1) {
201  /* I have been allocated this one */
202  break;
203  }
204  else if (result > 1) {
205  /* I have a free register pair */
206  free_reg = reg;
207  }
208  }
209  if (reg > 0xd8) {
210  reg = free_reg; // if no free, the free_reg still be 0
211  }
212 
213  resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
214 
215  return resource;
216 }
217 
218 static struct resource *amdfam15_find_mempair(struct device *dev, u32 nodeid, u32 link)
219 {
220  struct resource *resource;
221  u32 free_reg, reg;
222  resource = 0;
223  free_reg = 0;
224  for (reg = 0x80; reg <= 0xb8; reg += 0x8) {
225  int result;
226  result = reg_useable(reg, dev, nodeid, link);
227  if (result == 1) {
228  /* I have been allocated this one */
229  break;
230  }
231  else if (result > 1) {
232  /* I have a free register pair */
233  free_reg = reg;
234  }
235  }
236  if (reg > 0xb8) {
237  reg = free_reg;
238  }
239 
240  resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
241  return resource;
242 }
243 
244 static void amdfam15_link_read_bases(struct device *dev, u32 nodeid, u32 link)
245 {
246  struct resource *resource;
247 
248  /* Initialize the io space constraints on the current bus */
249  resource = amdfam15_find_iopair(dev, nodeid, link);
250  if (resource) {
251  u32 align;
253  resource->base = 0;
254  resource->size = 0;
255  resource->align = align;
256  resource->gran = align;
257  resource->limit = 0xffffUL;
259  }
260 
261  /* Initialize the prefetchable memory constraints on the current bus */
262  resource = amdfam15_find_mempair(dev, nodeid, link);
263  if (resource) {
264  resource->base = 0;
265  resource->size = 0;
268  resource->limit = 0xffffffffffULL;
271  }
272 
273  /* Initialize the memory constraints on the current bus */
274  resource = amdfam15_find_mempair(dev, nodeid, link);
275  if (resource) {
276  resource->base = 0;
277  resource->size = 0;
280  resource->limit = 0xffffffffffULL;
282  }
283 
284 }
285 
286 static void nb_read_resources(struct device *dev)
287 {
288  u32 nodeid;
289  struct bus *link;
290 
292  for (link = dev->link_list; link; link = link->next) {
293  if (link->children) {
295  }
296  }
297 
298  /*
299  * This MMCONF resource must be reserved in the PCI domain.
300  * It is not honored by the coreboot resource allocator if it is in
301  * the CPU_CLUSTER.
302  */
304 }
305 
306 static void set_resource(struct device *dev, struct resource *resource, u32 nodeid)
307 {
308  resource_t rbase, rend;
309  unsigned int reg, link_num;
310  char buf[50];
311 
312  /* Make certain the resource has actually been set */
313  if (!(resource->flags & IORESOURCE_ASSIGNED)) {
314  return;
315  }
316 
317  /* If I have already stored this resource don't worry about it */
319  return;
320  }
321 
322  /* Only handle PCI memory and IO resources */
324  return;
325 
326  /* Ensure I am actually looking at a resource of function 1 */
327  if ((resource->index & 0xffff) < 0x1000) {
328  return;
329  }
330  /* Get the base address */
331  rbase = resource->base;
332 
333  /* Get the limit (rounded up) */
334  rend = resource_end(resource);
335 
336  /* Get the register and link */
337  reg = resource->index & 0xfff; // 4k
339 
340  if (resource->flags & IORESOURCE_IO) {
341  set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
342  }
343  else if (resource->flags & IORESOURCE_MEM) {
344  set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, node_nums);// [39:8]
345  }
347  snprintf(buf, sizeof(buf), " <node %x link %x>",
348  nodeid, link_num);
350 }
351 
352 /**
353  * I tried to reuse the resource allocation code in set_resource()
354  * but it is too difficult to deal with the resource allocation magic.
355  */
356 
357 static void create_vga_resource(struct device *dev, unsigned int nodeid)
358 {
359  struct bus *link;
360 
361  /* find out which link the VGA card is connected,
362  * we only deal with the 'first' vga card */
363  for (link = dev->link_list; link; link = link->next) {
364  if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
365 #if CONFIG(MULTIPLE_VGA_ADAPTERS)
366  extern struct device *vga_pri; // the primary vga device, defined in device.c
367  printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d bus range [%d,%d]\n", vga_pri->bus->secondary,
368  link->secondary,link->subordinate);
369  /* We need to make sure the vga_pri is under the link */
370  if ((vga_pri->bus->secondary >= link->secondary) &&
371  (vga_pri->bus->secondary <= link->subordinate))
372 #endif
373  break;
374  }
375  }
376 
377  /* no VGA card installed */
378  if (link == NULL)
379  return;
380 
381  printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, sblink);
383 }
384 
385 static void nb_set_resources(struct device *dev)
386 {
387  unsigned int nodeid;
388  struct bus *bus;
389  struct resource *res;
390 
391  /* Find the nodeid */
392  nodeid = amdfam15_nodeid(dev);
393 
394  create_vga_resource(dev, nodeid); //TODO: do we need this?
395 
396  /* Set each resource we have found */
397  for (res = dev->resource_list; res; res = res->next) {
398  set_resource(dev, res, nodeid);
399  }
400 
401  for (bus = dev->link_list; bus; bus = bus->next) {
402  if (bus->children) {
404  }
405  }
406 }
407 
408 static unsigned long acpi_fill_hest(acpi_hest_t *hest)
409 {
410  void *addr, *current;
411 
412  /* Skip the HEST header. */
413  current = (void *)(hest + 1);
414 
416  if (addr != NULL)
417  current += acpi_create_hest_error_source(hest, current, 0,
418  addr + 2, *(UINT16 *)addr - 2);
419 
421  if (addr != NULL)
422  current += acpi_create_hest_error_source(hest, current, 1,
423  addr + 2, *(UINT16 *)addr - 2);
424 
425  return (unsigned long)current;
426 }
427 
429 {
430  msr_t msr;
431  char pscope[] = "\\_SB.PCI0";
432 
433  acpigen_write_scope(pscope);
434  msr = rdmsr(TOP_MEM);
435  acpigen_write_name_dword("TOM1", msr.lo);
436  msr = rdmsr(TOP_MEM2);
437  /*
438  * Since XP only implements parts of ACPI 2.0, we can't use a qword
439  * here.
440  * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
441  * slide 22ff.
442  * Shift value right by 20 bit to make it fit into 32bit,
443  * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
444  */
445  acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
446  acpigen_pop_len();
447 }
448 
450 {
451  unsigned int len = ssdt->length - sizeof(acpi_header_t);
452  unsigned int i;
453 
454  for (i = sizeof(acpi_header_t); i < len; i++) {
455  /* Search for _PR_ scope and replace it with _SB_ */
456  if (*(uint32_t *)((unsigned long)ssdt + i) == 0x5f52505f)
457  *(uint32_t *)((unsigned long)ssdt + i) = 0x5f42535f;
458  }
459  /* Recalculate checksum */
460  ssdt->checksum = 0;
461  ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length);
462 }
463 
464 static unsigned long agesa_write_acpi_tables(const struct device *device,
465  unsigned long current,
466  acpi_rsdp_t *rsdp)
467 {
468  acpi_srat_t *srat;
469  acpi_slit_t *slit;
470  acpi_header_t *ssdt;
471  acpi_header_t *alib;
472  acpi_header_t *ivrs;
473  acpi_hest_t *hest;
474 
475  /* HEST */
476  current = ALIGN(current, 8);
477  hest = (acpi_hest_t *)current;
479  acpi_add_table(rsdp, hest);
480  current += hest->header.length;
481 
482  current = ALIGN(current, 8);
483  printk(BIOS_DEBUG, "ACPI: * IVRS at %lx\n", current);
485  if (ivrs != NULL) {
486  memcpy((void *)current, ivrs, ivrs->length);
487  ivrs = (acpi_header_t *) current;
488  current += ivrs->length;
489  acpi_add_table(rsdp, ivrs);
490  } else {
491  printk(BIOS_DEBUG, " AGESA IVRS table NULL. Skipping.\n");
492  }
493 
494  /* SRAT */
495  current = ALIGN(current, 8);
496  printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current);
498  if (srat != NULL) {
499  memcpy((void *)current, srat, srat->header.length);
500  srat = (acpi_srat_t *) current;
501  current += srat->header.length;
502  acpi_add_table(rsdp, srat);
503  } else {
504  printk(BIOS_DEBUG, " AGESA SRAT table NULL. Skipping.\n");
505  }
506 
507  /* SLIT */
508  current = ALIGN(current, 8);
509  printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current);
511  if (slit != NULL) {
512  memcpy((void *)current, slit, slit->header.length);
513  slit = (acpi_slit_t *) current;
514  current += slit->header.length;
515  acpi_add_table(rsdp, slit);
516  } else {
517  printk(BIOS_DEBUG, " AGESA SLIT table NULL. Skipping.\n");
518  }
519 
520  /* ALIB */
521  current = ALIGN(current, 16);
522  printk(BIOS_DEBUG, "ACPI: * AGESA ALIB SSDT at %lx\n", current);
524  if (alib != NULL) {
525  memcpy((void *)current, alib, alib->length);
526  alib = (acpi_header_t *) current;
527  current += alib->length;
528  acpi_add_table(rsdp, (void *)alib);
529  }
530  else {
531  printk(BIOS_DEBUG, " AGESA ALIB SSDT table NULL. Skipping.\n");
532  }
533 
534  /* this pstate ssdt may cause Blue Screen: Fixed: Keep this comment for a while. */
535  /* SSDT */
536  current = ALIGN(current, 16);
537  printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
539  if (ssdt != NULL) {
541  memcpy((void *)current, ssdt, ssdt->length);
542  ssdt = (acpi_header_t *) current;
543  current += ssdt->length;
544  }
545  else {
546  printk(BIOS_DEBUG, " AGESA PState table NULL. Skipping.\n");
547  }
548  acpi_add_table(rsdp,ssdt);
549 
550  printk(BIOS_DEBUG, "ACPI: * SSDT for PState at %lx\n", current);
551 
552  return current;
553 }
554 
557  .set_resources = nb_set_resources,
558  .enable_resources = pci_dev_enable_resources,
559  .acpi_fill_ssdt = northbridge_fill_ssdt_generator,
560  .write_acpi_tables = agesa_write_acpi_tables,
561 };
562 
563 static const struct pci_driver family15_northbridge __pci_driver = {
564  .ops = &northbridge_operations,
565  .vendor = PCI_VID_AMD,
567 };
568 
569 static const struct pci_driver family10_northbridge __pci_driver = {
570  .ops = &northbridge_operations,
571  .vendor = PCI_VID_AMD,
572  .device = PCI_DID_AMD_10H_NB_HT,
573 };
574 
576  CHIP_NAME("AMD FAM15 Northbridge")
577  .enable_dev = 0,
578 };
579 
580 static void domain_read_resources(struct device *dev)
581 {
582  unsigned int reg;
583 
584  /* Find the already assigned resource pairs */
585  get_fx_devs();
586  for (reg = 0x80; reg <= 0xd8; reg+= 0x08) {
587  u32 base, limit;
588  base = f1_read_config32(reg);
589  limit = f1_read_config32(reg + 0x04);
590  /* Is this register allocated? */
591  if ((base & 3) != 0) {
592  unsigned int nodeid, reg_link;
593  struct device *reg_dev;
594  if (reg < 0xc0) { // mmio
595  nodeid = (limit & 0xf) + (base&0x30);
596  } else { // io
597  nodeid = (limit & 0xf) + ((base>>4)&0x30);
598  }
599  reg_link = (limit >> 4) & 7;
600  reg_dev = __f0_dev[nodeid];
601  if (reg_dev) {
602  /* Reserve the resource */
603  struct resource *res;
604  res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
605  if (res) {
606  res->flags = 1;
607  }
608  }
609  }
610  }
611  /* FIXME: do we need to check extend conf space?
612  I don't believe that much preset value */
613 
615 }
616 
617 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
618 struct hw_mem_hole_info {
619  unsigned int hole_startk;
620  int node_id;
621 };
622 static struct hw_mem_hole_info get_hw_mem_hole_info(void)
623 {
624  struct hw_mem_hole_info mem_hole;
625  int i;
626  mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
627  mem_hole.node_id = -1;
628  for (i = 0; i < node_nums; i++) {
629  resource_t basek, limitk;
630  u32 hole;
631  if (!get_dram_base_limit(i, &basek, &limitk))
632  continue; // no memory on this node
633  hole = pci_read_config32(__f1_dev[i], 0xf0);
634  if (hole & 1) { // we find the hole
635  mem_hole.hole_startk = (hole & (0xff << 24)) >> 10;
636  mem_hole.node_id = i; // record the node No with hole
637  break; // only one hole
638  }
639  }
640 
641  /* We need to double check if there is special set on base reg and limit reg
642  * are not continuous instead of hole, it will find out its hole_startk.
643  */
644  if (mem_hole.node_id == -1) {
645  resource_t limitk_pri = 0;
646  for (i = 0; i < node_nums; i++) {
647  resource_t base_k, limit_k;
648  if (!get_dram_base_limit(i, &base_k, &limit_k))
649  continue; // no memory on this node
650  if (base_k > 4 *1024 * 1024) break; // don't need to go to check
651  if (limitk_pri != base_k) { // we find the hole
652  mem_hole.hole_startk = (unsigned int)limitk_pri; // must beblow 4G
653  mem_hole.node_id = i;
654  break; //only one hole
655  }
656  limitk_pri = limit_k;
657  }
658  }
659  return mem_hole;
660 }
661 #endif
662 
663 static void domain_set_resources(struct device *dev)
664 {
665  unsigned long mmio_basek;
666  u32 pci_tolm;
667  int i, idx;
668  struct bus *link;
669 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
670  struct hw_mem_hole_info mem_hole;
671 #endif
672 
673  pci_tolm = 0xffffffffUL;
674  for (link = dev->link_list; link; link = link->next) {
675  pci_tolm = find_pci_tolm(link);
676  }
677 
678  // FIXME handle interleaved nodes. If you fix this here, please fix
679  // amdk8, too.
680  mmio_basek = pci_tolm >> 10;
681  /* Round mmio_basek to something the processor can support */
682  mmio_basek &= ~((1 << 6) -1);
683 
684  // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
685  // MMIO hole. If you fix this here, please fix amdk8, too.
686  /* Round the mmio hole to 64M */
687  mmio_basek &= ~((64*1024) - 1);
688 
689 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
690  /* if the hw mem hole is already set in raminit stage, here we will compare
691  * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
692  * use hole_basek as mmio_basek and we don't need to reset hole.
693  * otherwise We reset the hole to the mmio_basek
694  */
695 
696  mem_hole = get_hw_mem_hole_info();
697 
698  // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
699  if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk))
700  mmio_basek = mem_hole.hole_startk;
701 #endif
702 
703  idx = 0x10;
704  for (i = 0; i < node_nums; i++) {
705  resource_t basek, limitk, sizek; // 4 1T
706 
707  if (!get_dram_base_limit(i, &basek, &limitk))
708  continue; // no memory on this node
709 
710  sizek = limitk - basek;
711 
712  /* See if we need a hole from 0xa0000 (640K) to 0xbffff (768K) */
713  if (basek < 640 && sizek > 768) {
714  ram_resource(dev, (idx | i), basek, 640 - basek);
715  idx += 0x10;
716  basek = 768;
717  sizek = limitk - basek;
718 
719  }
720 
721  /* split the region to accommodate pci memory space */
722  if ((basek < 4*1024*1024) && (limitk > mmio_basek)) {
723  if (basek <= mmio_basek) {
724  unsigned int pre_sizek;
725  pre_sizek = mmio_basek - basek;
726  if (pre_sizek > 0) {
727  ram_resource(dev, (idx | i), basek, pre_sizek);
728  idx += 0x10;
729  sizek -= pre_sizek;
730  }
731  basek = mmio_basek;
732  }
733  if ((basek + sizek) <= 4*1024*1024) {
734  sizek = 0;
735  }
736  else {
737  uint64_t topmem2 = amd_topmem2();
738  basek = 4*1024*1024;
739  sizek = topmem2/1024 - basek;
740  }
741  }
742 
743  ram_resource(dev, (idx | i), basek, sizek);
744  idx += 0x10;
745  printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
746  i, mmio_basek, basek, limitk);
747  }
748 
750 
751  for (link = dev->link_list; link; link = link->next) {
752  if (link->children) {
753  assign_resources(link);
754  }
755  }
756 }
757 
758 static struct device_operations pci_domain_ops = {
760  .set_resources = domain_set_resources,
761  .scan_bus = pci_domain_scan_bus,
762 };
763 
764 static void sysconf_init(struct device *dev) // first node
765 {
766  sblink = (pci_read_config32(dev, 0x64)>>8) & 7; // don't forget sublink1
767  node_nums = ((pci_read_config32(dev, 0x60)>>4) & 7) + 1; //NodeCnt[2:0]
768 }
769 
770 static void cpu_bus_scan(struct device *dev)
771 {
772  struct bus *cpu_bus;
773  struct device *dev_mc;
774  int i,j;
775  int coreid_bits;
776  int core_max = 0;
777  unsigned int ApicIdCoreIdSize;
778  unsigned int core_nums;
779  int siblings = 0;
780  unsigned int family;
781 
782  dev_mc = pcidev_on_root(DEV_CDB, 0);
783  if (!dev_mc) {
784  printk(BIOS_ERR, "0:%02x.0 not found", DEV_CDB);
785  die("");
786  }
787  sysconf_init(dev_mc);
788 
789  /* Get Max Number of cores(MNC) */
790  coreid_bits = (cpuid_ecx(0x80000008) & 0x0000F000) >> 12;
791  core_max = 1 << (coreid_bits & 0x000F); //mnc
792 
793  ApicIdCoreIdSize = ((cpuid_ecx(0x80000008)>>12) & 0xF);
794  if (ApicIdCoreIdSize) {
795  core_nums = (1 << ApicIdCoreIdSize) - 1;
796  } else {
797  core_nums = 3; //quad core
798  }
799 
800  /* Find which cpus are present */
801  cpu_bus = dev->link_list;
802  for (i = 0; i < node_nums; i++) {
803  struct device *cdb_dev;
804  unsigned int devn;
805  struct bus *pbus;
806 
807  devn = DEV_CDB + i;
808  pbus = dev_mc->bus;
809 
810  /* Find the cpu's pci device */
811  cdb_dev = pcidev_on_root(devn, 0);
812  if (!cdb_dev) {
813  /* If I am probing things in a weird order
814  * ensure all of the cpu's pci devices are found.
815  */
816  int fn;
817  for (fn = 0; fn <= 5; fn++) { //FBDIMM?
818  cdb_dev = pci_probe_dev(NULL, pbus,
819  PCI_DEVFN(devn, fn));
820  }
821  cdb_dev = pcidev_on_root(devn, 0);
822  } else {
823  /* Ok, We need to set the links for that device.
824  * otherwise the device under it will not be scanned
825  */
826  add_more_links(cdb_dev, 4);
827  }
828 
829  family = cpuid_eax(1);
830  family = (family >> 20) & 0xFF;
831  if (family == 1) { //f10
832  u32 dword;
833  cdb_dev = pcidev_on_root(devn, 3);
834  dword = pci_read_config32(cdb_dev, 0xe8);
835  siblings = ((dword & BIT15) >> 13) | ((dword & (BIT13 | BIT12)) >> 12);
836  } else if (family == 6) {//f15
837  cdb_dev = pcidev_on_root(devn, 5);
838  if (cdb_dev && cdb_dev->enabled) {
839  siblings = pci_read_config32(cdb_dev, 0x84);
840  siblings &= 0xFF;
841  }
842  } else {
843  siblings = 0; //default one core
844  }
845  int enable_node = cdb_dev && cdb_dev->enabled;
846  printk(BIOS_SPEW, "%s family%xh, core_max=0x%x, core_nums=0x%x, siblings=0x%x\n",
847  dev_path(cdb_dev), 0x0f + family, core_max, core_nums, siblings);
848 
849  for (j = 0; j <= siblings; j++) {
850  extern CONST OPTIONS_CONFIG_TOPOLOGY ROMDATA TopologyConfiguration;
851  u32 modules = TopologyConfiguration.PlatformNumberOfModules;
852  u32 lapicid_start = 0;
853 
854  /*
855  * APIC ID calucation is tightly coupled with AGESA v5 code.
856  * This calculation MUST match the assignment calculation done
857  * in LocalApicInitializationAtEarly() function.
858  * And reference GetLocalApicIdForCore()
859  *
860  * Apply APIC enumeration rules
861  * For systems with >= 16 APICs, put the IO-APICs at 0..n and
862  * put the local-APICs at m..z
863  *
864  * This is needed because many IO-APIC devices only have 4 bits
865  * for their APIC id and therefore must reside at 0..15
866  */
867 
868  u8 plat_num_io_apics = 3; /* FIXME */
869 
870  if ((node_nums * core_max) + plat_num_io_apics >= 0x10) {
871  lapicid_start = (plat_num_io_apics - 1) / core_max;
872  lapicid_start = (lapicid_start + 1) * core_max;
873  printk(BIOS_SPEW, "lpaicid_start=0x%x ", lapicid_start);
874  }
875  u32 apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (siblings + 1)) : j);
876  printk(BIOS_SPEW, "node 0x%x core 0x%x apicid=0x%x\n",
877  i, j, apic_id);
878 
879  struct device *cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
880  if (cpu)
881  amd_cpu_topology(cpu, i, j);
882  } //j
883  }
884 }
885 
886 static void cpu_bus_init(struct device *dev)
887 {
889 }
890 
891 static struct device_operations cpu_bus_ops = {
893  .set_resources = noop_set_resources,
894  .init = cpu_bus_init,
895  .scan_bus = cpu_bus_scan,
896 };
897 
898 static void root_complex_enable_dev(struct device *dev)
899 {
900  /* Set the operations if it is a special bus type */
901  if (dev->path.type == DEVICE_PATH_DOMAIN) {
902  dev->ops = &pci_domain_ops;
903  } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
904  dev->ops = &cpu_bus_ops;
905  }
906 }
907 
909  CHIP_NAME("AMD Family 15tn Root Complex")
910  .enable_dev = root_complex_enable_dev,
911 };
912 
913 /*********************************************************************
914  * Change the vendor / device IDs to match the generic VBIOS header. *
915  *********************************************************************/
917 {
918  u32 new_vendev = vendev;
919 
920  switch (vendev) {
921  case 0x10029900: /* AMD Radeon HD 7660G (Trinity) */
922  case 0x10029901: /* AMD Radeon HD 7660D (Trinity) */
923  case 0x10029903: /* AMD Radeon HD 7640G (Trinity) */
924  case 0x10029904: /* AMD Radeon HD 7560D (Trinity) */
925  case 0x10029907: /* AMD Radeon HD 7620G (Trinity) */
926  case 0x10029908: /* AMD Radeon HD 7600G (Trinity) */
927  case 0x1002990A: /* AMD Radeon HD 7500G (Trinity) */
928  case 0x1002990B: /* AMD Radeon HD 8650G (Richland) */
929  case 0x1002990C: /* AMD Radeon HD 8670D (Richland) */
930  case 0x1002990D: /* AMD Radeon HD 8550G (Richland) */
931  case 0x1002990E: /* AMD Radeon HD 8570D (Richland) */
932  case 0x1002990F: /* AMD Radeon HD 8610G (Richland) */
933  case 0x10029910: /* AMD Radeon HD 7660G (Trinity) */
934  case 0x10029913: /* AMD Radeon HD 7640G (Trinity) */
935  case 0x10029917: /* AMD Radeon HD 7620G (Trinity) */
936  case 0x10029918: /* AMD Radeon HD 7600G (Trinity) */
937  case 0x10029919: /* AMD Radeon HD 7500G (Trinity) */
938  case 0x10029990: /* AMD Radeon HD 7520G (Trinity) */
939  case 0x10029991: /* AMD Radeon HD 7540D (Trinity) */
940  case 0x10029992: /* AMD Radeon HD 7420G (Trinity) */
941  case 0x10029993: /* AMD Radeon HD 7480D (Trinity) */
942  case 0x10029994: /* AMD Radeon HD 7400G (Trinity) */
943  case 0x10029995: /* AMD Radeon HD 8450G (Richland) */
944  case 0x10029996: /* AMD Radeon HD 8470D (Richland) */
945  case 0x10029997: /* AMD Radeon HD 8350G (Richland) */
946  case 0x10029998: /* AMD Radeon HD 8370D (Richland) */
947  case 0x10029999: /* AMD Radeon HD 8510G (Richland) */
948  case 0x1002999A: /* AMD Radeon HD 8410G (Richland) */
949  case 0x1002999B: /* AMD Radeon HD 8310G (Richland) */
950  case 0x1002999C: /* AMD Radeon HD 8650D (Richland) */
951  case 0x1002999D: /* AMD Radeon HD 8550D (Richland) */
952  case 0x100299A0: /* AMD Radeon HD 7520G (Trinity) */
953  case 0x100299A2: /* AMD Radeon HD 7420G (Trinity) */
954  case 0x100299A4: /* AMD Radeon HD 7400G (Trinity) */
955  new_vendev = 0x10029901;
956  break;
957  }
958 
959  return new_vendev;
960 }
#define BIT13
Definition: Ioh.h:30
#define BIT12
Definition: Ioh.h:29
#define BIT15
Definition: Ioh.h:32
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
u8 acpi_checksum(u8 *table, u32 length)
Definition: acpi.c:35
unsigned long acpi_create_hest_error_source(acpi_hest_t *hest, acpi_hest_esd_t *esd, u16 type, void *data, u16 data_len)
Definition: acpi.c:1372
void acpi_write_hest(acpi_hest_t *hest, unsigned long(*acpi_fill_hest)(acpi_hest_t *hest))
Definition: acpi.c:1433
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_scope(const char *name)
Definition: acpigen.c:326
void acpigen_write_name_dword(const char *name, uint32_t val)
Definition: acpigen.c:158
@ PICK_PSTATE
Definition: agesa_helper.h:11
@ PICK_IVRS
Definition: agesa_helper.h:17
@ PICK_WHEA_CMC
Definition: agesa_helper.h:15
@ PICK_SRAT
Definition: agesa_helper.h:12
@ PICK_SLIT
Definition: agesa_helper.h:13
@ PICK_WHEA_MCE
Definition: agesa_helper.h:14
@ PICK_ALIB
Definition: agesa_helper.h:16
static uint64_t amd_topmem2(void)
Definition: mtrr.h:74
#define TOP_MEM
Definition: mtrr.h:34
#define TOP_MEM2
Definition: mtrr.h:35
void add_uma_resource_below_tolm(struct device *nb, int idx)
Definition: amd_mtrr.c:8
pte_t value
Definition: mmu.c:91
static unsigned int cpuid_ecx(unsigned int op)
Definition: cpu.h:106
static unsigned int cpuid_eax(unsigned int op)
Definition: cpu.h:79
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
static __always_inline unsigned long nodeid(void)
Definition: smihandler.c:53
struct device * add_cpu_device(struct bus *cpu_bus, unsigned int apic_id, int enabled)
Definition: cpu_device.c:6
void assign_resources(struct bus *bus)
Assign the computed resources to the devices on the bus.
Definition: device.c:268
struct device * vga_pri
Definition: device.c:186
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
struct resource * new_resource(struct device *dev, unsigned int index)
See if a resource structure already exists for a given index and if not allocate one.
Definition: device_util.c:346
void mmconf_resource(struct device *dev, unsigned long index)
Definition: device_util.c:857
struct resource * probe_resource(const struct device *dev, unsigned int index)
See if a resource structure already exists for a given index.
Definition: device_util.c:323
u32 find_pci_tolm(struct bus *bus)
Definition: device_util.c:890
void report_resource_stored(struct device *dev, const struct resource *resource, const char *comment)
Print the resource that was just stored.
Definition: device_util.c:508
resource_t resource_end(const struct resource *resource)
Compute the maximum address that is part of a resource.
Definition: device_util.c:445
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
void add_more_links(struct device *dev, unsigned int total_links)
Ensure the device has a minimum number of bus links.
Definition: device_util.c:652
void * agesawrapper_getlateinitptr(int pick)
Definition: acpi_tables.c:34
struct acpi_table_header acpi_header_t
#define ALIGN
Definition: asm.h:22
#define MMIO_CONF_BASE
Definition: msr.h:24
static __always_inline msr_t rdmsr(unsigned int index)
Definition: msr.h:146
#define CHIP_NAME(X)
Definition: device.h:32
static void noop_read_resources(struct device *dev)
Standard device operations function pointers shims.
Definition: device.h:73
static void noop_set_resources(struct device *dev)
Definition: device.h:74
#define ram_resource(dev, idx, basek, sizek)
Definition: device.h:321
#define amd_cpu_topology(cpu, node, core)
Definition: device.h:233
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
void initialize_cpus(struct bus *cpu_bus)
static int log2(u32 x)
Definition: lib.h:53
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
static uint8_t * buf
Definition: uart.c:7
result
Definition: mrc_cache.c:35
#define HT_IO_HOST_ALIGN
Definition: nb_common.h:6
#define DEV_CDB
Definition: nb_common.h:9
#define HT_MEM_HOST_ALIGN
Definition: nb_common.h:7
u32 map_oprom_vendev(u32 vendev)
Definition: northbridge.c:834
static void sysconf_init(struct device *dev)
Definition: northbridge.c:764
struct chip_operations northbridge_amd_agesa_family15tn_ops
Definition: northbridge.c:575
static void cpu_bus_init(struct device *dev)
Definition: northbridge.c:886
static void get_fx_devs(void)
Definition: northbridge.c:67
static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index, u32 mmio_min, u32 mmio_max, u32 nodes)
Definition: northbridge.c:49
static struct device * __f1_dev[MAX_NODE_NUMS]
Definition: northbridge.c:30
static const struct pci_driver family15_northbridge __pci_driver
Definition: northbridge.c:563
static struct device_operations cpu_bus_ops
Definition: northbridge.c:891
static int reg_useable(unsigned int reg, struct device *goal_dev, unsigned int goal_nodeid, unsigned int goal_link)
Definition: northbridge.c:162
static void nb_read_resources(struct device *dev)
Definition: northbridge.c:286
static struct device * __f0_dev[MAX_NODE_NUMS]
Definition: northbridge.c:29
static int get_dram_base_limit(u32 nodeid, resource_t *basek, resource_t *limitk)
Definition: northbridge.c:105
static struct device_operations pci_domain_ops
Definition: northbridge.c:758
static void set_io_addr_reg(struct device *dev, u32 nodeid, u32 linkn, u32 reg, u32 io_min, u32 io_max)
Definition: northbridge.c:35
static void root_complex_enable_dev(struct device *dev)
Definition: northbridge.c:898
static void f1_write_config32(unsigned int reg, u32 value)
Definition: northbridge.c:91
static u32 amdfam15_nodeid(struct device *dev)
Definition: northbridge.c:138
static void set_resource(struct device *dev, struct resource *resource, u32 nodeid)
Definition: northbridge.c:306
static void create_vga_resource(struct device *dev, unsigned int nodeid)
I tried to reuse the resource allocation code in set_resource() but it is too difficult to deal with ...
Definition: northbridge.c:357
static void northbridge_fill_ssdt_generator(const struct device *device)
Definition: northbridge.c:428
static struct device * __f2_dev[MAX_NODE_NUMS]
Definition: northbridge.c:31
static unsigned int sblink
Definition: northbridge.c:28
static void cpu_bus_scan(struct device *dev)
Definition: northbridge.c:770
struct chip_operations northbridge_amd_agesa_family15tn_root_complex_ops
Definition: northbridge.c:908
static unsigned int fx_devs
Definition: northbridge.c:33
static unsigned int node_nums
Definition: northbridge.c:27
static void nb_set_resources(struct device *dev)
Definition: northbridge.c:385
static struct device_operations northbridge_operations
Definition: northbridge.c:555
static struct device * __f4_dev[MAX_NODE_NUMS]
Definition: northbridge.c:32
static void set_vga_enable_reg(u32 nodeid, u32 linkn)
Definition: northbridge.c:143
static struct device * get_node_pci(u32 nodeid, u32 fn)
Definition: northbridge.c:62
static void domain_set_resources(struct device *dev)
Definition: northbridge.c:663
static struct resource * amdfam15_find_iopair(struct device *dev, unsigned int nodeid, unsigned int link)
Definition: northbridge.c:190
static unsigned long agesa_write_acpi_tables(const struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Definition: northbridge.c:464
static struct resource * amdfam15_find_mempair(struct device *dev, u32 nodeid, u32 link)
Definition: northbridge.c:218
static unsigned long acpi_fill_hest(acpi_hest_t *hest)
Definition: northbridge.c:408
static void domain_read_resources(struct device *dev)
Definition: northbridge.c:580
static u32 f1_read_config32(unsigned int reg)
Definition: northbridge.c:84
static void patch_ssdt_processor_scope(acpi_header_t *ssdt)
Definition: northbridge.c:449
#define MAX_NODE_NUMS
Definition: northbridge.c:25
static void amdfam15_link_read_bases(struct device *dev, u32 nodeid, u32 link)
Definition: northbridge.c:244
@ DEVICE_PATH_CPU_CLUSTER
Definition: path.h:14
@ DEVICE_PATH_DOMAIN
Definition: path.h:13
#define PCI_DEVFN(slot, func)
Definition: pci_def.h:548
#define PCI_BRIDGE_CTL_VGA
Definition: pci_def.h:139
struct device * pci_probe_dev(struct device *dev, struct bus *bus, unsigned int devfn)
Scan a PCI bus.
Definition: pci_device.c:1183
void pci_domain_read_resources(struct device *dev)
Definition: pci_device.c:547
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_domain_scan_bus(struct device *dev)
Scan a PCI domain.
Definition: pci_device.c:1610
#define PCI_VID_AMD
Definition: pci_ids.h:496
#define PCI_DID_AMD_15H_MODEL_101F_NB_HT
Definition: pci_ids.h:500
#define PCI_DID_AMD_10H_NB_HT
Definition: pci_ids.h:498
#define IOINDEX(IDX, LINK)
Definition: resource.h:60
#define IORESOURCE_MEM
Definition: resource.h:10
#define IORESOURCE_STORED
Definition: resource.h:32
#define IORESOURCE_ASSIGNED
Definition: resource.h:34
#define IORESOURCE_IO
Definition: resource.h:9
u64 resource_t
Definition: resource.h:43
#define IOINDEX_LINK(IDX)
Definition: resource.h:61
#define IORESOURCE_PREFETCH
Definition: resource.h:17
#define IORESOURCE_BRIDGE
Definition: resource.h:26
uintptr_t base
Definition: uart.c:17
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long long uint64_t
Definition: stdint.h:17
uint8_t u8
Definition: stdint.h:45
acpi_header_t header
Definition: acpi.h:877
Definition: acpi.h:82
acpi_header_t header
Definition: acpi.h:347
acpi_header_t header
Definition: acpi.h:291
Definition: device.h:76
DEVTREE_CONST struct bus * next
Definition: device.h:80
unsigned int bridge_ctrl
Definition: device.h:81
DEVTREE_CONST struct device * children
Definition: device.h:79
unsigned char link_num
Definition: device.h:83
uint16_t subordinate
Definition: device.h:85
DEVTREE_CONST struct device * dev
Definition: device.h:78
uint16_t secondary
Definition: device.h:84
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct pci_path pci
Definition: path.h:116
enum device_path_type type
Definition: path.h:114
Definition: device.h:107
struct device_path path
Definition: device.h:115
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct bus * bus
Definition: device.h:108
DEVTREE_CONST struct bus * link_list
Definition: device.h:139
DEVTREE_CONST struct resource * resource_list
Definition: device.h:134
unsigned int enabled
Definition: device.h:122
unsigned int hi
Definition: msr.h:112
unsigned int lo
Definition: msr.h:111
unsigned int devfn
Definition: path.h:54
unsigned long flags
Definition: resource.h:49
unsigned char align
Definition: resource.h:51
resource_t limit
Definition: resource.h:47
unsigned char gran
Definition: resource.h:52
resource_t base
Definition: resource.h:45
unsigned long index
Definition: resource.h:50
resource_t size
Definition: resource.h:46
DEVTREE_CONST struct resource * next
Definition: resource.h:48
u8 val
Definition: sys.c:300
int snprintf(char *buf, size_t size, const char *fmt,...)
Note: This file is only for POSIX compatibility, and is meant to be chain-included via string....
Definition: vsprintf.c:35
typedef void(X86APIP X86EMU_intrFuncs)(int num)