blob: 45627cee44cdccc4990f20df6b667e9875e7f355 [file] [log] [blame]
Frank Vibrans39fca802011-02-14 18:35:15 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <console/console.h>
21#include <arch/io.h>
22#include <stdint.h>
23#include <device/device.h>
24#include <device/pci.h>
25#include <device/pci_ids.h>
26#include <device/hypertransport.h>
27#include <stdlib.h>
28#include <string.h>
29#include <bitops.h>
30#include <cpu/cpu.h>
31
32#include <cpu/x86/lapic.h>
33
34#include "chip.h"
35#include "northbridge.h"
36
37
38//#define FX_DEVS NODE_NUMS
39#define FX_DEVS 1
40
41static device_t __f0_dev[FX_DEVS];
42static device_t __f1_dev[FX_DEVS];
43static device_t __f2_dev[FX_DEVS];
44static device_t __f4_dev[FX_DEVS];
45static unsigned fx_devs=0;
46
47
48device_t get_node_pci(u32 nodeid, u32 fn)
49{
50 return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn));
51}
52
53
54static void get_fx_devs(void)
55{
56 int i;
57 for(i = 0; i < FX_DEVS; i++) {
58 __f0_dev[i] = get_node_pci(i, 0);
59 __f1_dev[i] = get_node_pci(i, 1);
60 __f2_dev[i] = get_node_pci(i, 2);
61 __f4_dev[i] = get_node_pci(i, 4);
62 if (__f0_dev[i] != NULL && __f1_dev[i] != NULL)
63 fx_devs = i+1;
64 }
65 if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) {
66 die("Cannot find 0:0x18.[0|1]\n");
67 }
68}
69
70
71static u32 f1_read_config32(unsigned reg)
72{
73 if (fx_devs == 0)
74 get_fx_devs();
75 return pci_read_config32(__f1_dev[0], reg);
76}
77
78
79static void f1_write_config32(unsigned reg, u32 value)
80{
81 int i;
82 if (fx_devs == 0)
83 get_fx_devs();
84 for(i = 0; i < fx_devs; i++) {
85 device_t dev;
86 dev = __f1_dev[i];
87 if (dev && dev->enabled) {
88 pci_write_config32(dev, reg, value);
89 }
90 }
91}
92
93
94static u32 amdfam14_nodeid(device_t dev)
95{
96 return (dev->path.pci.devfn >> 3) - CONFIG_CDB;
97}
98
99
100#include "amdfam14_conf.c"
101
102
103static void northbridge_init(device_t dev)
104{
105 printk(BIOS_DEBUG, "Northbridge init\n");
106}
107
108
109static void set_vga_enable_reg(u32 nodeid, u32 linkn)
110{
111 u32 val;
112
113 val = 1 | (nodeid<<4) | (linkn<<12);
114 /* it will routing (1)mmio 0xa0000:0xbffff (2) io 0x3b0:0x3bb,
115 0x3c0:0x3df */
116 f1_write_config32(0xf4, val);
117
118}
119
120
121static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid,
122 unsigned goal_link)
123{
124 struct resource *res;
125 unsigned nodeid, link = 0;
126 int result;
127 res = 0;
128 for(nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
129 device_t dev;
130 dev = __f0_dev[nodeid];
131 if (!dev)
132 continue;
133 for(link = 0; !res && (link < 8); link++) {
134 res = probe_resource(dev, IOINDEX(0x1000 + reg, link));
135 }
136 }
137 result = 2;
138 if (res) {
139 result = 0;
140 if ( (goal_link == (link - 1)) &&
141 (goal_nodeid == (nodeid - 1)) &&
142 (res->flags <= 1)) {
143 result = 1;
144 }
145 }
146 return result;
147}
148
149static struct resource *amdfam14_find_iopair(device_t dev, unsigned nodeid, unsigned link)
150{
151 struct resource *resource;
152 u32 result, reg;
153 resource = 0;
154 reg = 0;
155 result = reg_useable(0xc0, dev, nodeid, link);
156 if (result >= 1) {
157 /* I have been allocated this one */
158 reg = 0xc0;
159 }
160
161 //Ext conf space
162 if(!reg) {
163 //because of Extend conf space, we will never run out of reg, but we need one index to differ them. so same node and same link can have multi range
164 u32 index = get_io_addr_index(nodeid, link);
165 reg = 0x110+ (index<<24) + (4<<20); // index could be 0, 255
166 }
167
168 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
169
170 return resource;
171}
172
173static struct resource *amdfam14_find_mempair(device_t dev, u32 nodeid, u32 link)
174{
175 struct resource *resource;
176 u32 free_reg, reg;
177 resource = 0;
178 free_reg = 0;
179 for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
180 int result;
181 result = reg_useable(reg, dev, nodeid, link);
182 if (result == 1) {
183 /* I have been allocated this one */
184 break;
185 }
186 else if (result > 1) {
187 /* I have a free register pair */
188 free_reg = reg;
189 }
190 }
191 if (reg > 0xb8) {
192 reg = free_reg;
193 }
194
195 //Ext conf space
196 if(!reg) {
197 //because of Extend conf space, we will never run out of reg,
198 // but we need one index to differ them. so same node and
199 // same link can have multi range
200 u32 index = get_mmio_addr_index(nodeid, link);
201 reg = 0x110+ (index<<24) + (6<<20); // index could be 0, 63
202
203 }
204 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
205 return resource;
206}
207
208
209static void amdfam14_link_read_bases(device_t dev, u32 nodeid, u32 link)
210{
211 struct resource *resource;
212
213 /* Initialize the io space constraints on the current bus */
214 resource = amdfam14_find_iopair(dev, nodeid, link);
215 if (resource) {
216 u32 align;
217#if CONFIG_EXT_CONF_SUPPORT == 1
218 if((resource->index & 0x1fff) == 0x1110) { // ext
219 align = 8;
220 }
221 else
222#endif
223 align = log2(HT_IO_HOST_ALIGN);
224 resource->base = 0;
225 resource->size = 0;
226 resource->align = align;
227 resource->gran = align;
228 resource->limit = 0xffffUL;
229 resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE;
230 }
231
232 /* Initialize the prefetchable memory constraints on the current bus */
233 resource = amdfam14_find_mempair(dev, nodeid, link);
234 if (resource) {
235 resource->base = 0;
236 resource->size = 0;
237 resource->align = log2(HT_MEM_HOST_ALIGN);
238 resource->gran = log2(HT_MEM_HOST_ALIGN);
239 resource->limit = 0xffffffffffULL;
240 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
241 resource->flags |= IORESOURCE_BRIDGE;
242
243#if CONFIG_EXT_CONF_SUPPORT == 1
244 if((resource->index & 0x1fff) == 0x1110) { // ext
245 normalize_resource(resource);
246 }
247#endif
248
249 }
250
251 /* Initialize the memory constraints on the current bus */
252 resource = amdfam14_find_mempair(dev, nodeid, link);
253 if (resource) {
254 resource->base = 0;
255 resource->size = 0;
256 resource->align = log2(HT_MEM_HOST_ALIGN);
257 resource->gran = log2(HT_MEM_HOST_ALIGN);
258 resource->limit = 0xffffffffffULL;
259 resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE;
260#if CONFIG_EXT_CONF_SUPPORT == 1
261 if((resource->index & 0x1fff) == 0x1110) { // ext
262 normalize_resource(resource);
263 }
264#endif
265 }
266}
267
268static u32 my_find_pci_tolm(struct bus *bus, u32 tolm)
269{
270 struct resource *min;
271 min = 0;
272 search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
273 if (min && tolm > min->base) {
274 tolm = min->base;
275 }
276 return tolm;
277}
278
279#if CONFIG_HW_MEM_HOLE_SIZEK != 0
280
281struct hw_mem_hole_info {
282 unsigned hole_startk;
283 int node_id;
284};
285
286static struct hw_mem_hole_info get_hw_mem_hole_info(void)
287{
288 struct hw_mem_hole_info mem_hole;
289 int i;
290
291 mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
292 mem_hole.node_id = -1;
293
294 struct dram_base_mask_t d;
295 u32 hole;
296 d = get_dram_base_mask(0);
297 if(d.mask & 1) {
298 hole = pci_read_config32(__f1_dev[0], 0xf0);
299 if(hole & 1) { // we find the hole
300 mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
301 mem_hole.node_id = 0; // record the node No with hole
302 }
303 }
304
305#if 0
306 // We need to double check if there is speical set on base reg and limit reg
307 // are not continous instead of hole, it will find out it's hole_startk
308 if(mem_hole.node_id==-1) {
309 resource_t limitk_pri = 0;
310 struct dram_base_mask_t d;
311 resource_t base_k, limit_k;
312 d = get_dram_base_mask(0);
313 if(d.base & 1) {
314 base_k = ((resource_t)(d.base & 0x1fffff00)) <<9;
315 if(base_k <= 4 *1024 * 1024) {
316 if(limitk_pri != base_k) { // we find the hole
317 mem_hole.hole_startk = (unsigned)limitk_pri; // must be below 4G
318 mem_hole.node_id = 0;
319 }
320 }
321
322 limit_k = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9;
323 limitk_pri = limit_k;
324 }
325 }
326#endif
327
328 return mem_hole;
329}
330#endif
331
332#if CONFIG_WRITE_HIGH_TABLES==1
333#define HIGH_TABLES_SIZE 64 // maximum size of high tables in KB
334extern uint64_t high_tables_base, high_tables_size;
335#endif
336
337#if CONFIG_GFXUMA == 1
338extern uint64_t uma_memory_base, uma_memory_size;
339
340static void add_uma_resource(struct device *dev, int index)
341{
342 struct resource *resource;
343
344 printk(BIOS_DEBUG, "\nFam14h - Adding UMA memory.\n");
345
346 resource = new_resource(dev, index);
347 resource->base = (resource_t) uma_memory_base;
348 resource->size = (resource_t) uma_memory_size;
349 resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
350 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
351}
352#endif
353
354static void read_resources(device_t dev)
355{
356 u32 nodeid;
357 struct bus *link;
358
359 printk(BIOS_DEBUG, "\nFam14h - read_resources.\n");
360
361 nodeid = amdfam14_nodeid(dev);
362 for(link = dev->link_list; link; link = link->next) {
363 if (link->children) {
364 amdfam14_link_read_bases(dev, nodeid, link->link_num);
365 }
366 }
367}
368
369
370static void set_resource(device_t dev, struct resource *resource,
371 u32 nodeid)
372{
373 resource_t rbase, rend;
374 unsigned reg, link_num;
375 char buf[50];
376
377 printk(BIOS_DEBUG, "\nFam14h - set_resource.\n");
378
379 /* Make certain the resource has actually been set */
380 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
381 return;
382 }
383
384 /* If I have already stored this resource don't worry about it */
385 if (resource->flags & IORESOURCE_STORED) {
386 return;
387 }
388
389 /* Only handle PCI memory and IO resources */
390 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
391 return;
392
393 /* Ensure I am actually looking at a resource of function 1 */
394 if ((resource->index & 0xffff) < 0x1000) {
395 return;
396 }
397 /* Get the base address */
398 rbase = resource->base;
399
400 /* Get the limit (rounded up) */
401 rend = resource_end(resource);
402
403 /* Get the register and link */
404 reg = resource->index & 0xfff; // 4k
405 link_num = IOINDEX_LINK(resource->index);
406
407 if (resource->flags & IORESOURCE_IO) {
408 set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8);
409 }
410 else if (resource->flags & IORESOURCE_MEM) {
411 set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, 1) ;// [39:8]
412 }
413 resource->flags |= IORESOURCE_STORED;
414 sprintf(buf, " <node %x link %x>",
415 nodeid, link_num);
416 report_resource_stored(dev, resource, buf);
417}
418
419
420#if CONFIG_CONSOLE_VGA_MULTI == 1
421extern device_t vga_pri; // the primary vga device, defined in device.c
422#endif
423
424static void create_vga_resource(device_t dev, unsigned nodeid)
425{
426 struct bus *link;
427
428 printk(BIOS_DEBUG, "\nFam14h - create_vga_resource.\n");
429
430 /* find out which link the VGA card is connected,
431 * we only deal with the 'first' vga card */
432 for (link = dev->link_list; link; link = link->next) {
433 if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
434#if CONFIG_CONSOLE_VGA_MULTI == 1
435 printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d bus range [%d,%d]\n", vga_pri->bus->secondary,
436 link->secondary,link->subordinate);
437 /* We need to make sure the vga_pri is under the link */
438 if((vga_pri->bus->secondary >= link->secondary ) &&
439 (vga_pri->bus->secondary <= link->subordinate )
440 )
441#endif
442 break;
443 }
444 }
445
446 /* no VGA card installed */
447 if (link == NULL)
448 return;
449
450 printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link->link_num);
451 set_vga_enable_reg(nodeid, link->link_num);
452}
453
454
455static void set_resources(device_t dev)
456{
457 unsigned nodeid;
458 struct bus *bus;
459 struct resource *res;
460
461 printk(BIOS_DEBUG, "\nFam14h - set_resources.\n");
462
463 /* Find the nodeid */
464 nodeid = amdfam14_nodeid(dev);
465
466 create_vga_resource(dev, nodeid);
467
468 /* Set each resource we have found */
469 for(res = dev->resource_list; res; res = res->next) {
470 set_resource(dev, res, nodeid);
471 }
472
473 for(bus = dev->link_list; bus; bus = bus->next) {
474 if (bus->children) {
475 assign_resources(bus);
476 }
477 }
478}
479
480
481/* Domain/Root Complex related code */
482
483static void domain_read_resources(device_t dev)
484{
485 unsigned reg;
486
487 printk(BIOS_DEBUG, "\nFam14h - domain_read_resources.\n");
488
489 /* Find the already assigned resource pairs */
490 get_fx_devs();
491 for(reg = 0x80; reg <= 0xc0; reg+= 0x08) {
492 u32 base, limit;
493 base = f1_read_config32(reg);
494 limit = f1_read_config32(reg + 0x04);
495 /* Is this register allocated? */
496 if ((base & 3) != 0) {
497 unsigned nodeid, reg_link;
498 device_t reg_dev;
499 if(reg<0xc0) { // mmio
500 nodeid = (limit & 0xf) + (base&0x30);
501 } else { // io
502 nodeid = (limit & 0xf) + ((base>>4)&0x30);
503 }
504 reg_link = (limit >> 4) & 7;
505 reg_dev = __f0_dev[nodeid];
506 if (reg_dev) {
507 /* Reserve the resource */
508 struct resource *res;
509 res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
510 if (res) {
511 res->flags = 1;
512 }
513 }
514 }
515 }
516 /* FIXME: do we need to check extend conf space?
517 I don't believe that much preset value */
518
519#if CONFIG_PCI_64BIT_PREF_MEM == 0
520 pci_domain_read_resources(dev);
521#else
522 struct bus *link;
523 struct resource *resource;
524 for(link=dev->link_list; link; link = link->next) {
525 /* Initialize the system wide io space constraints */
526 resource = new_resource(dev, 0|(link->link_num<<2));
527 resource->base = 0x400;
528 resource->limit = 0xffffUL;
529 resource->flags = IORESOURCE_IO;
530
531 /* Initialize the system wide prefetchable memory resources constraints */
532 resource = new_resource(dev, 1|(link->link_num<<2));
533 resource->limit = 0xfcffffffffULL;
534 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
535
536 /* Initialize the system wide memory resources constraints */
537 resource = new_resource(dev, 2|(link->link_num<<2));
538 resource->limit = 0xfcffffffffULL;
539 resource->flags = IORESOURCE_MEM;
540 }
541#endif
542}
543
544
545static void domain_set_resources(device_t dev)
546{
547 printk(BIOS_DEBUG, "\nFam14h - domain_set_resources.\n");
548 printk(BIOS_DEBUG, " amsr - incoming dev = %08lx\n",dev);
549
550#if CONFIG_PCI_64BIT_PREF_MEM == 1
551 struct resource *io, *mem1, *mem2;
552 struct resource *res;
553#endif
554 unsigned long mmio_basek;
555 u32 pci_tolm;
556 int i, idx;
557 struct bus *link;
558#if CONFIG_HW_MEM_HOLE_SIZEK != 0
559 struct hw_mem_hole_info mem_hole;
560 u32 reset_memhole = 1;
561#endif
562
563#if CONFIG_PCI_64BIT_PREF_MEM == 1
564
565printk(BIOS_DEBUG, "adsr - CONFIG_PCI_64BIT_PREF_MEM is true.\n");
566 for(link = dev->link_list; link; link = link->next) {
567 /* Now reallocate the pci resources memory with the
568 * highest addresses I can manage.
569 */
570 mem1 = find_resource(dev, 1|(link->link_num<<2));
571 mem2 = find_resource(dev, 2|(link->link_num<<2));
572
573 printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
574 mem1->base, mem1->limit, mem1->size, mem1->align);
575 printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
576 mem2->base, mem2->limit, mem2->size, mem2->align);
577
578 /* See if both resources have roughly the same limits */
579 if (((mem1->limit <= 0xffffffff) && (mem2->limit <= 0xffffffff)) ||
580 ((mem1->limit > 0xffffffff) && (mem2->limit > 0xffffffff)))
581 {
582 /* If so place the one with the most stringent alignment first
583 */
584 if (mem2->align > mem1->align) {
585 struct resource *tmp;
586 tmp = mem1;
587 mem1 = mem2;
588 mem2 = tmp;
589 }
590 /* Now place the memory as high up as it will go */
591 mem2->base = resource_max(mem2);
592 mem1->limit = mem2->base - 1;
593 mem1->base = resource_max(mem1);
594 }
595 else {
596 /* Place the resources as high up as they will go */
597 mem2->base = resource_max(mem2);
598 mem1->base = resource_max(mem1);
599 }
600
601 printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
602 mem1->base, mem1->limit, mem1->size, mem1->align);
603 printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
604 mem2->base, mem2->limit, mem2->size, mem2->align);
605 }
606
607 for(res = &dev->resource_list; res; res = res->next)
608 {
609 res->flags |= IORESOURCE_ASSIGNED;
610 res->flags |= IORESOURCE_STORED;
611 report_resource_stored(dev, res, "");
612 }
613#endif
614
615 pci_tolm = 0xffffffffUL;
616 for(link = dev->link_list; link; link = link->next) {
617 pci_tolm = my_find_pci_tolm(link, pci_tolm);
618 }
619
620 // FIXME handle interleaved nodes. If you fix this here, please fix
621 // amdk8, too.
622 mmio_basek = pci_tolm >> 10;
623 /* Round mmio_basek to something the processor can support */
624 mmio_basek &= ~((1 << 6) -1);
625
626 // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
627 // MMIO hole. If you fix this here, please fix amdk8, too.
628 /* Round the mmio hole to 64M */
629 mmio_basek &= ~((64*1024) - 1);
630
631#if CONFIG_HW_MEM_HOLE_SIZEK != 0
632/* if the hw mem hole is already set in raminit stage, here we will compare
633 * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
634 * use hole_basek as mmio_basek and we don't need to reset hole.
635 * otherwise We reset the hole to the mmio_basek
636 */
637
638 mem_hole = get_hw_mem_hole_info();
639
640 // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
641 if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) {
642 mmio_basek = mem_hole.hole_startk;
643 reset_memhole = 0;
644 }
645#endif
646
647 idx = 0x10;
648
649 struct dram_base_mask_t d;
650 resource_t basek, limitk, sizek; // 4 1T
651
652 d = get_dram_base_mask(0);
653
654 if (d.mask & 1) {
655 basek = ((resource_t)(d.base)) << 8;
656 limitk = (resource_t)((d.mask << 8) | 0xFFFFFF);
657printk(BIOS_DEBUG, "adsr: (before) basek = %llx, limitk = %llx.\n",basek,limitk);
658
659 /* Convert these values to multiples of 1K for ease of math. */
660 basek >>= 10;
661 limitk >>= 10;
662 sizek = limitk - basek + 1;
663
664printk(BIOS_DEBUG, "adsr: (after) basek = %llx, limitk = %llx, sizek = %llx.\n",basek,limitk,sizek);
665
666 /* see if we need a hole from 0xa0000 to 0xbffff */
667 if ((basek < 640) && (sizek > 768)) {
668printk(BIOS_DEBUG, "adsr - 0xa0000 to 0xbffff resource.\n");
669 ram_resource(dev, (idx | 0), basek, 640 - basek);
670 idx += 0x10;
671 basek = 768;
672 sizek = limitk - 768;
673 }
674
675
676printk(BIOS_DEBUG, "adsr: mmio_basek=%08x, basek=%08x, limitk=%08x\n", mmio_basek, basek, limitk);
677
678 /* split the region to accomodate pci memory space */
679 if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) {
680 if (basek <= mmio_basek) {
681 unsigned pre_sizek;
682 pre_sizek = mmio_basek - basek;
683 if(pre_sizek>0) {
684 ram_resource(dev, idx, basek, pre_sizek);
685 idx += 0x10;
686 sizek -= pre_sizek;
687#if CONFIG_WRITE_HIGH_TABLES==1
688 if (high_tables_base==0) {
689 /* Leave some space for ACPI, PIRQ and MP tables */
690#if CONFIG_GFXUMA == 1
691 high_tables_base = uma_memory_base - (HIGH_TABLES_SIZE * 1024);
692#else
693 high_tables_base = (mmio_basek - HIGH_TABLES_SIZE) * 1024;
694#endif
695 high_tables_size = HIGH_TABLES_SIZE * 1024;
696 printk(BIOS_DEBUG, " split: %dK table at =%08llx\n", HIGH_TABLES_SIZE,
697 high_tables_base);
698 }
699#endif
700 }
701
702 basek = mmio_basek;
703 }
704 if ((basek + sizek) <= 4*1024*1024) {
705 sizek = 0;
706 }
707 else {
708 basek = 4*1024*1024;
709 sizek -= (4*1024*1024 - mmio_basek);
710 }
711 }
712
713 ram_resource(dev, (idx | 0), basek, sizek);
714 idx += 0x10;
715#if CONFIG_WRITE_HIGH_TABLES==1
716 printk(BIOS_DEBUG, "%d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
717 0, mmio_basek, basek, limitk);
718 if (high_tables_base==0) {
719 /* Leave some space for ACPI, PIRQ and MP tables */
720#if CONFIG_GFXUMA == 1
721 high_tables_base = uma_memory_base - (HIGH_TABLES_SIZE * 1024);
722 printk(BIOS_DEBUG, " adsr - uma_memory_base = %x.\n",uma_memory_base);
723#else
724 high_tables_base = (limitk - HIGH_TABLES_SIZE) * 1024;
725#endif
726 high_tables_size = HIGH_TABLES_SIZE * 1024;
727 }
728#endif
729 }
730printk(BIOS_DEBUG, " adsr - mmio_basek = %x.\n",mmio_basek);
731printk(BIOS_DEBUG, " adsr - high_tables_size = %x.\n",high_tables_size);
732
733#if CONFIG_GFXUMA == 1
734 printk(BIOS_DEBUG, "adsr - adding uma resource.\n");
735 add_uma_resource(dev, 7);
736#endif
737
738 for(link = dev->link_list; link; link = link->next) {
739 if (link->children) {
740 assign_resources(link);
741 }
742 }
743printk(BIOS_DEBUG, " adsr - leaving this lovely routine.\n");
744}
745
746
747static void domain_enable_resources(device_t dev)
748{
749 u32 val;
750 /* Must be called after PCI enumeration and resource allocation */
751 printk(BIOS_DEBUG, "\nFam14h - domain_enable_resources: AmdInitMid.\n");
752 val = agesawrapper_amdinitmid ();
753 if(val) {
754 printk(BIOS_DEBUG, "agesawrapper_amdinitmid failed: %x \n", val);
755 }
756
757 printk(BIOS_DEBUG, " ader - leaving domain_enable_resources.\n");
758}
759
760
761/* Bus related code */
762
763
764static void cpu_bus_read_resources(device_t dev)
765{
766 printk(BIOS_DEBUG, "\nFam14h - cpu_bus_read_resources.\n");
767
768#if CONFIG_MMCONF_SUPPORT
769 struct resource *resource = new_resource(dev, 0xc0010058);
770 resource->base = CONFIG_MMCONF_BASE_ADDRESS;
771 resource->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256;
772 resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
773 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
774#endif
775}
776
777static void cpu_bus_set_resources(device_t dev)
778{
779 struct resource *resource = find_resource(dev, 0xc0010058);
780
781 printk(BIOS_DEBUG, "\nFam14h - cpu_bus_set_resources.\n");
782
783 if (resource) {
784 report_resource_stored(dev, resource, " <mmconfig>");
785 }
786 pci_dev_set_resources(dev);
787}
788
789static void cpu_bus_init(device_t dev)
790{
791 initialize_cpus(dev->link_list);
792}
793
794
795/* North Bridge Structures */
796
797static struct device_operations northbridge_operations = {
798 .read_resources = read_resources,
799 .set_resources = set_resources,
800 .enable_resources = pci_dev_enable_resources,
801 .init = northbridge_init,
802 .enable = 0,
803 .ops_pci = 0,
804};
805
806
807static const struct pci_driver northbridge_driver __pci_driver = {
808 .ops = &northbridge_operations,
809 .vendor = PCI_VENDOR_ID_AMD,
810 .device = 0x1510,
811};
812
813
814struct chip_operations northbridge_amd_agesa_wrapper_family14_ops = {
815 CHIP_NAME("AMD Family 14h Northbridge")
816 .enable_dev = 0,
817};
818
819
820/* Root Complex Structures */
821
822
823static struct device_operations pci_domain_ops = {
824 .read_resources = domain_read_resources,
825 .set_resources = domain_set_resources,
826 .enable_resources = domain_enable_resources,
827 .init = NULL,
828 .scan_bus = pci_domain_scan_bus,
829};
830
831
832static struct device_operations cpu_bus_ops = {
833 .read_resources = cpu_bus_read_resources,
834 .set_resources = cpu_bus_set_resources,
835 .enable_resources = NULL,
836 .init = cpu_bus_init,
837 .scan_bus = 0,
838};
839
840
841static void root_complex_enable_dev(struct device *dev)
842{
843 /* Set the operations if it is a special bus type */
844 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
845 dev->ops = &pci_domain_ops;
846 }
847 else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
848 dev->ops = &cpu_bus_ops;
849 }
850}
851
852
853struct chip_operations northbridge_amd_agesa_wrapper_family14_root_complex_ops = {
854 CHIP_NAME("AMD Family 14h Root Complex")
855 .enable_dev = root_complex_enable_dev,
856};