blob: c06e53cffe7ac397416d42b7af46e1e237721be9 [file] [log] [blame]
zbao2c08f6a2012-07-02 15:32:58 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 Advanced Micro Devices, Inc.
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +03005 * Copyright (C) 2014 Edward O'Callaghan <eocallaghan@alterapraxis.com>
zbao2c08f6a2012-07-02 15:32:58 +08006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
zbao2c08f6a2012-07-02 15:32:58 +080015 */
16
17#include <console/console.h>
18#include <arch/io.h>
Kyösti Mälkki8ae16a42014-06-19 20:44:34 +030019#include <arch/acpi.h>
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +020020#include <arch/acpigen.h>
zbao2c08f6a2012-07-02 15:32:58 +080021#include <stdint.h>
22#include <device/device.h>
23#include <device/pci.h>
24#include <device/pci_ids.h>
25#include <device/hypertransport.h>
26#include <stdlib.h>
27#include <string.h>
Ronald G. Minnich5079a0d2012-11-27 11:32:38 -080028#include <lib.h>
zbao2c08f6a2012-07-02 15:32:58 +080029#include <cpu/cpu.h>
30#include <cbmem.h>
Martin Roth73e86a82013-01-17 16:28:30 -070031#include <AGESA.h>
zbao2c08f6a2012-07-02 15:32:58 +080032
33#include <cpu/x86/lapic.h>
Kyösti Mälkkidbc47392012-08-05 12:11:40 +030034#include <cpu/amd/mtrr.h>
zbao2c08f6a2012-07-02 15:32:58 +080035
36#include <Porting.h>
zbao2c08f6a2012-07-02 15:32:58 +080037#include <Options.h>
38#include <Topology.h>
Kyösti Mälkkid610c582017-03-05 06:28:18 +020039
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020040#include <northbridge/amd/agesa/state_machine.h>
Kyösti Mälkkid610c582017-03-05 06:28:18 +020041#include <northbridge/amd/agesa/agesa_helper.h>
zbao2c08f6a2012-07-02 15:32:58 +080042
Kyösti Mälkki113f6702018-05-20 20:12:32 +030043#define MAX_NODE_NUMS MAX_NODES
zbao2c08f6a2012-07-02 15:32:58 +080044
zbao2c08f6a2012-07-02 15:32:58 +080045typedef struct dram_base_mask {
46 u32 base; //[47:27] at [28:8]
47 u32 mask; //[47:27] at [28:8] and enable at bit 0
48} dram_base_mask_t;
49
50static unsigned node_nums;
51static unsigned sblink;
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +030052static struct device *__f0_dev[MAX_NODE_NUMS];
53static struct device *__f1_dev[MAX_NODE_NUMS];
54static struct device *__f2_dev[MAX_NODE_NUMS];
55static struct device *__f4_dev[MAX_NODE_NUMS];
zbao2c08f6a2012-07-02 15:32:58 +080056static unsigned fx_devs = 0;
57
58static dram_base_mask_t get_dram_base_mask(u32 nodeid)
59{
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +030060 struct device *dev;
zbao2c08f6a2012-07-02 15:32:58 +080061 dram_base_mask_t d;
62 dev = __f1_dev[0];
63 u32 temp;
64 temp = pci_read_config32(dev, 0x44 + (nodeid << 3)); //[39:24] at [31:16]
65 d.mask = ((temp & 0xfff80000)>>(8+3)); // mask out DramMask [26:24] too
66 temp = pci_read_config32(dev, 0x144 + (nodeid <<3)) & 0xff; //[47:40] at [7:0]
Elyes HAOUAS27e18012017-06-27 23:14:51 +020067 d.mask |= temp << 21;
zbao2c08f6a2012-07-02 15:32:58 +080068 temp = pci_read_config32(dev, 0x40 + (nodeid << 3)); //[39:24] at [31:16]
69 d.mask |= (temp & 1); // enable bit
70 d.base = ((temp & 0xfff80000)>>(8+3)); // mask out DramBase [26:24) too
71 temp = pci_read_config32(dev, 0x140 + (nodeid <<3)) & 0xff; //[47:40] at [7:0]
Elyes HAOUAS27e18012017-06-27 23:14:51 +020072 d.base |= temp << 21;
zbao2c08f6a2012-07-02 15:32:58 +080073 return d;
74}
75
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +030076static void set_io_addr_reg(struct device *dev, u32 nodeid, u32 linkn, u32 reg,
zbao2c08f6a2012-07-02 15:32:58 +080077 u32 io_min, u32 io_max)
78{
79 u32 i;
80 u32 tempreg;
81 /* io range allocation */
Elyes HAOUAS27e18012017-06-27 23:14:51 +020082 tempreg = (nodeid&0xf) | ((nodeid & 0x30)<<(8-4)) | (linkn << 4) | ((io_max&0xf0)<<(12-4)); //limit
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +020083 for (i = 0; i < node_nums; i++)
zbao2c08f6a2012-07-02 15:32:58 +080084 pci_write_config32(__f1_dev[i], reg+4, tempreg);
Elyes HAOUAS27e18012017-06-27 23:14:51 +020085 tempreg = 3 /*| (3 << 4)*/ | ((io_min&0xf0)<<(12-4)); //base :ISA and VGA ?
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +020086 for (i = 0; i < node_nums; i++)
zbao2c08f6a2012-07-02 15:32:58 +080087 pci_write_config32(__f1_dev[i], reg, tempreg);
88}
89
90static void set_mmio_addr_reg(u32 nodeid, u32 linkn, u32 reg, u32 index, u32 mmio_min, u32 mmio_max, u32 nodes)
91{
92 u32 i;
93 u32 tempreg;
94 /* io range allocation */
Elyes HAOUAS27e18012017-06-27 23:14:51 +020095 tempreg = (nodeid&0xf) | (linkn << 4) | (mmio_max&0xffffff00); //limit
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +020096 for (i = 0; i < nodes; i++)
zbao2c08f6a2012-07-02 15:32:58 +080097 pci_write_config32(__f1_dev[i], reg+4, tempreg);
98 tempreg = 3 | (nodeid & 0x30) | (mmio_min&0xffffff00);
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +020099 for (i = 0; i < node_nums; i++)
zbao2c08f6a2012-07-02 15:32:58 +0800100 pci_write_config32(__f1_dev[i], reg, tempreg);
101}
102
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300103static struct device *get_node_pci(u32 nodeid, u32 fn)
zbao2c08f6a2012-07-02 15:32:58 +0800104{
zbao2c08f6a2012-07-02 15:32:58 +0800105 return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn));
zbao2c08f6a2012-07-02 15:32:58 +0800106}
107
108static void get_fx_devs(void)
109{
110 int i;
111 for (i = 0; i < MAX_NODE_NUMS; i++) {
112 __f0_dev[i] = get_node_pci(i, 0);
113 __f1_dev[i] = get_node_pci(i, 1);
114 __f2_dev[i] = get_node_pci(i, 2);
115 __f4_dev[i] = get_node_pci(i, 4);
116 if (__f0_dev[i] != NULL && __f1_dev[i] != NULL)
117 fx_devs = i+1;
118 }
119 if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) {
120 die("Cannot find 0:0x18.[0|1]\n");
121 }
122 printk(BIOS_DEBUG, "fx_devs=0x%x\n", fx_devs);
123}
124
125static u32 f1_read_config32(unsigned reg)
126{
127 if (fx_devs == 0)
128 get_fx_devs();
129 return pci_read_config32(__f1_dev[0], reg);
130}
131
132static void f1_write_config32(unsigned reg, u32 value)
133{
134 int i;
135 if (fx_devs == 0)
136 get_fx_devs();
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200137 for (i = 0; i < fx_devs; i++) {
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300138 struct device *dev;
zbao2c08f6a2012-07-02 15:32:58 +0800139 dev = __f1_dev[i];
140 if (dev && dev->enabled) {
141 pci_write_config32(dev, reg, value);
142 }
143 }
144}
145
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300146static u32 amdfam15_nodeid(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +0800147{
zbao2c08f6a2012-07-02 15:32:58 +0800148 return (dev->path.pci.devfn >> 3) - CONFIG_CDB;
zbao2c08f6a2012-07-02 15:32:58 +0800149}
150
151static void set_vga_enable_reg(u32 nodeid, u32 linkn)
152{
153 u32 val;
154
Elyes HAOUAS27e18012017-06-27 23:14:51 +0200155 val = 1 | (nodeid << 4) | (linkn << 12);
zbao2c08f6a2012-07-02 15:32:58 +0800156 /* it will routing
157 * (1)mmio 0xa0000:0xbffff
158 * (2)io 0x3b0:0x3bb, 0x3c0:0x3df
159 */
160 f1_write_config32(0xf4, val);
161
162}
163
164/**
165 * @return
Edward O'Callaghanae5fd342014-11-20 19:58:09 +1100166 * @retval 2 resoure does not exist, usable
167 * @retval 0 resource exists, not usable
zbao2c08f6a2012-07-02 15:32:58 +0800168 * @retval 1 resource exist, resource has been allocated before
169 */
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300170static int reg_useable(unsigned reg, struct device *goal_dev, unsigned goal_nodeid,
zbao2c08f6a2012-07-02 15:32:58 +0800171 unsigned goal_link)
172{
173 struct resource *res;
174 unsigned nodeid, link = 0;
175 int result;
176 res = 0;
177 for (nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300178 struct device *dev;
zbao2c08f6a2012-07-02 15:32:58 +0800179 dev = __f0_dev[nodeid];
180 if (!dev)
181 continue;
182 for (link = 0; !res && (link < 8); link++) {
183 res = probe_resource(dev, IOINDEX(0x1000 + reg, link));
184 }
185 }
186 result = 2;
187 if (res) {
188 result = 0;
189 if ((goal_link == (link - 1)) &&
190 (goal_nodeid == (nodeid - 1)) &&
191 (res->flags <= 1)) {
192 result = 1;
193 }
194 }
195 return result;
196}
197
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300198static struct resource *amdfam15_find_iopair(struct device *dev, unsigned nodeid, unsigned link)
zbao2c08f6a2012-07-02 15:32:58 +0800199{
200 struct resource *resource;
201 u32 free_reg, reg;
202 resource = 0;
203 free_reg = 0;
204 for (reg = 0xc0; reg <= 0xd8; reg += 0x8) {
205 int result;
206 result = reg_useable(reg, dev, nodeid, link);
207 if (result == 1) {
208 /* I have been allocated this one */
209 break;
210 }
211 else if (result > 1) {
212 /* I have a free register pair */
213 free_reg = reg;
214 }
215 }
216 if (reg > 0xd8) {
217 reg = free_reg; // if no free, the free_reg still be 0
218 }
219
220 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
221
222 return resource;
223}
224
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300225static struct resource *amdfam15_find_mempair(struct device *dev, u32 nodeid, u32 link)
zbao2c08f6a2012-07-02 15:32:58 +0800226{
227 struct resource *resource;
228 u32 free_reg, reg;
229 resource = 0;
230 free_reg = 0;
231 for (reg = 0x80; reg <= 0xb8; reg += 0x8) {
232 int result;
233 result = reg_useable(reg, dev, nodeid, link);
234 if (result == 1) {
235 /* I have been allocated this one */
236 break;
237 }
238 else if (result > 1) {
239 /* I have a free register pair */
240 free_reg = reg;
241 }
242 }
243 if (reg > 0xb8) {
244 reg = free_reg;
245 }
246
247 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
248 return resource;
249}
250
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300251static void amdfam15_link_read_bases(struct device *dev, u32 nodeid, u32 link)
zbao2c08f6a2012-07-02 15:32:58 +0800252{
253 struct resource *resource;
254
255 /* Initialize the io space constraints on the current bus */
256 resource = amdfam15_find_iopair(dev, nodeid, link);
257 if (resource) {
258 u32 align;
259 align = log2(HT_IO_HOST_ALIGN);
260 resource->base = 0;
261 resource->size = 0;
262 resource->align = align;
263 resource->gran = align;
264 resource->limit = 0xffffUL;
265 resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE;
266 }
267
268 /* Initialize the prefetchable memory constraints on the current bus */
269 resource = amdfam15_find_mempair(dev, nodeid, link);
270 if (resource) {
271 resource->base = 0;
272 resource->size = 0;
273 resource->align = log2(HT_MEM_HOST_ALIGN);
274 resource->gran = log2(HT_MEM_HOST_ALIGN);
275 resource->limit = 0xffffffffffULL;
276 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
277 resource->flags |= IORESOURCE_BRIDGE;
278 }
279
280 /* Initialize the memory constraints on the current bus */
281 resource = amdfam15_find_mempair(dev, nodeid, link);
282 if (resource) {
283 resource->base = 0;
284 resource->size = 0;
285 resource->align = log2(HT_MEM_HOST_ALIGN);
286 resource->gran = log2(HT_MEM_HOST_ALIGN);
287 resource->limit = 0xffffffffffULL;
288 resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE;
289 }
290
291}
292
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300293static void nb_read_resources(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +0800294{
295 u32 nodeid;
296 struct bus *link;
297
298 nodeid = amdfam15_nodeid(dev);
299 for (link = dev->link_list; link; link = link->next) {
300 if (link->children) {
301 amdfam15_link_read_bases(dev, nodeid, link->link_num);
302 }
303 }
Steven Sherk1cbabb02013-02-01 09:22:35 -0700304
305 /*
Stefan Reinauer4aff4452013-02-12 14:17:15 -0800306 * This MMCONF resource must be reserved in the PCI domain.
Steven Sherk1cbabb02013-02-01 09:22:35 -0700307 * It is not honored by the coreboot resource allocator if it is in
Stefan Reinauer0aa37c42013-02-12 15:20:54 -0800308 * the CPU_CLUSTER.
Steven Sherk1cbabb02013-02-01 09:22:35 -0700309 */
Kyösti Mälkkie25b5ef2016-12-02 08:56:05 +0200310 mmconf_resource(dev, 0xc0010058);
zbao2c08f6a2012-07-02 15:32:58 +0800311}
312
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300313static void set_resource(struct device *dev, struct resource *resource, u32 nodeid)
zbao2c08f6a2012-07-02 15:32:58 +0800314{
315 resource_t rbase, rend;
316 unsigned reg, link_num;
317 char buf[50];
318
319 /* Make certain the resource has actually been set */
320 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
321 return;
322 }
323
324 /* If I have already stored this resource don't worry about it */
325 if (resource->flags & IORESOURCE_STORED) {
326 return;
327 }
328
329 /* Only handle PCI memory and IO resources */
330 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
331 return;
332
333 /* Ensure I am actually looking at a resource of function 1 */
334 if ((resource->index & 0xffff) < 0x1000) {
335 return;
336 }
337 /* Get the base address */
338 rbase = resource->base;
339
340 /* Get the limit (rounded up) */
341 rend = resource_end(resource);
342
343 /* Get the register and link */
344 reg = resource->index & 0xfff; // 4k
345 link_num = IOINDEX_LINK(resource->index);
346
347 if (resource->flags & IORESOURCE_IO) {
348 set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
349 }
350 else if (resource->flags & IORESOURCE_MEM) {
Edward O'Callaghanae5fd342014-11-20 19:58:09 +1100351 set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, node_nums);// [39:8]
zbao2c08f6a2012-07-02 15:32:58 +0800352 }
353 resource->flags |= IORESOURCE_STORED;
Elyes HAOUAS0d4b11a2016-10-03 21:57:21 +0200354 snprintf(buf, sizeof(buf), " <node %x link %x>",
zbao2c08f6a2012-07-02 15:32:58 +0800355 nodeid, link_num);
356 report_resource_stored(dev, resource, buf);
357}
358
359/**
360 * I tried to reuse the resource allocation code in set_resource()
361 * but it is too difficult to deal with the resource allocation magic.
362 */
363
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300364static void create_vga_resource(struct device *dev, unsigned nodeid)
zbao2c08f6a2012-07-02 15:32:58 +0800365{
366 struct bus *link;
367
368 /* find out which link the VGA card is connected,
369 * we only deal with the 'first' vga card */
370 for (link = dev->link_list; link; link = link->next) {
371 if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
Martin Roth77a58b92017-06-24 14:45:48 -0600372#if IS_ENABLED(CONFIG_MULTIPLE_VGA_ADAPTERS)
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300373 extern struct device *vga_pri; // the primary vga device, defined in device.c
zbao2c08f6a2012-07-02 15:32:58 +0800374 printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d bus range [%d,%d]\n", vga_pri->bus->secondary,
375 link->secondary,link->subordinate);
376 /* We need to make sure the vga_pri is under the link */
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +0200377 if ((vga_pri->bus->secondary >= link->secondary) &&
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300378 (vga_pri->bus->secondary <= link->subordinate))
zbao2c08f6a2012-07-02 15:32:58 +0800379#endif
380 break;
381 }
382 }
383
384 /* no VGA card installed */
385 if (link == NULL)
386 return;
387
388 printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, sblink);
389 set_vga_enable_reg(nodeid, sblink);
390}
391
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300392static void nb_set_resources(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +0800393{
394 unsigned nodeid;
395 struct bus *bus;
396 struct resource *res;
397
398 /* Find the nodeid */
399 nodeid = amdfam15_nodeid(dev);
400
401 create_vga_resource(dev, nodeid); //TODO: do we need this?
402
403 /* Set each resource we have found */
404 for (res = dev->resource_list; res; res = res->next) {
405 set_resource(dev, res, nodeid);
406 }
407
408 for (bus = dev->link_list; bus; bus = bus->next) {
409 if (bus->children) {
410 assign_resources(bus);
411 }
412 }
413}
414
Vladimir Serbinenko807127f2014-11-09 13:36:18 +0100415static unsigned long acpi_fill_hest(acpi_hest_t *hest)
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +0200416{
417 void *addr, *current;
418
419 /* Skip the HEST header. */
420 current = (void *)(hest + 1);
421
422 addr = agesawrapper_getlateinitptr(PICK_WHEA_MCE);
423 if (addr != NULL)
Stefan Reinauer77a1d1a2015-07-21 12:48:17 -0700424 current += acpi_create_hest_error_source(hest, current, 0,
425 addr + 2, *(UINT16 *)addr - 2);
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +0200426
427 addr = agesawrapper_getlateinitptr(PICK_WHEA_CMC);
428 if (addr != NULL)
Stefan Reinauer77a1d1a2015-07-21 12:48:17 -0700429 current += acpi_create_hest_error_source(hest, current, 1,
430 addr + 2, *(UINT16 *)addr - 2);
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +0200431
432 return (unsigned long)current;
433}
434
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300435static void northbridge_fill_ssdt_generator(struct device *device)
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +0200436{
437 msr_t msr;
438 char pscope[] = "\\_SB.PCI0";
439
440 acpigen_write_scope(pscope);
441 msr = rdmsr(TOP_MEM);
442 acpigen_write_name_dword("TOM1", msr.lo);
443 msr = rdmsr(TOP_MEM2);
444 /*
445 * Since XP only implements parts of ACPI 2.0, we can't use a qword
446 * here.
447 * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
448 * slide 22ff.
449 * Shift value right by 20 bit to make it fit into 32bit,
450 * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
451 */
452 acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
453 acpigen_pop_len();
454}
455
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300456static unsigned long agesa_write_acpi_tables(struct device *device,
Alexander Couzens83fc32f2015-04-12 22:28:37 +0200457 unsigned long current,
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +0200458 acpi_rsdp_t *rsdp)
459{
460 acpi_srat_t *srat;
461 acpi_slit_t *slit;
462 acpi_header_t *ssdt;
463 acpi_header_t *alib;
464 acpi_header_t *ivrs;
465 acpi_hest_t *hest;
466
467 /* HEST */
468 current = ALIGN(current, 8);
469 hest = (acpi_hest_t *)current;
Vladimir Serbinenko807127f2014-11-09 13:36:18 +0100470 acpi_write_hest((void *)current, acpi_fill_hest);
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +0200471 acpi_add_table(rsdp, (void *)current);
472 current += ((acpi_header_t *)current)->length;
473
474 current = ALIGN(current, 8);
475 printk(BIOS_DEBUG, "ACPI: * IVRS at %lx\n", current);
476 ivrs = agesawrapper_getlateinitptr(PICK_IVRS);
477 if (ivrs != NULL) {
478 memcpy((void *)current, ivrs, ivrs->length);
479 ivrs = (acpi_header_t *) current;
480 current += ivrs->length;
481 acpi_add_table(rsdp, ivrs);
482 } else {
483 printk(BIOS_DEBUG, " AGESA IVRS table NULL. Skipping.\n");
484 }
485
486 /* SRAT */
487 current = ALIGN(current, 8);
488 printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current);
489 srat = (acpi_srat_t *) agesawrapper_getlateinitptr (PICK_SRAT);
490 if (srat != NULL) {
491 memcpy((void *)current, srat, srat->header.length);
492 srat = (acpi_srat_t *) current;
493 current += srat->header.length;
494 acpi_add_table(rsdp, srat);
495 } else {
496 printk(BIOS_DEBUG, " AGESA SRAT table NULL. Skipping.\n");
497 }
498
499 /* SLIT */
500 current = ALIGN(current, 8);
501 printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current);
502 slit = (acpi_slit_t *) agesawrapper_getlateinitptr (PICK_SLIT);
503 if (slit != NULL) {
504 memcpy((void *)current, slit, slit->header.length);
505 slit = (acpi_slit_t *) current;
506 current += slit->header.length;
507 acpi_add_table(rsdp, slit);
508 } else {
509 printk(BIOS_DEBUG, " AGESA SLIT table NULL. Skipping.\n");
510 }
511
512 /* ALIB */
513 current = ALIGN(current, 16);
514 printk(BIOS_DEBUG, "ACPI: * AGESA ALIB SSDT at %lx\n", current);
515 alib = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_ALIB);
516 if (alib != NULL) {
517 memcpy((void *)current, alib, alib->length);
518 alib = (acpi_header_t *) current;
519 current += alib->length;
520 acpi_add_table(rsdp, (void *)alib);
521 }
522 else {
523 printk(BIOS_DEBUG, " AGESA ALIB SSDT table NULL. Skipping.\n");
524 }
525
526 /* this pstate ssdt may cause Blue Screen: Fixed: Keep this comment for a while. */
527 /* SSDT */
528 current = ALIGN(current, 16);
529 printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
530 ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
531 if (ssdt != NULL) {
532 memcpy((void *)current, ssdt, ssdt->length);
533 ssdt = (acpi_header_t *) current;
534 current += ssdt->length;
535 }
536 else {
537 printk(BIOS_DEBUG, " AGESA PState table NULL. Skipping.\n");
538 }
539 acpi_add_table(rsdp,ssdt);
540
541 printk(BIOS_DEBUG, "ACPI: * SSDT for PState at %lx\n", current);
542
543 return current;
544}
545
546
zbao2c08f6a2012-07-02 15:32:58 +0800547static struct device_operations northbridge_operations = {
Steven Sherkf4340582013-01-29 16:13:35 -0700548 .read_resources = nb_read_resources,
549 .set_resources = nb_set_resources,
zbao2c08f6a2012-07-02 15:32:58 +0800550 .enable_resources = pci_dev_enable_resources,
Edward O'Callaghand994ef12014-11-21 02:22:33 +1100551 .init = DEVICE_NOOP,
Vladimir Serbinenko56f46d82014-10-08 22:06:27 +0200552 .acpi_fill_ssdt_generator = northbridge_fill_ssdt_generator,
553 .write_acpi_tables = agesa_write_acpi_tables,
zbao2c08f6a2012-07-02 15:32:58 +0800554 .enable = 0,
555 .ops_pci = 0,
556};
557
558static const struct pci_driver family15_northbridge __pci_driver = {
559 .ops = &northbridge_operations,
560 .vendor = PCI_VENDOR_ID_AMD,
Marshall Dawson463f46e2016-10-14 20:46:08 -0600561 .device = PCI_DEVICE_ID_AMD_15H_MODEL_101F_NB_HT,
zbao2c08f6a2012-07-02 15:32:58 +0800562};
563
564static const struct pci_driver family10_northbridge __pci_driver = {
565 .ops = &northbridge_operations,
566 .vendor = PCI_VENDOR_ID_AMD,
567 .device = PCI_DEVICE_ID_AMD_10H_NB_HT,
568};
569
570struct chip_operations northbridge_amd_agesa_family15tn_ops = {
571 CHIP_NAME("AMD FAM15 Northbridge")
572 .enable_dev = 0,
573};
574
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300575static void domain_read_resources(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +0800576{
577 unsigned reg;
578
579 /* Find the already assigned resource pairs */
580 get_fx_devs();
581 for (reg = 0x80; reg <= 0xd8; reg+= 0x08) {
582 u32 base, limit;
583 base = f1_read_config32(reg);
584 limit = f1_read_config32(reg + 0x04);
585 /* Is this register allocated? */
586 if ((base & 3) != 0) {
587 unsigned nodeid, reg_link;
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300588 struct device *reg_dev;
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +0200589 if (reg < 0xc0) { // mmio
zbao2c08f6a2012-07-02 15:32:58 +0800590 nodeid = (limit & 0xf) + (base&0x30);
591 } else { // io
592 nodeid = (limit & 0xf) + ((base>>4)&0x30);
593 }
594 reg_link = (limit >> 4) & 7;
595 reg_dev = __f0_dev[nodeid];
596 if (reg_dev) {
597 /* Reserve the resource */
598 struct resource *res;
599 res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
600 if (res) {
601 res->flags = 1;
602 }
603 }
604 }
605 }
606 /* FIXME: do we need to check extend conf space?
607 I don't believe that much preset value */
608
zbao2c08f6a2012-07-02 15:32:58 +0800609 pci_domain_read_resources(dev);
zbao2c08f6a2012-07-02 15:32:58 +0800610}
611
zbao2c08f6a2012-07-02 15:32:58 +0800612#if CONFIG_HW_MEM_HOLE_SIZEK != 0
613struct hw_mem_hole_info {
614 unsigned hole_startk;
615 int node_id;
616};
617static struct hw_mem_hole_info get_hw_mem_hole_info(void)
618{
619 struct hw_mem_hole_info mem_hole;
620 int i;
621 mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
622 mem_hole.node_id = -1;
623 for (i = 0; i < node_nums; i++) {
624 dram_base_mask_t d;
625 u32 hole;
626 d = get_dram_base_mask(i);
627 if (!(d.mask & 1)) continue; // no memory on this node
628 hole = pci_read_config32(__f1_dev[i], 0xf0);
629 if (hole & 1) { // we find the hole
Elyes HAOUAS27e18012017-06-27 23:14:51 +0200630 mem_hole.hole_startk = (hole & (0xff << 24)) >> 10;
zbao2c08f6a2012-07-02 15:32:58 +0800631 mem_hole.node_id = i; // record the node No with hole
632 break; // only one hole
633 }
634 }
Kyösti Mälkki2f9b3af2014-06-26 05:30:54 +0300635
636 /* We need to double check if there is special set on base reg and limit reg
637 * are not continuous instead of hole, it will find out its hole_startk.
638 */
zbao2c08f6a2012-07-02 15:32:58 +0800639 if (mem_hole.node_id == -1) {
640 resource_t limitk_pri = 0;
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +0200641 for (i = 0; i < node_nums; i++) {
zbao2c08f6a2012-07-02 15:32:58 +0800642 dram_base_mask_t d;
643 resource_t base_k, limit_k;
644 d = get_dram_base_mask(i);
645 if (!(d.base & 1)) continue;
646 base_k = ((resource_t)(d.base & 0x1fffff00)) <<9;
647 if (base_k > 4 *1024 * 1024) break; // don't need to go to check
648 if (limitk_pri != base_k) { // we find the hole
649 mem_hole.hole_startk = (unsigned)limitk_pri; // must beblow 4G
650 mem_hole.node_id = i;
651 break; //only one hole
652 }
zbao15dc3cc2012-08-03 15:56:21 +0800653 limit_k = ((resource_t)(((d.mask & ~1) + 0x000FF) & 0x1fffff00)) << 9;
zbao2c08f6a2012-07-02 15:32:58 +0800654 limitk_pri = limit_k;
655 }
656 }
657 return mem_hole;
658}
659#endif
660
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300661static void domain_set_resources(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +0800662{
zbao2c08f6a2012-07-02 15:32:58 +0800663 unsigned long mmio_basek;
664 u32 pci_tolm;
665 int i, idx;
666 struct bus *link;
667#if CONFIG_HW_MEM_HOLE_SIZEK != 0
668 struct hw_mem_hole_info mem_hole;
669 u32 reset_memhole = 1;
670#endif
671
zbao2c08f6a2012-07-02 15:32:58 +0800672 pci_tolm = 0xffffffffUL;
673 for (link = dev->link_list; link; link = link->next) {
674 pci_tolm = find_pci_tolm(link);
675 }
676
677 // FIXME handle interleaved nodes. If you fix this here, please fix
678 // amdk8, too.
679 mmio_basek = pci_tolm >> 10;
680 /* Round mmio_basek to something the processor can support */
681 mmio_basek &= ~((1 << 6) -1);
682
683 // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
684 // MMIO hole. If you fix this here, please fix amdk8, too.
685 /* Round the mmio hole to 64M */
686 mmio_basek &= ~((64*1024) - 1);
687
688#if CONFIG_HW_MEM_HOLE_SIZEK != 0
689 /* if the hw mem hole is already set in raminit stage, here we will compare
690 * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
691 * use hole_basek as mmio_basek and we don't need to reset hole.
692 * otherwise We reset the hole to the mmio_basek
693 */
694
695 mem_hole = get_hw_mem_hole_info();
696
697 // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
698 if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) {
699 mmio_basek = mem_hole.hole_startk;
700 reset_memhole = 0;
701 }
702#endif
703
704 idx = 0x10;
705 for (i = 0; i < node_nums; i++) {
706 dram_base_mask_t d;
707 resource_t basek, limitk, sizek; // 4 1T
708
709 d = get_dram_base_mask(i);
710
711 if (!(d.mask & 1)) continue;
712 basek = ((resource_t)(d.base & 0x1fffff00)) << 9; // could overflow, we may lost 6 bit here
Edward O'Callaghanae5fd342014-11-20 19:58:09 +1100713 limitk = ((resource_t)(((d.mask & ~1) + 0x000FF) & 0x1fffff00)) << 9;
zbao2c08f6a2012-07-02 15:32:58 +0800714
715 sizek = limitk - basek;
716
717 /* see if we need a hole from 0xa0000 to 0xbffff */
718 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
719 ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
720 idx += 0x10;
721 basek = (8*64)+(16*16);
722 sizek = limitk - ((8*64)+(16*16));
723
724 }
725
Kyösti Mälkki26c65432014-06-26 05:30:54 +0300726 /* split the region to accommodate pci memory space */
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +0200727 if ((basek < 4*1024*1024) && (limitk > mmio_basek)) {
zbao2c08f6a2012-07-02 15:32:58 +0800728 if (basek <= mmio_basek) {
729 unsigned pre_sizek;
730 pre_sizek = mmio_basek - basek;
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +0200731 if (pre_sizek > 0) {
zbao2c08f6a2012-07-02 15:32:58 +0800732 ram_resource(dev, (idx | i), basek, pre_sizek);
733 idx += 0x10;
734 sizek -= pre_sizek;
zbao2c08f6a2012-07-02 15:32:58 +0800735 }
736 basek = mmio_basek;
737 }
738 if ((basek + sizek) <= 4*1024*1024) {
739 sizek = 0;
740 }
741 else {
Siyuan Wang29840e22013-06-04 19:56:22 +0800742 uint64_t topmem2 = bsp_topmem2();
zbao2c08f6a2012-07-02 15:32:58 +0800743 basek = 4*1024*1024;
Siyuan Wang29840e22013-06-04 19:56:22 +0800744 sizek = topmem2/1024 - basek;
zbao2c08f6a2012-07-02 15:32:58 +0800745 }
746 }
747
zbao2c08f6a2012-07-02 15:32:58 +0800748 ram_resource(dev, (idx | i), basek, sizek);
749 idx += 0x10;
zbao2c08f6a2012-07-02 15:32:58 +0800750 printk(BIOS_DEBUG, "node %d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
751 i, mmio_basek, basek, limitk);
zbao2c08f6a2012-07-02 15:32:58 +0800752 }
753
Kyösti Mälkki61be3602017-04-15 20:07:53 +0300754 add_uma_resource_below_tolm(dev, 7);
zbao2c08f6a2012-07-02 15:32:58 +0800755
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200756 for (link = dev->link_list; link; link = link->next) {
zbao2c08f6a2012-07-02 15:32:58 +0800757 if (link->children) {
758 assign_resources(link);
759 }
760 }
761}
762
763static struct device_operations pci_domain_ops = {
764 .read_resources = domain_read_resources,
765 .set_resources = domain_set_resources,
Edward O'Callaghane9e1d7a2015-01-02 15:11:49 +1100766 .init = DEVICE_NOOP,
zbao2c08f6a2012-07-02 15:32:58 +0800767 .scan_bus = pci_domain_scan_bus,
zbao2c08f6a2012-07-02 15:32:58 +0800768};
769
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300770static void sysconf_init(struct device *dev) // first node
zbao2c08f6a2012-07-02 15:32:58 +0800771{
772 sblink = (pci_read_config32(dev, 0x64)>>8) & 7; // don't forget sublink1
773 node_nums = ((pci_read_config32(dev, 0x60)>>4) & 7) + 1; //NodeCnt[2:0]
774}
775
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300776static void add_more_links(struct device *dev, unsigned total_links)
zbao2c08f6a2012-07-02 15:32:58 +0800777{
778 struct bus *link, *last = NULL;
779 int link_num;
780
781 for (link = dev->link_list; link; link = link->next)
782 last = link;
783
784 if (last) {
785 int links = total_links - last->link_num;
786 link_num = last->link_num;
787 if (links > 0) {
788 link = malloc(links*sizeof(*link));
789 if (!link)
790 die("Couldn't allocate more links!\n");
791 memset(link, 0, links*sizeof(*link));
792 last->next = link;
793 }
794 }
795 else {
796 link_num = -1;
797 link = malloc(total_links*sizeof(*link));
798 memset(link, 0, total_links*sizeof(*link));
799 dev->link_list = link;
800 }
801
802 for (link_num = link_num + 1; link_num < total_links; link_num++) {
803 link->link_num = link_num;
804 link->dev = dev;
805 link->next = link + 1;
806 last = link;
807 link = link->next;
808 }
809 last->next = NULL;
810}
811
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300812static void cpu_bus_scan(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +0800813{
814 struct bus *cpu_bus;
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300815 struct device *dev_mc;
zbao2c08f6a2012-07-02 15:32:58 +0800816#if CONFIG_CBB
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300817 struct device *pci_domain;
zbao2c08f6a2012-07-02 15:32:58 +0800818#endif
819 int i,j;
820 int coreid_bits;
821 int core_max = 0;
822 unsigned ApicIdCoreIdSize;
823 unsigned core_nums;
824 int siblings = 0;
825 unsigned int family;
826
827#if CONFIG_CBB
828 dev_mc = dev_find_slot(0, PCI_DEVFN(CONFIG_CDB, 0)); //0x00
829 if (dev_mc && dev_mc->bus) {
830 printk(BIOS_DEBUG, "%s found", dev_path(dev_mc));
831 pci_domain = dev_mc->bus->dev;
Stefan Reinauer4aff4452013-02-12 14:17:15 -0800832 if (pci_domain && (pci_domain->path.type == DEVICE_PATH_DOMAIN)) {
zbao2c08f6a2012-07-02 15:32:58 +0800833 printk(BIOS_DEBUG, "\n%s move to ",dev_path(dev_mc));
834 dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff
835 printk(BIOS_DEBUG, "%s",dev_path(dev_mc));
836 } else {
837 printk(BIOS_DEBUG, " but it is not under pci_domain directly ");
838 }
839 printk(BIOS_DEBUG, "\n");
840 }
841 dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
842 if (!dev_mc) {
843 dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
844 if (dev_mc && dev_mc->bus) {
845 printk(BIOS_DEBUG, "%s found\n", dev_path(dev_mc));
846 pci_domain = dev_mc->bus->dev;
Stefan Reinauer4aff4452013-02-12 14:17:15 -0800847 if (pci_domain && (pci_domain->path.type == DEVICE_PATH_DOMAIN)) {
zbao2c08f6a2012-07-02 15:32:58 +0800848 if ((pci_domain->link_list) && (pci_domain->link_list->children == dev_mc)) {
849 printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc));
850 dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff
851 printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc));
852 while (dev_mc) {
853 printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc));
854 dev_mc->path.pci.devfn -= PCI_DEVFN(0x18,0);
855 printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc));
856 dev_mc = dev_mc->sibling;
857 }
858 }
859 }
860 }
861 }
862#endif
863 dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
864 if (!dev_mc) {
865 printk(BIOS_ERR, "%02x:%02x.0 not found", CONFIG_CBB, CONFIG_CDB);
866 die("");
867 }
868 sysconf_init(dev_mc);
869#if CONFIG_CBB && (MAX_NODE_NUMS > 32)
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +0200870 if (node_nums > 32) { // need to put node 32 to node 63 to bus 0xfe
zbao2c08f6a2012-07-02 15:32:58 +0800871 if (pci_domain->link_list && !pci_domain->link_list->next) {
872 struct bus *new_link = new_link(pci_domain);
873 pci_domain->link_list->next = new_link;
874 new_link->link_num = 1;
875 new_link->dev = pci_domain;
876 new_link->children = 0;
877 printk(BIOS_DEBUG, "%s links now 2\n", dev_path(pci_domain));
878 }
879 pci_domain->link_list->next->secondary = CONFIG_CBB - 1;
880 }
881#endif
882
883 /* Get Max Number of cores(MNC) */
Kyösti Mälkkid41feed2017-09-24 16:23:57 +0300884 coreid_bits = (cpuid_ecx(0x80000008) & 0x0000F000) >> 12;
zbao2c08f6a2012-07-02 15:32:58 +0800885 core_max = 1 << (coreid_bits & 0x000F); //mnc
886
887 ApicIdCoreIdSize = ((cpuid_ecx(0x80000008)>>12) & 0xF);
888 if (ApicIdCoreIdSize) {
889 core_nums = (1 << ApicIdCoreIdSize) - 1;
890 } else {
891 core_nums = 3; //quad core
892 }
893
894 /* Find which cpus are present */
895 cpu_bus = dev->link_list;
896 for (i = 0; i < node_nums; i++) {
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300897 struct device *cdb_dev;
zbao2c08f6a2012-07-02 15:32:58 +0800898 unsigned busn, devn;
899 struct bus *pbus;
900
901 busn = CONFIG_CBB;
902 devn = CONFIG_CDB + i;
903 pbus = dev_mc->bus;
904#if CONFIG_CBB && (MAX_NODE_NUMS > 32)
905 if (i >= 32) {
906 busn--;
907 devn -= 32;
908 pbus = pci_domain->link_list->next;
909 }
910#endif
911
912 /* Find the cpu's pci device */
913 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0));
914 if (!cdb_dev) {
915 /* If I am probing things in a weird order
916 * ensure all of the cpu's pci devices are found.
917 */
918 int fn;
Elyes HAOUAS5a7e72f2016-08-23 21:36:02 +0200919 for (fn = 0; fn <= 5; fn++) { //FBDIMM?
zbao2c08f6a2012-07-02 15:32:58 +0800920 cdb_dev = pci_probe_dev(NULL, pbus,
921 PCI_DEVFN(devn, fn));
922 }
923 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0));
924 } else {
925 /* Ok, We need to set the links for that device.
926 * otherwise the device under it will not be scanned
927 */
Kyösti Mälkki2a2d6132015-02-04 13:25:37 +0200928 add_more_links(cdb_dev, 4);
zbao2c08f6a2012-07-02 15:32:58 +0800929 }
930
931 family = cpuid_eax(1);
932 family = (family >> 20) & 0xFF;
933 if (family == 1) { //f10
934 u32 dword;
935 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 3));
936 dword = pci_read_config32(cdb_dev, 0xe8);
937 siblings = ((dword & BIT15) >> 13) | ((dword & (BIT13 | BIT12)) >> 12);
938 } else if (family == 6) {//f15
939 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 5));
940 if (cdb_dev && cdb_dev->enabled) {
941 siblings = pci_read_config32(cdb_dev, 0x84);
942 siblings &= 0xFF;
943 }
944 } else {
945 siblings = 0; //default one core
946 }
Kyösti Mälkkicd9fc1a2012-07-06 19:02:56 +0300947 int enable_node = cdb_dev && cdb_dev->enabled;
zbao2c08f6a2012-07-02 15:32:58 +0800948 printk(BIOS_SPEW, "%s family%xh, core_max=0x%x, core_nums=0x%x, siblings=0x%x\n",
949 dev_path(cdb_dev), 0x0f + family, core_max, core_nums, siblings);
950
Elyes HAOUAS1d8daa62016-09-18 08:50:54 +0200951 for (j = 0; j <= siblings; j++) {
zbao2c08f6a2012-07-02 15:32:58 +0800952 extern CONST OPTIONS_CONFIG_TOPOLOGY ROMDATA TopologyConfiguration;
953 u32 modules = TopologyConfiguration.PlatformNumberOfModules;
954 u32 lapicid_start = 0;
955
zbao2c08f6a2012-07-02 15:32:58 +0800956 /*
957 * APIC ID calucation is tightly coupled with AGESA v5 code.
958 * This calculation MUST match the assignment calculation done
959 * in LocalApicInitializationAtEarly() function.
960 * And reference GetLocalApicIdForCore()
961 *
962 * Apply apic enumeration rules
963 * For systems with >= 16 APICs, put the IO-APICs at 0..n and
964 * put the local-APICs at m..z
965 *
966 * This is needed because many IO-APIC devices only have 4 bits
967 * for their APIC id and therefore must reside at 0..15
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +0200968 */
Kyösti Mälkki50036322016-05-18 13:35:21 +0300969
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +0200970 u8 plat_num_io_apics = 3; /* FIXME */
Kyösti Mälkki50036322016-05-18 13:35:21 +0300971
972 if ((node_nums * core_max) + plat_num_io_apics >= 0x10) {
973 lapicid_start = (plat_num_io_apics - 1) / core_max;
zbao2c08f6a2012-07-02 15:32:58 +0800974 lapicid_start = (lapicid_start + 1) * core_max;
975 printk(BIOS_SPEW, "lpaicid_start=0x%x ", lapicid_start);
976 }
Kyösti Mälkkic33f1e92012-08-07 17:12:11 +0300977 u32 apic_id = (lapicid_start * (i/modules + 1)) + ((i % modules) ? (j + (siblings + 1)) : j);
zbao2c08f6a2012-07-02 15:32:58 +0800978 printk(BIOS_SPEW, "node 0x%x core 0x%x apicid=0x%x\n",
Kyösti Mälkkic33f1e92012-08-07 17:12:11 +0300979 i, j, apic_id);
zbao2c08f6a2012-07-02 15:32:58 +0800980
Kyösti Mälkkie2c2a4c2018-05-20 20:59:52 +0300981 struct device *cpu = add_cpu_device(cpu_bus, apic_id, enable_node);
Kyösti Mälkkic33f1e92012-08-07 17:12:11 +0300982 if (cpu)
983 amd_cpu_topology(cpu, i, j);
zbao2c08f6a2012-07-02 15:32:58 +0800984 } //j
985 }
zbao2c08f6a2012-07-02 15:32:58 +0800986}
987
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +0300988static void cpu_bus_init(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +0800989{
990 initialize_cpus(dev->link_list);
991}
992
zbao2c08f6a2012-07-02 15:32:58 +0800993static struct device_operations cpu_bus_ops = {
Edward O'Callaghan2837ab22014-11-06 08:57:40 +1100994 .read_resources = DEVICE_NOOP,
995 .set_resources = DEVICE_NOOP,
Edward O'Callaghan812d2a42014-10-31 08:17:23 +1100996 .enable_resources = DEVICE_NOOP,
zbao2c08f6a2012-07-02 15:32:58 +0800997 .init = cpu_bus_init,
998 .scan_bus = cpu_bus_scan,
999};
1000
1001static void root_complex_enable_dev(struct device *dev)
1002{
Kyösti Mälkki87213b62012-08-27 20:00:33 +03001003 static int done = 0;
1004
Kyösti Mälkki87213b62012-08-27 20:00:33 +03001005 if (!done) {
1006 setup_bsp_ramtop();
Kyösti Mälkki87213b62012-08-27 20:00:33 +03001007 done = 1;
1008 }
1009
zbao2c08f6a2012-07-02 15:32:58 +08001010 /* Set the operations if it is a special bus type */
Stefan Reinauer4aff4452013-02-12 14:17:15 -08001011 if (dev->path.type == DEVICE_PATH_DOMAIN) {
zbao2c08f6a2012-07-02 15:32:58 +08001012 dev->ops = &pci_domain_ops;
Stefan Reinauer0aa37c42013-02-12 15:20:54 -08001013 } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
zbao2c08f6a2012-07-02 15:32:58 +08001014 dev->ops = &cpu_bus_ops;
1015 }
1016}
1017
1018struct chip_operations northbridge_amd_agesa_family15tn_root_complex_ops = {
Kyösti Mälkki2900d4b2017-07-25 14:55:29 +03001019 CHIP_NAME("AMD Family 15tn Root Complex")
zbao2c08f6a2012-07-02 15:32:58 +08001020 .enable_dev = root_complex_enable_dev,
1021};
Dave Frodincbf3d402012-12-05 08:20:12 -07001022
Edward O'Callaghanae5fd342014-11-20 19:58:09 +11001023/*********************************************************************
1024 * Change the vendor / device IDs to match the generic VBIOS header. *
1025 *********************************************************************/
Dave Frodincbf3d402012-12-05 08:20:12 -07001026u32 map_oprom_vendev(u32 vendev)
1027{
Edward O'Callaghanae5fd342014-11-20 19:58:09 +11001028 u32 new_vendev = vendev;
Dave Frodincbf3d402012-12-05 08:20:12 -07001029
1030 switch(vendev) {
Bruce Griffith42e11f52013-07-08 18:19:08 -06001031 case 0x10029900: /* AMD Radeon HD 7660G (Trinity) */
1032 case 0x10029901: /* AMD Radeon HD 7660D (Trinity) */
1033 case 0x10029903: /* AMD Radeon HD 7640G (Trinity) */
1034 case 0x10029904: /* AMD Radeon HD 7560D (Trinity) */
1035 case 0x10029907: /* AMD Radeon HD 7620G (Trinity) */
1036 case 0x10029908: /* AMD Radeon HD 7600G (Trinity) */
1037 case 0x1002990A: /* AMD Radeon HD 7500G (Trinity) */
1038 case 0x1002990B: /* AMD Radeon HD 8650G (Richland) */
1039 case 0x1002990C: /* AMD Radeon HD 8670D (Richland) */
1040 case 0x1002990D: /* AMD Radeon HD 8550G (Richland) */
1041 case 0x1002990E: /* AMD Radeon HD 8570D (Richland) */
1042 case 0x1002990F: /* AMD Radeon HD 8610G (Richland) */
1043 case 0x10029910: /* AMD Radeon HD 7660G (Trinity) */
1044 case 0x10029913: /* AMD Radeon HD 7640G (Trinity) */
1045 case 0x10029917: /* AMD Radeon HD 7620G (Trinity) */
1046 case 0x10029918: /* AMD Radeon HD 7600G (Trinity) */
1047 case 0x10029919: /* AMD Radeon HD 7500G (Trinity) */
1048 case 0x10029990: /* AMD Radeon HD 7520G (Trinity) */
1049 case 0x10029991: /* AMD Radeon HD 7540D (Trinity) */
1050 case 0x10029992: /* AMD Radeon HD 7420G (Trinity) */
1051 case 0x10029993: /* AMD Radeon HD 7480D (Trinity) */
1052 case 0x10029994: /* AMD Radeon HD 7400G (Trinity) */
1053 case 0x10029995: /* AMD Radeon HD 8450G (Richland) */
1054 case 0x10029996: /* AMD Radeon HD 8470D (Richland) */
1055 case 0x10029997: /* AMD Radeon HD 8350G (Richland) */
1056 case 0x10029998: /* AMD Radeon HD 8370D (Richland) */
1057 case 0x10029999: /* AMD Radeon HD 8510G (Richland) */
1058 case 0x1002999A: /* AMD Radeon HD 8410G (Richland) */
1059 case 0x1002999B: /* AMD Radeon HD 8310G (Richland) */
1060 case 0x1002999C: /* AMD Radeon HD 8650D (Richland) */
1061 case 0x1002999D: /* AMD Radeon HD 8550D (Richland) */
1062 case 0x100299A0: /* AMD Radeon HD 7520G (Trinity) */
1063 case 0x100299A2: /* AMD Radeon HD 7420G (Trinity) */
1064 case 0x100299A4: /* AMD Radeon HD 7400G (Trinity) */
Edward O'Callaghanae5fd342014-11-20 19:58:09 +11001065 new_vendev = 0x10029901;
Dave Frodincbf3d402012-12-05 08:20:12 -07001066 break;
1067 }
1068
1069 return new_vendev;
1070}