blob: 71f4897b393e0a6b5fdcd7e7dc8df36932cc3ba8 [file] [log] [blame]
Marc Jones1587dc82017-05-15 18:55:11 -06001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015-2016 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16
17#include <arch/io.h>
18#include <arch/acpi.h>
19#include <arch/acpigen.h>
20#include <cbmem.h>
21#include <chip.h>
22#include <console/console.h>
23#include <cpu/amd/amdfam15.h>
24#include <cpu/amd/mtrr.h>
25#include <cpu/cpu.h>
26#include <device/device.h>
27#include <device/pci.h>
28#include <device/pci_ids.h>
29#include <device/hypertransport.h>
30#include <lib.h>
31#include <agesawrapper.h>
32#include <agesawrapper_call.h>
33#include <soc/northbridge.h>
34#include <stdint.h>
35#include <stdlib.h>
36#include <string.h>
37
38/*
39 * AMD vendorcode files. Place at the end so coreboot defaults and maintained
40 * and not set by vendorcode
41 */
42#include <AGESA.h>
43#include <cpuRegisters.h>
44#include <FieldAccessors.h>
45#include <Options.h>
46#include <Porting.h>
47#include <Topology.h>
48
49#define MAX_NODE_NUMS (MAX_NODES * MAX_DIES)
50
51#if (defined CONFIG_EXT_CONF_SUPPORT) && CONFIG_EXT_CONF_SUPPORT == 1
52#error CONFIG_EXT_CONF_SUPPORT == 1 not support anymore!
53#endif
54
55typedef struct dram_base_mask {
56 u32 base; //[47:27] at [28:8]
57 u32 mask; //[47:27] at [28:8] and enable at bit 0
58} dram_base_mask_t;
59
60static unsigned node_nums;
61static unsigned sblink;
62static device_t __f0_dev;
63static device_t __f1_dev;
64static device_t __f2_dev;
65static device_t __f4_dev;
66static unsigned fx_dev = 0;
67
68static dram_base_mask_t get_dram_base_mask(u32 nodeid)
69{
70 device_t dev = __f1_dev;
71 dram_base_mask_t d;
72 u32 temp;
73 temp = pci_read_config32(dev, 0x44 + (nodeid << 3)); //[39:24] at [31:16]
74 d.mask = ((temp & 0xfff80000) >> (8 + 3)); // mask out DramMask [26:24] too
75 temp = pci_read_config32(dev, 0x144 + (nodeid << 3)) & 0xff; //[47:40] at [7:0]
76 d.mask |= temp << 21;
77 temp = pci_read_config32(dev, 0x40 + (nodeid << 3)); //[39:24] at [31:16]
78 d.mask |= (temp & 1); // enable bit
79 d.base = ((temp & 0xfff80000) >> (8 + 3)); // mask out DramBase [26:24) too
80 temp = pci_read_config32(dev, 0x140 + (nodeid << 3)) & 0xff; //[47:40] at [7:0]
81 d.base |= temp << 21;
82 return d;
83}
84
85static void set_io_addr_reg(device_t dev, u32 nodeid, u32 linkn, u32 reg,
86 u32 io_min, u32 io_max)
87{
88 u32 tempreg;
89 /* io range allocation */
90 tempreg = (nodeid & 0xf) | ((nodeid & 0x30) << (8 - 4)) | (linkn << 4) | ((io_max & 0xf0) << (12 - 4)); //limit
91 pci_write_config32(__f1_dev, reg + 4, tempreg);
92 tempreg = 3 | ((io_min & 0xf0) << (12 - 4)); //base :ISA and VGA ?
93 pci_write_config32(__f1_dev, reg, tempreg);
94}
95
96static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index, u32 mmio_min, u32 mmio_max)
97{
98 u32 tempreg;
99 /* io range allocation */
100 tempreg = (nodeid & 0xf) | (linkn << 4) | (mmio_max & 0xffffff00); //limit
101 pci_write_config32(__f1_dev, reg + 4, tempreg);
102 tempreg = 3 | (nodeid & 0x30) | (mmio_min & 0xffffff00);
103 pci_write_config32(__f1_dev, reg, tempreg);
104}
105
106static device_t get_node_pci(u32 fn)
107{
108 return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, fn));
109}
110
111static void get_fx_dev(void)
112{
113 __f0_dev = get_node_pci(0);
114 __f1_dev = get_node_pci(1);
115 __f2_dev = get_node_pci(2);
116 __f4_dev = get_node_pci(4);
117 fx_dev = 1;
118
119 if (__f1_dev == NULL || __f0_dev == NULL || fx_dev == 0)
120 die("Cannot find 0:0x18.[0|1]\n");
121}
122
123static u32 f1_read_config32(unsigned reg)
124{
125 if (fx_dev == 0)
126 get_fx_dev();
127 return pci_read_config32(__f1_dev, reg);
128}
129
130static void f1_write_config32(unsigned reg, u32 value)
131{
132 if (fx_dev == 0)
133 get_fx_dev();
134 pci_write_config32(__f1_dev, reg, value);
135}
136
137static void set_vga_enable_reg(u32 nodeid, u32 linkn)
138{
139 u32 val;
140
141 val = 1 | (nodeid << 4) | (linkn << 12);
142 /* Routes:
143 * mmio 0xa0000:0xbffff
144 * io 0x3b0:0x3bb, 0x3c0:0x3df
145 */
146 f1_write_config32(0xf4, val);
147}
148
149static void read_resources(device_t dev)
150{
151
152 /*
153 * This MMCONF resource must be reserved in the PCI domain.
154 * It is not honored by the coreboot resource allocator if it is in
155 * the CPU_CLUSTER.
156 */
157 mmconf_resource(dev, 0xc0010058);
158}
159
160static void set_resource(device_t dev, struct resource *resource, u32 nodeid)
161{
162 resource_t rbase, rend;
163 unsigned reg, link_num;
164 char buf[50];
165
166 /* Make certain the resource has actually been set */
167 if (!(resource->flags & IORESOURCE_ASSIGNED))
168 return;
169
170 /* If I have already stored this resource don't worry about it */
171 if (resource->flags & IORESOURCE_STORED)
172 return;
173
174 /* Only handle PCI memory and IO resources */
175 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
176 return;
177
178 /* Ensure I am actually looking at a resource of function 1 */
179 if ((resource->index & 0xffff) < 0x1000)
180 return;
181
182 /* Get the base address */
183 rbase = resource->base;
184
185 /* Get the limit (rounded up) */
186 rend = resource_end(resource);
187
188 /* Get the register and link */
189 reg = resource->index & 0xfff; // 4k
190 link_num = IOINDEX_LINK(resource->index);
191
192 if (resource->flags & IORESOURCE_IO) {
193 set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
194 }
195 else if (resource->flags & IORESOURCE_MEM) {
196 set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >> 24), rbase >> 8, rend >> 8); // [39:8]
197 }
198 resource->flags |= IORESOURCE_STORED;
199 snprintf(buf, sizeof(buf), " <node %x link %x>",
200 nodeid, link_num);
201 report_resource_stored(dev, resource, buf);
202}
203
204/**
205 * I tried to reuse the resource allocation code in set_resource()
206 * but it is too difficult to deal with the resource allocation magic.
207 */
208
209static void create_vga_resource(device_t dev)
210{
211 struct bus *link;
212
213 /* find out which link the VGA card is connected,
214 * we only deal with the 'first' vga card */
215 for (link = dev->link_list; link; link = link->next) {
216 if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
217 break;
218 }
219
220 /* no VGA card installed */
221 if (link == NULL)
222 return;
223
224 printk(BIOS_DEBUG, "VGA: %s link %d has VGA device\n", dev_path(dev), sblink);
225 set_vga_enable_reg(0, sblink);
226}
227
228static void set_resources(device_t dev)
229{
230 struct bus *bus;
231 struct resource *res;
232
233
234 /* do we need this? */
235 create_vga_resource(dev);
236
237 /* Set each resource we have found */
238 for (res = dev->resource_list; res; res = res->next) {
239 set_resource(dev, res, 0);
240 }
241
242 for (bus = dev->link_list; bus; bus = bus->next) {
243 if (bus->children) {
244 assign_resources(bus);
245 }
246 }
247}
248
249static void northbridge_init(struct device *dev)
250{
251}
252
253static unsigned long acpi_fill_hest(acpi_hest_t *hest)
254{
255 void *addr, *current;
256
257 /* Skip the HEST header. */
258 current = (void *)(hest + 1);
259
260 addr = agesawrapper_getlateinitptr(PICK_WHEA_MCE);
261 if (addr != NULL)
262 current += acpi_create_hest_error_source(hest, current, 0, (void *)((u32)addr + 2), *(UINT16 *)addr - 2);
263
264 addr = agesawrapper_getlateinitptr(PICK_WHEA_CMC);
265 if (addr != NULL)
266 current += acpi_create_hest_error_source(hest, current, 1, (void *)((u32)addr + 2), *(UINT16 *)addr - 2);
267
268 return (unsigned long)current;
269}
270
271static void northbridge_fill_ssdt_generator(device_t device)
272{
273 msr_t msr;
274 char pscope[] = "\\_SB.PCI0";
275
276 acpigen_write_scope(pscope);
277 msr = rdmsr(TOP_MEM);
278 acpigen_write_name_dword("TOM1", msr.lo);
279 msr = rdmsr(TOP_MEM2);
280 /*
281 * Since XP only implements parts of ACPI 2.0, we can't use a qword
282 * here.
283 * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
284 * slide 22ff.
285 * Shift value right by 20 bit to make it fit into 32bit,
286 * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
287 */
288 acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
289 acpigen_pop_len();
290}
291
292static unsigned long agesa_write_acpi_tables(device_t device,
293 unsigned long current,
294 acpi_rsdp_t *rsdp)
295{
296 acpi_srat_t *srat;
297 acpi_slit_t *slit;
298 acpi_header_t *ssdt;
299 acpi_header_t *alib;
300 acpi_header_t *ivrs;
301 acpi_hest_t *hest;
302
303 /* HEST */
304 current = ALIGN(current, 8);
305 hest = (acpi_hest_t *)current;
306 acpi_write_hest((void *)current, acpi_fill_hest);
307 acpi_add_table(rsdp, (void *)current);
308 current += ((acpi_header_t *)current)->length;
309
310 current = ALIGN(current, 8);
311 printk(BIOS_DEBUG, "ACPI: * IVRS at %lx\n", current);
312 ivrs = agesawrapper_getlateinitptr(PICK_IVRS);
313 if (ivrs != NULL) {
314 memcpy((void *)current, ivrs, ivrs->length);
315 ivrs = (acpi_header_t *) current;
316 current += ivrs->length;
317 acpi_add_table(rsdp, ivrs);
318 } else {
319 printk(BIOS_DEBUG, " AGESA IVRS table NULL. Skipping.\n");
320 }
321
322 /* SRAT */
323 current = ALIGN(current, 8);
324 printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current);
325 srat = (acpi_srat_t *) agesawrapper_getlateinitptr (PICK_SRAT);
326 if (srat != NULL) {
327 memcpy((void *)current, srat, srat->header.length);
328 srat = (acpi_srat_t *) current;
329 current += srat->header.length;
330 acpi_add_table(rsdp, srat);
331 } else {
332 printk(BIOS_DEBUG, " AGESA SRAT table NULL. Skipping.\n");
333 }
334
335 /* SLIT */
336 current = ALIGN(current, 8);
337 printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current);
338 slit = (acpi_slit_t *) agesawrapper_getlateinitptr (PICK_SLIT);
339 if (slit != NULL) {
340 memcpy((void *)current, slit, slit->header.length);
341 slit = (acpi_slit_t *) current;
342 current += slit->header.length;
343 acpi_add_table(rsdp, slit);
344 } else {
345 printk(BIOS_DEBUG, " AGESA SLIT table NULL. Skipping.\n");
346 }
347
348 /* ALIB */
349 current = ALIGN(current, 16);
350 printk(BIOS_DEBUG, "ACPI: * AGESA ALIB SSDT at %lx\n", current);
351 alib = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_ALIB);
352 if (alib != NULL) {
353 memcpy((void *)current, alib, alib->length);
354 alib = (acpi_header_t *) current;
355 current += alib->length;
356 acpi_add_table(rsdp, (void *)alib);
357 }
358 else {
359 printk(BIOS_DEBUG, " AGESA ALIB SSDT table NULL. Skipping.\n");
360 }
361
362 /* this pstate ssdt may cause Blue Screen: Fixed: Keep this comment for a while. */
363 /* SSDT */
364 current = ALIGN(current, 16);
365 printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
366 ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
367 if (ssdt != NULL) {
368 memcpy((void *)current, ssdt, ssdt->length);
369 ssdt = (acpi_header_t *) current;
370 current += ssdt->length;
371 }
372 else {
373 printk(BIOS_DEBUG, " AGESA PState table NULL. Skipping.\n");
374 }
375 acpi_add_table(rsdp,ssdt);
376
377 printk(BIOS_DEBUG, "ACPI: * SSDT for PState at %lx\n", current);
378 return current;
379}
380
381static struct device_operations northbridge_operations = {
382 .read_resources = read_resources,
383 .set_resources = set_resources,
384 .enable_resources = pci_dev_enable_resources,
385 .init = northbridge_init,
386 .acpi_fill_ssdt_generator = northbridge_fill_ssdt_generator,
387 .write_acpi_tables = agesa_write_acpi_tables,
388 .enable = 0,
389 .ops_pci = 0,
390};
391
392static const struct pci_driver family15_northbridge __pci_driver = {
393 .ops = &northbridge_operations,
394 .vendor = PCI_VENDOR_ID_AMD,
395 .device = PCI_DEVICE_ID_AMD_15H_MODEL_707F_NB_HT,
396};
397
398void fam15_finalize(void *chip_info)
399{
400 device_t dev;
401 u32 value;
402 dev = dev_find_slot(0, PCI_DEVFN(0, 0)); /* clear IoapicSbFeatureEn */
403 pci_write_config32(dev, 0xF8, 0);
404 pci_write_config32(dev, 0xFC, 5); /* TODO: move it to dsdt.asl */
405
406 /* disable No Snoop */
407 dev = dev_find_slot(0, PCI_DEVFN(1, 1));
408 value = pci_read_config32(dev, 0x60);
409 value &= ~(1 << 11);
410 pci_write_config32(dev, 0x60, value);
411}
412
413void domain_read_resources(device_t dev)
414{
415 unsigned reg;
416
417 /* Find the already assigned resource pairs */
418 get_fx_dev();
419 for (reg = 0x80; reg <= 0xd8; reg += 0x08) {
420 u32 base, limit;
421 base = f1_read_config32(reg);
422 limit = f1_read_config32(reg + 0x04);
423 /* Is this register allocated? */
424 if ((base & 3) != 0) {
425 unsigned nodeid, reg_link;
426 device_t reg_dev;
427 if (reg < 0xc0) { // mmio
428 nodeid = (limit & 0xf) + (base & 0x30);
429 } else { // io
430 nodeid = (limit & 0xf) + ((base >> 4) & 0x30);
431 }
432 reg_link = (limit >> 4) & 7;
433 reg_dev = __f0_dev;
434 if (reg_dev) {
435 /* Reserve the resource */
436 struct resource *res;
437 res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
438 if (res) {
439 res->flags = 1;
440 }
441 }
442 }
443 }
444 /* FIXME: do we need to check extend conf space?
445 I don't believe that much preset value */
446
447 pci_domain_read_resources(dev);
448}
449
450void domain_enable_resources(device_t dev)
451{
452 if (acpi_is_wakeup_s3())
453 AGESAWRAPPER(fchs3laterestore);
454
455 /* Must be called after PCI enumeration and resource allocation */
456 if (!acpi_is_wakeup_s3())
457 AGESAWRAPPER(amdinitmid);
458
459 printk(BIOS_DEBUG, " ader - leaving domain_enable_resources.\n");
460}
461
462#if CONFIG_HW_MEM_HOLE_SIZEK != 0
463struct hw_mem_hole_info {
464 unsigned hole_startk;
465 int node_id;
466};
467
468static struct hw_mem_hole_info get_hw_mem_hole_info(void)
469{
470 struct hw_mem_hole_info mem_hole;
471 mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
472 mem_hole.node_id = -1;
473 dram_base_mask_t d;
474 u32 hole;
475 d = get_dram_base_mask(0);
476 hole = pci_read_config32(__f1_dev, 0xf0);
477 if (hole & 2) {
478 /* We found the hole */
479 mem_hole.hole_startk = (hole & (0xff << 24)) >> 10;
480 mem_hole.node_id = 0; // record the node # with hole
481 }
482
483 return mem_hole;
484}
485#endif
486
487void domain_set_resources(device_t dev)
488{
489 unsigned long mmio_basek;
490 u32 pci_tolm;
491 int i, idx;
492 struct bus *link;
493#if CONFIG_HW_MEM_HOLE_SIZEK != 0
494 struct hw_mem_hole_info mem_hole;
495 u32 reset_memhole = 1;
496#endif
497
498 pci_tolm = 0xffffffffUL;
499 for (link = dev->link_list; link; link = link->next) {
500 pci_tolm = find_pci_tolm(link);
501 }
502
503 mmio_basek = pci_tolm >> 10;
504 /* Round mmio_basek to something the processor can support */
505 mmio_basek &= ~((1 << 6) -1);
506
507 /* FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
508 * MMIO hole. If you fix this here, please fix amdk8, too.
509 */
510 /* Round the mmio hole to 64M */
511 mmio_basek &= ~((64 * 1024) - 1);
512
513#if CONFIG_HW_MEM_HOLE_SIZEK != 0
514 /* if the hw mem hole is already set in raminit stage, here we will compare
515 * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
516 * use hole_basek as mmio_basek and we don't need to reset hole.
517 * otherwise We reset the hole to the mmio_basek
518 */
519
520 mem_hole = get_hw_mem_hole_info();
521
522 /* Use hole_basek as mmio_basek, and we don't need to reset hole anymore */
523 if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) {
524 mmio_basek = mem_hole.hole_startk;
525 reset_memhole = 0;
526 }
527#endif
528
529 idx = 0x10;
530 for (i = 0; i < node_nums; i++) {
531 dram_base_mask_t d;
532 resource_t basek, limitk, sizek; // 4 1T
533
534 d = get_dram_base_mask(i);
535
536 if (!(d.mask & 1))
537 continue;
538 basek = ((resource_t)(d.base & 0x1fffff00)) << 9; // could overflow, we may lost 6 bit here
539 limitk = ((resource_t)(((d.mask & ~1) + 0x000FF) & 0x1fffff00)) << 9 ;
540
541 sizek = limitk - basek;
542
543 /* see if we need a hole from 0xa0000 to 0xbffff */
544 if ((basek < ((8 * 64) + (8 * 16))) && (sizek > ((8 * 64) + (16 * 16)))) {
545 ram_resource(dev, (idx | i), basek, ((8 * 64) + (8 * 16)) - basek);
546 idx += 0x10;
547 basek = (8 * 64) + (16 * 16);
548 sizek = limitk - ((8 * 64) + (16 * 16));
549
550 }
551
552 /* split the region to accommodate pci memory space */
553 if ((basek < 4 * 1024 * 1024 ) && (limitk > mmio_basek)) {
554 if (basek <= mmio_basek) {
555 unsigned pre_sizek;
556 pre_sizek = mmio_basek - basek;
557 if (pre_sizek>0) {
558 ram_resource(dev, (idx | i), basek, pre_sizek);
559 idx += 0x10;
560 sizek -= pre_sizek;
561 }
562 basek = mmio_basek;
563 }
564 if ((basek + sizek) <= 4 * 1024 * 1024) {
565 sizek = 0;
566 }
567 else {
568 uint64_t topmem2 = bsp_topmem2();
569 basek = 4 * 1024 * 1024;
570 sizek = topmem2 / 1024 - basek;
571 }
572 }
573
574 ram_resource(dev, (idx | i), basek, sizek);
575 idx += 0x10;
576 printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
577 i, mmio_basek, basek, limitk);
578 }
579
580 add_uma_resource_below_tolm(dev, 7);
581
582 for (link = dev->link_list; link; link = link->next) {
583 if (link->children) {
584 assign_resources(link);
585 }
586 }
587 /*
588 * Reserve everything between A segment and 1MB:
589 *
590 * 0xa0000 - 0xbffff: legacy VGA
591 * 0xc0000 - 0xfffff: RAM
592 */
593 mmio_resource(dev, 0xa0000, 0xa0000 / KiB, 0x20000 / KiB);
594 reserved_ram_resource(dev, 0xc0000, 0xc0000 / KiB, 0x40000 / KiB);
595}
596
597static void sysconf_init(device_t dev) // first node
598{
599 sblink = (pci_read_config32(dev, 0x64) >> 8) & 7; // don't forget sublink1
600 node_nums = ((pci_read_config32(dev, 0x60) >> 4) & 7) + 1; // NodeCnt[2:0]
601}
602
603
604void cpu_bus_scan(device_t dev)
605{
606 struct bus *cpu_bus;
607 device_t cpu;
608 device_t cdb_dev;
609 device_t dev_mc;
610 int j;
611 int core_max;
612 int core_nums;
613 int siblings;
614 int family;
615 int enable_node;
616 u32 lapicid_start;
617 u32 apic_id;
618 u32 pccount;
619
620
621 dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
622 if (!dev_mc) {
623 printk(BIOS_ERR, "%02x:%02x.0 not found", CONFIG_CBB, CONFIG_CDB);
624 die("");
625 }
626 sysconf_init(dev_mc); /* sets global node_nums */
627
628 if (node_nums != 1)
629 die("node_nums != 1. This is an SOC. Something is terribly wrong.");
630
631 /* Get max and actual number of cores */
632 pccount = cpuid_ecx(AMD_CPUID_ASIZE_PCCOUNT);
633 core_max = 1 << ((pccount >> 12) & 0xF);
634 core_nums = (pccount & 0xF);
635
636 family = (cpuid_eax(1) >> 20) & 0xFF;
637
638 cdb_dev = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 5));
639 siblings = pci_read_config32(cdb_dev, 0x84) & 0xFF;
640
641 printk(BIOS_SPEW, "%s family%xh, core_max=%d, core_nums=%d, siblings=%d\n",
642 dev_path(cdb_dev), 0x0f + family, core_max, core_nums, siblings);
643
644 /*
645 * APIC ID calucation is tightly coupled with AGESA v5 code.
646 * This calculation MUST match the assignment calculation done
647 * in LocalApicInitializationAtEarly() function.
648 * And reference GetLocalApicIdForCore()
649 *
650 * Apply apic enumeration rules
651 * For systems with >= 16 APICs, put the IO-APICs at 0..n and
652 * put the local-APICs at m..z
653 *
654 * This is needed because many IO-APIC devices only have 4 bits
655 * for their APIC id and therefore must reside at 0..15
656 */
657
658 /*
659 * While the above statement is true, we know some things about
660 * this silicon. It is an SOC and can't have >= 16 APICs, but
661 * we will start numbering at 0x10. We also know there is only
662 * on physical node (module in AMD speak).
663 */
664
665 lapicid_start = 0x10; /* Get this from devicetree? see comment above. */
666 enable_node = cdb_dev && cdb_dev->enabled;
667 cpu_bus = dev->link_list;
668
669 for (j = 0; j <= siblings; j++ ) {
670 apic_id = lapicid_start + j;
671 printk(BIOS_SPEW, "lapicid_start 0x%x, node 0x%x, core 0x%x, apicid=0x%x\n",
672 lapicid_start, node_nums, j, apic_id);
673
674 cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
675 if (cpu)
676 amd_cpu_topology(cpu, node_nums, j);
677 }
678}
679
680/*********************************************************************
681 * Change the vendor / device IDs to match the generic VBIOS header. *
682 *********************************************************************/
683u32 map_oprom_vendev(u32 vendev)
684{
685 u32 new_vendev;
686 new_vendev =
687 ((0x100298E0 <= vendev) && (vendev <= 0x100298EF)) ? 0x100298E0 : vendev;
688
689 if (vendev != new_vendev)
690 printk(BIOS_NOTICE, "Mapping PCI device %8x to %8x\n", vendev, new_vendev);
691
692 return new_vendev;
693}