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 <cpu/x86/lapic.h>
15 #include <cpu/amd/msr.h>
16 #include <cpu/amd/mtrr.h>
17 #include <Porting.h>
18 #include <AGESA.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[39:24], 00_0000h} <= address[39: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  /*
122  * BKDG address[39:0] <= {DramLimit[39:24], FF_FFFFh} converted as above but
123  * ORed with 0xffff to get real limit before shifting.
124  */
125  temp = pci_read_config32(__f1_dev[nodeid], 0x44 + (nodeid << 3)); //[39:24] at [31:16]
126  *limitk = ((temp & 0xffff0000) | 0xffff) >> (10 - 8);
127  *limitk += 1; // round up last byte
128 
129  return 1;
130 }
131 
132 static u32 amdfam16_nodeid(struct device *dev)
133 {
134  return (dev->path.pci.devfn >> 3) - DEV_CDB;
135 }
136 
137 static void set_vga_enable_reg(u32 nodeid, u32 linkn)
138 {
139  u32 val;
140 
141  val = 1 | (nodeid << 4) | (linkn << 12);
142  /* it will routing
143  * (1)mmio 0xa0000:0xbffff
144  * (2)io 0x3b0:0x3bb, 0x3c0:0x3df
145  */
146  f1_write_config32(0xf4, val);
147 
148 }
149 
150 /**
151  * @return
152  * @retval 2 resource does not exist, usable
153  * @retval 0 resource exists, not usable
154  * @retval 1 resource exist, resource has been allocated before
155  */
156 static int reg_useable(unsigned int reg, struct device *goal_dev,
157  unsigned int goal_nodeid, unsigned int goal_link)
158 {
159  struct resource *res;
160  unsigned int nodeid, link = 0;
161  int result;
162  res = 0;
163  for (nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
164  struct device *dev;
165  dev = __f0_dev[nodeid];
166  if (!dev)
167  continue;
168  for (link = 0; !res && (link < 8); link++) {
169  res = probe_resource(dev, IOINDEX(0x1000 + reg, link));
170  }
171  }
172  result = 2;
173  if (res) {
174  result = 0;
175  if ((goal_link == (link - 1)) &&
176  (goal_nodeid == (nodeid - 1)) &&
177  (res->flags <= 1)) {
178  result = 1;
179  }
180  }
181  return result;
182 }
183 
184 static struct resource *amdfam16_find_iopair(struct device *dev,
185  unsigned int nodeid, unsigned int link)
186 {
187  struct resource *resource;
188  u32 free_reg, reg;
189  resource = 0;
190  free_reg = 0;
191  for (reg = 0xc0; reg <= 0xd8; reg += 0x8) {
192  int result;
193  result = reg_useable(reg, dev, nodeid, link);
194  if (result == 1) {
195  /* I have been allocated this one */
196  break;
197  }
198  else if (result > 1) {
199  /* I have a free register pair */
200  free_reg = reg;
201  }
202  }
203  if (reg > 0xd8) {
204  reg = free_reg; // if no free, the free_reg still be 0
205  }
206 
207  resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
208 
209  return resource;
210 }
211 
212 static struct resource *amdfam16_find_mempair(struct device *dev, u32 nodeid, u32 link)
213 {
214  struct resource *resource;
215  u32 free_reg, reg;
216  resource = 0;
217  free_reg = 0;
218  for (reg = 0x80; reg <= 0xb8; reg += 0x8) {
219  int result;
220  result = reg_useable(reg, dev, nodeid, link);
221  if (result == 1) {
222  /* I have been allocated this one */
223  break;
224  }
225  else if (result > 1) {
226  /* I have a free register pair */
227  free_reg = reg;
228  }
229  }
230  if (reg > 0xb8) {
231  reg = free_reg;
232  }
233 
234  resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
235  return resource;
236 }
237 
238 static void amdfam16_link_read_bases(struct device *dev, u32 nodeid, u32 link)
239 {
240  struct resource *resource;
241 
242  /* Initialize the io space constraints on the current bus */
243  resource = amdfam16_find_iopair(dev, nodeid, link);
244  if (resource) {
245  u32 align;
247  resource->base = 0;
248  resource->size = 0;
249  resource->align = align;
250  resource->gran = align;
251  resource->limit = 0xffffUL;
253  }
254 
255  /* Initialize the prefetchable memory constraints on the current bus */
256  resource = amdfam16_find_mempair(dev, nodeid, link);
257  if (resource) {
258  resource->base = 0;
259  resource->size = 0;
262  resource->limit = 0xffffffffffULL;
265  }
266 
267  /* Initialize the memory constraints on the current bus */
268  resource = amdfam16_find_mempair(dev, nodeid, link);
269  if (resource) {
270  resource->base = 0;
271  resource->size = 0;
274  resource->limit = 0xffffffffffULL;
276  }
277 
278 }
279 
280 static void read_resources(struct device *dev)
281 {
282  u32 nodeid;
283  struct bus *link;
284 
286  for (link = dev->link_list; link; link = link->next) {
287  if (link->children) {
289  }
290  }
291 
292  /*
293  * This MMCONF resource must be reserved in the PCI_DOMAIN.
294  * It is not honored by the coreboot resource allocator if it is in
295  * the APIC_CLUSTER.
296  */
298 }
299 
300 static void set_resource(struct device *dev, struct resource *resource, u32 nodeid)
301 {
302  resource_t rbase, rend;
303  unsigned int reg, link_num;
304  char buf[50];
305 
306  /* Make certain the resource has actually been set */
307  if (!(resource->flags & IORESOURCE_ASSIGNED)) {
308  return;
309  }
310 
311  /* If I have already stored this resource don't worry about it */
313  return;
314  }
315 
316  /* Only handle PCI memory and IO resources */
318  return;
319 
320  /* Ensure I am actually looking at a resource of function 1 */
321  if ((resource->index & 0xffff) < 0x1000) {
322  return;
323  }
324  /* Get the base address */
325  rbase = resource->base;
326 
327  /* Get the limit (rounded up) */
328  rend = resource_end(resource);
329 
330  /* Get the register and link */
331  reg = resource->index & 0xfff; // 4k
333 
334  if (resource->flags & IORESOURCE_IO) {
335  set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
336  }
337  else if (resource->flags & IORESOURCE_MEM) {
338  set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, node_nums);// [39:8]
339  }
341  snprintf(buf, sizeof(buf), " <node %x link %x>",
342  nodeid, link_num);
344 }
345 
346 /**
347  * I tried to reuse the resource allocation code in set_resource()
348  * but it is too difficult to deal with the resource allocation magic.
349  */
350 
351 static void create_vga_resource(struct device *dev, unsigned int nodeid)
352 {
353  struct bus *link;
354 
355  /* find out which link the VGA card is connected,
356  * we only deal with the 'first' vga card */
357  for (link = dev->link_list; link; link = link->next) {
358  if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
359 #if CONFIG(MULTIPLE_VGA_ADAPTERS)
360  extern struct device *vga_pri; // the primary vga device, defined in device.c
361  printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d bus range [%d,%d]\n", vga_pri->bus->secondary,
362  link->secondary,link->subordinate);
363  /* We need to make sure the vga_pri is under the link */
364  if ((vga_pri->bus->secondary >= link->secondary) &&
365  (vga_pri->bus->secondary <= link->subordinate))
366 #endif
367  break;
368  }
369  }
370 
371  /* no VGA card installed */
372  if (link == NULL)
373  return;
374 
375  printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, sblink);
377 }
378 
379 static void set_resources(struct device *dev)
380 {
381  unsigned int nodeid;
382  struct bus *bus;
383  struct resource *res;
384 
385  /* Find the nodeid */
386  nodeid = amdfam16_nodeid(dev);
387 
388  create_vga_resource(dev, nodeid); //TODO: do we need this?
389 
390  /* Set each resource we have found */
391  for (res = dev->resource_list; res; res = res->next) {
392  set_resource(dev, res, nodeid);
393  }
394 
395  for (bus = dev->link_list; bus; bus = bus->next) {
396  if (bus->children) {
398  }
399  }
400 }
401 
402 static unsigned long acpi_fill_hest(acpi_hest_t *hest)
403 {
404  void *addr, *current;
405 
406  /* Skip the HEST header. */
407  current = (void *)(hest + 1);
408 
410  if (addr != NULL)
411  current += acpi_create_hest_error_source(hest, current, 0,
412  addr + 2, *(UINT16 *)addr - 2);
413 
415  if (addr != NULL)
416  current += acpi_create_hest_error_source(hest, current, 1,
417  addr + 2, *(UINT16 *)addr - 2);
418 
419  return (unsigned long)current;
420 }
421 
423 {
424  msr_t msr;
425  char pscope[] = "\\_SB.PCI0";
426 
427  acpigen_write_scope(pscope);
428  msr = rdmsr(TOP_MEM);
429  acpigen_write_name_dword("TOM1", msr.lo);
430  msr = rdmsr(TOP_MEM2);
431  /*
432  * Since XP only implements parts of ACPI 2.0, we can't use a qword
433  * here.
434  * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
435  * slide 22ff.
436  * Shift value right by 20 bit to make it fit into 32bit,
437  * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
438  */
439  acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
440  acpigen_pop_len();
441 }
442 
444 {
445  unsigned int len = ssdt->length - sizeof(acpi_header_t);
446  unsigned int i;
447 
448  for (i = sizeof(acpi_header_t); i < len; i++) {
449  /* Search for _PR_ scope and replace it with _SB_ */
450  if (*(uint32_t *)((unsigned long)ssdt + i) == 0x5f52505f)
451  *(uint32_t *)((unsigned long)ssdt + i) = 0x5f42535f;
452  }
453  /* Recalculate checksum */
454  ssdt->checksum = 0;
455  ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length);
456 }
457 
458 static unsigned long agesa_write_acpi_tables(const struct device *device,
459  unsigned long current,
460  acpi_rsdp_t *rsdp)
461 {
462  acpi_srat_t *srat;
463  acpi_slit_t *slit;
464  acpi_header_t *ssdt;
465  acpi_header_t *alib;
466  acpi_header_t *ivrs;
467  acpi_hest_t *hest;
468 
469  /* HEST */
470  current = ALIGN(current, 8);
471  hest = (acpi_hest_t *)current;
473  acpi_add_table(rsdp, hest);
474  current += hest->header.length;
475 
476  current = ALIGN(current, 8);
477  printk(BIOS_DEBUG, "ACPI: * IVRS at %lx\n", current);
479  if (ivrs != NULL) {
480  memcpy((void *)current, ivrs, ivrs->length);
481  ivrs = (acpi_header_t *) current;
482  current += ivrs->length;
483  acpi_add_table(rsdp, ivrs);
484  } else {
485  printk(BIOS_DEBUG, " AGESA IVRS table NULL. Skipping.\n");
486  }
487 
488  /* SRAT */
489  current = ALIGN(current, 8);
490  printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current);
492  if (srat != NULL) {
493  memcpy((void *)current, srat, srat->header.length);
494  srat = (acpi_srat_t *) current;
495  current += srat->header.length;
496  acpi_add_table(rsdp, srat);
497  } else {
498  printk(BIOS_DEBUG, " AGESA SRAT table NULL. Skipping.\n");
499  }
500 
501  /* SLIT */
502  current = ALIGN(current, 8);
503  printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current);
505  if (slit != NULL) {
506  memcpy((void *)current, slit, slit->header.length);
507  slit = (acpi_slit_t *) current;
508  current += slit->header.length;
509  acpi_add_table(rsdp, slit);
510  } else {
511  printk(BIOS_DEBUG, " AGESA SLIT table NULL. Skipping.\n");
512  }
513 
514  /* ALIB */
515  current = ALIGN(current, 16);
516  printk(BIOS_DEBUG, "ACPI: * AGESA ALIB SSDT at %lx\n", current);
518  if (alib != NULL) {
519  memcpy((void *)current, alib, alib->length);
520  alib = (acpi_header_t *) current;
521  current += alib->length;
522  acpi_add_table(rsdp, (void *)alib);
523  }
524  else {
525  printk(BIOS_DEBUG, " AGESA ALIB SSDT table NULL. Skipping.\n");
526  }
527 
528  /* this pstate ssdt may cause Blue Screen: Fixed: Keep this comment for a while. */
529  /* SSDT */
530  current = ALIGN(current, 16);
531  printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
533  if (ssdt != NULL) {
535  memcpy((void *)current, ssdt, ssdt->length);
536  ssdt = (acpi_header_t *) current;
537  current += ssdt->length;
538  }
539  else {
540  printk(BIOS_DEBUG, " AGESA PState table NULL. Skipping.\n");
541  }
542  acpi_add_table(rsdp,ssdt);
543 
544  printk(BIOS_DEBUG, "ACPI: * SSDT for PState at %lx\n", current);
545 
546  return current;
547 }
548 
551  .set_resources = set_resources,
552  .enable_resources = pci_dev_enable_resources,
553  .acpi_fill_ssdt = northbridge_fill_ssdt_generator,
554  .write_acpi_tables = agesa_write_acpi_tables,
555 };
556 
557 static const struct pci_driver family16_northbridge __pci_driver = {
558  .ops = &northbridge_operations,
559  .vendor = PCI_VID_AMD,
561 };
562 
563 static const struct pci_driver family10_northbridge __pci_driver = {
564  .ops = &northbridge_operations,
565  .vendor = PCI_VID_AMD,
566  .device = PCI_DID_AMD_10H_NB_HT,
567 };
568 
569 static void fam16_finalize(void *chip_info)
570 {
571  struct device *dev;
572  u32 value;
573  dev = pcidev_on_root(0, 0); /* clear IoapicSbFeatureEn */
574  pci_write_config32(dev, 0xF8, 0);
575  pci_write_config32(dev, 0xFC, 5); /* TODO: move it to dsdt.asl */
576 
577  /* disable No Snoop */
578  dev = pcidev_on_root(1, 1);
579  if (dev != NULL) {
580  value = pci_read_config32(dev, 0x60);
581  value &= ~(1 << 11);
582  pci_write_config32(dev, 0x60, value);
583  }
584 }
585 
587  CHIP_NAME("AMD FAM16 Northbridge")
588  .enable_dev = 0,
589  .final = fam16_finalize,
590 };
591 
592 static void domain_read_resources(struct device *dev)
593 {
594  unsigned int reg;
595 
596  /* Find the already assigned resource pairs */
597  get_fx_devs();
598  for (reg = 0x80; reg <= 0xd8; reg+= 0x08) {
599  u32 base, limit;
600  base = f1_read_config32(reg);
601  limit = f1_read_config32(reg + 0x04);
602  /* Is this register allocated? */
603  if ((base & 3) != 0) {
604  unsigned int nodeid, reg_link;
605  struct device *reg_dev;
606  if (reg < 0xc0) { // mmio
607  nodeid = (limit & 0xf) + (base&0x30);
608  } else { // io
609  nodeid = (limit & 0xf) + ((base>>4)&0x30);
610  }
611  reg_link = (limit >> 4) & 7;
612  reg_dev = __f0_dev[nodeid];
613  if (reg_dev) {
614  /* Reserve the resource */
615  struct resource *res;
616  res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
617  if (res) {
618  res->flags = 1;
619  }
620  }
621  }
622  }
623  /* FIXME: do we need to check extend conf space?
624  I don't believe that much preset value */
625 
627 }
628 
629 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
630 struct hw_mem_hole_info {
631  unsigned int hole_startk;
632  int node_id;
633 };
634 static struct hw_mem_hole_info get_hw_mem_hole_info(void)
635 {
636  struct hw_mem_hole_info mem_hole;
637  int i;
638  mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
639  mem_hole.node_id = -1;
640  for (i = 0; i < node_nums; i++) {
641  resource_t basek, limitk;
642  u32 hole;
643  if (!get_dram_base_limit(i, &basek, &limitk))
644  continue; // no memory on this node
645  hole = pci_read_config32(__f1_dev[i], 0xf0);
646  if (hole & 2) { // we find the hole
647  mem_hole.hole_startk = (hole & (0xff << 24)) >> 10;
648  mem_hole.node_id = i; // record the node No with hole
649  break; // only one hole
650  }
651  }
652 
653  /* We need to double check if there is special set on base reg and limit reg
654  * are not continuous instead of hole, it will find out its hole_startk.
655  */
656  if (mem_hole.node_id == -1) {
657  resource_t limitk_pri = 0;
658  for (i = 0; i < node_nums; i++) {
659  resource_t base_k, limit_k;
660  if (!get_dram_base_limit(i, &base_k, &limit_k))
661  continue; // no memory on this node
662  if (base_k > 4 *1024 * 1024) break; // don't need to go to check
663  if (limitk_pri != base_k) { // we find the hole
664  mem_hole.hole_startk = (unsigned int)limitk_pri; // must beblow 4G
665  mem_hole.node_id = i;
666  break; //only one hole
667  }
668  limitk_pri = limit_k;
669  }
670  }
671  return mem_hole;
672 }
673 #endif
674 
675 static void domain_set_resources(struct device *dev)
676 {
677  unsigned long mmio_basek;
678  u32 pci_tolm;
679  int i, idx;
680  struct bus *link;
681 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
682  struct hw_mem_hole_info mem_hole;
683 #endif
684 
685  pci_tolm = 0xffffffffUL;
686  for (link = dev->link_list; link; link = link->next) {
687  pci_tolm = find_pci_tolm(link);
688  }
689 
690  // FIXME handle interleaved nodes. If you fix this here, please fix
691  // amdk8, too.
692  mmio_basek = pci_tolm >> 10;
693  /* Round mmio_basek to something the processor can support */
694  mmio_basek &= ~((1 << 6) -1);
695 
696  // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
697  // MMIO hole. If you fix this here, please fix amdk8, too.
698  /* Round the mmio hole to 64M */
699  mmio_basek &= ~((64*1024) - 1);
700 
701 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
702  /* if the hw mem hole is already set in raminit stage, here we will compare
703  * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
704  * use hole_basek as mmio_basek and we don't need to reset hole.
705  * otherwise We reset the hole to the mmio_basek
706  */
707 
708  mem_hole = get_hw_mem_hole_info();
709 
710  // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
711  if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk))
712  mmio_basek = mem_hole.hole_startk;
713 #endif
714 
715  idx = 0x10;
716  for (i = 0; i < node_nums; i++) {
717  resource_t basek, limitk, sizek; // 4 1T
718 
719  if (!get_dram_base_limit(i, &basek, &limitk))
720  continue; // no memory on this node
721 
722  sizek = limitk - basek;
723 
724  /* See if we need a hole from 0xa0000 (640K) to 0xbffff (768K) */
725  if (basek < 640 && sizek > 768) {
726  ram_resource(dev, (idx | i), basek, 640 - basek);
727  idx += 0x10;
728  basek = 768;
729  sizek = limitk - basek;
730  }
731 
732  //printk(BIOS_DEBUG, "node %d : mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n", i, mmio_basek, basek, limitk);
733 
734  /* split the region to accommodate pci memory space */
735  if ((basek < 4*1024*1024) && (limitk > mmio_basek)) {
736  if (basek <= mmio_basek) {
737  unsigned int pre_sizek;
738  pre_sizek = mmio_basek - basek;
739  if (pre_sizek > 0) {
740  ram_resource(dev, (idx | i), basek, pre_sizek);
741  idx += 0x10;
742  sizek -= pre_sizek;
743  }
744  basek = mmio_basek;
745  }
746  if ((basek + sizek) <= 4*1024*1024) {
747  sizek = 0;
748  }
749  else {
750  uint64_t topmem2 = amd_topmem2();
751  basek = 4*1024*1024;
752  sizek = topmem2/1024 - basek;
753  }
754  }
755 
756  ram_resource(dev, (idx | i), basek, sizek);
757  idx += 0x10;
758  printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
759  i, mmio_basek, basek, limitk);
760  }
761 
763 
764  for (link = dev->link_list; link; link = link->next) {
765  if (link->children) {
766  assign_resources(link);
767  }
768  }
769 }
770 
771 static const char *domain_acpi_name(const struct device *dev)
772 {
773  if (dev->path.type == DEVICE_PATH_DOMAIN)
774  return "PCI0";
775 
776  return NULL;
777 }
778 
779 static struct device_operations pci_domain_ops = {
781  .set_resources = domain_set_resources,
782  .scan_bus = pci_domain_scan_bus,
783  .acpi_name = domain_acpi_name,
784 };
785 
786 static void sysconf_init(struct device *dev) // first node
787 {
788  sblink = (pci_read_config32(dev, 0x64)>>8) & 7; // don't forget sublink1
789  node_nums = ((pci_read_config32(dev, 0x60)>>4) & 7) + 1; //NodeCnt[2:0]
790 }
791 
792 static void cpu_bus_scan(struct device *dev)
793 {
794  struct bus *cpu_bus;
795  struct device *dev_mc;
796  int i,j;
797  int coreid_bits;
798  int core_max = 0;
799  unsigned int ApicIdCoreIdSize;
800  unsigned int core_nums;
801  int siblings = 0;
802  unsigned int family;
803 
804  dev_mc = pcidev_on_root(DEV_CDB, 0);
805  if (!dev_mc) {
806  printk(BIOS_ERR, "0:%02x.0 not found", DEV_CDB);
807  die("");
808  }
809  sysconf_init(dev_mc);
810 
811  /* Get Max Number of cores(MNC) */
812  coreid_bits = (cpuid_ecx(0x80000008) & 0x0000F000) >> 12;
813  core_max = 1 << (coreid_bits & 0x000F); //mnc
814 
815  ApicIdCoreIdSize = ((cpuid_ecx(0x80000008)>>12) & 0xF);
816  if (ApicIdCoreIdSize) {
817  core_nums = (1 << ApicIdCoreIdSize) - 1;
818  } else {
819  core_nums = 3; //quad core
820  }
821 
822  /* Find which cpus are present */
823  cpu_bus = dev->link_list;
824  for (i = 0; i < node_nums; i++) {
825  struct device *cdb_dev;
826  unsigned int devn;
827  struct bus *pbus;
828 
829  devn = DEV_CDB + i;
830  pbus = dev_mc->bus;
831 
832  /* Find the cpu's pci device */
833  cdb_dev = pcidev_on_root(devn, 0);
834  if (!cdb_dev) {
835  /* If I am probing things in a weird order
836  * ensure all of the cpu's pci devices are found.
837  */
838  int fn;
839  for (fn = 0; fn <= 5; fn++) { //FBDIMM?
840  cdb_dev = pci_probe_dev(NULL, pbus,
841  PCI_DEVFN(devn, fn));
842  }
843  cdb_dev = pcidev_on_root(devn, 0);
844  } else {
845  /* Ok, We need to set the links for that device.
846  * otherwise the device under it will not be scanned
847  */
848  add_more_links(cdb_dev, 4);
849  }
850 
851  family = cpuid_eax(1);
852  family = (family >> 20) & 0xFF;
853  if (family == 1) { //f10
854  u32 dword;
855  cdb_dev = pcidev_on_root(devn, 3);
856  dword = pci_read_config32(cdb_dev, 0xe8);
857  siblings = ((dword & BIT15) >> 13) | ((dword & (BIT13 | BIT12)) >> 12);
858  } else if (family == 7) {//f16
859  cdb_dev = pcidev_on_root(devn, 5);
860  if (cdb_dev && cdb_dev->enabled) {
861  siblings = pci_read_config32(cdb_dev, 0x84);
862  siblings &= 0xFF;
863  }
864  } else {
865  siblings = 0; //default one core
866  }
867  int enable_node = cdb_dev && cdb_dev->enabled;
868  printk(BIOS_SPEW, "%s family%xh, core_max=0x%x, core_nums=0x%x, siblings=0x%x\n",
869  dev_path(cdb_dev), 0x0f + family, core_max, core_nums, siblings);
870 
871  for (j = 0; j <= siblings; j++) {
872  extern CONST OPTIONS_CONFIG_TOPOLOGY ROMDATA TopologyConfiguration;
873  u32 modules = TopologyConfiguration.PlatformNumberOfModules;
874  u32 lapicid_start = 0;
875 
876  /*
877  * APIC ID calucation is tightly coupled with AGESA v5 code.
878  * This calculation MUST match the assignment calculation done
879  * in LocalApicInitializationAtEarly() function.
880  * And reference GetLocalApicIdForCore()
881  *
882  * Apply APIC enumeration rules
883  * For systems with >= 16 APICs, put the IO-APICs at 0..n and
884  * put the local-APICs at m..z
885  *
886  * This is needed because many IO-APIC devices only have 4 bits
887  * for their APIC id and therefore must reside at 0..15
888  */
889 
890  u8 plat_num_io_apics = 3; /* FIXME */
891 
892  if ((node_nums * core_max) + plat_num_io_apics >= 0x10) {
893  lapicid_start = (plat_num_io_apics - 1) / core_max;
894  lapicid_start = (lapicid_start + 1) * core_max;
895  printk(BIOS_SPEW, "lpaicid_start=0x%x ", lapicid_start);
896  }
897  u32 apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (siblings + 1)) : j);
898  printk(BIOS_SPEW, "node 0x%x core 0x%x apicid=0x%x\n",
899  i, j, apic_id);
900 
901  struct device *cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
902  if (cpu)
903  amd_cpu_topology(cpu, i, j);
904  } //j
905  }
906 }
907 
908 static void cpu_bus_init(struct device *dev)
909 {
911 }
912 
913 static struct device_operations cpu_bus_ops = {
915  .set_resources = noop_set_resources,
916  .init = cpu_bus_init,
917  .scan_bus = cpu_bus_scan,
918 };
919 
920 static void root_complex_enable_dev(struct device *dev)
921 {
922  /* Set the operations if it is a special bus type */
923  if (dev->path.type == DEVICE_PATH_DOMAIN) {
924  dev->ops = &pci_domain_ops;
925  } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
926  dev->ops = &cpu_bus_ops;
927  }
928 }
929 
931  CHIP_NAME("AMD FAM16 Root Complex")
932  .enable_dev = root_complex_enable_dev,
933 };
934 
935 /*********************************************************************
936  * Change the vendor / device IDs to match the generic VBIOS header. *
937  *********************************************************************/
939 {
940  u32 new_vendev = vendev;
941 
942  switch (vendev) {
943  case 0x10029830:
944  case 0x10029831:
945  case 0x10029832:
946  case 0x10029833:
947  case 0x10029834:
948  case 0x10029835:
949  case 0x10029836:
950  case 0x10029837:
951  case 0x10029838:
952  case 0x10029839:
953  case 0x1002983A:
954  case 0x1002983D:
955  new_vendev = 0x10029830; // This is the default value in AMD-generated VBIOS
956  break;
957  default:
958  break;
959  }
960 
961  if (vendev != new_vendev)
962  printk(BIOS_NOTICE, "Mapping PCI device %8x to %8x\n", vendev, new_vendev);
963 
964  return new_vendev;
965 }
#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_NOTICE
BIOS_NOTICE - Unexpected but relatively insignificant.
Definition: loglevel.h:100
#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:786
static u32 amdfam16_nodeid(struct device *dev)
Definition: northbridge.c:132
static void cpu_bus_init(struct device *dev)
Definition: northbridge.c:908
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 family16_northbridge __pci_driver
Definition: northbridge.c:557
static struct device_operations cpu_bus_ops
Definition: northbridge.c:913
static int reg_useable(unsigned int reg, struct device *goal_dev, unsigned int goal_nodeid, unsigned int goal_link)
Definition: northbridge.c:156
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:779
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:920
static void set_resources(struct device *dev)
Definition: northbridge.c:379
static void f1_write_config32(unsigned int reg, u32 value)
Definition: northbridge.c:91
static void set_resource(struct device *dev, struct resource *resource, u32 nodeid)
Definition: northbridge.c:300
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:351
static void northbridge_fill_ssdt_generator(const struct device *device)
Definition: northbridge.c:422
static struct device * __f2_dev[MAX_NODE_NUMS]
Definition: northbridge.c:31
static struct resource * amdfam16_find_iopair(struct device *dev, unsigned int nodeid, unsigned int link)
Definition: northbridge.c:184
static unsigned int sblink
Definition: northbridge.c:28
static void cpu_bus_scan(struct device *dev)
Definition: northbridge.c:792
struct chip_operations northbridge_amd_agesa_family16kb_ops
Definition: northbridge.c:586
struct chip_operations northbridge_amd_agesa_family16kb_root_complex_ops
Definition: northbridge.c:930
static unsigned int fx_devs
Definition: northbridge.c:33
static unsigned int node_nums
Definition: northbridge.c:27
static void fam16_finalize(void *chip_info)
Definition: northbridge.c:569
static struct device_operations northbridge_operations
Definition: northbridge.c:549
static void read_resources(struct device *dev)
Definition: northbridge.c:280
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:137
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:675
static unsigned long agesa_write_acpi_tables(const struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Definition: northbridge.c:458
static const char * domain_acpi_name(const struct device *dev)
Definition: northbridge.c:771
static unsigned long acpi_fill_hest(acpi_hest_t *hest)
Definition: northbridge.c:402
static void domain_read_resources(struct device *dev)
Definition: northbridge.c:592
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:443
#define MAX_NODE_NUMS
Definition: northbridge.c:25
static struct resource * amdfam16_find_mempair(struct device *dev, u32 nodeid, u32 link)
Definition: northbridge.c:212
static void amdfam16_link_read_bases(struct device *dev, u32 nodeid, u32 link)
Definition: northbridge.c:238
@ 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_DID_AMD_16H_MODEL_000F_NB_HT
Definition: pci_ids.h:504
#define PCI_VID_AMD
Definition: pci_ids.h:496
#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)