Fix memory size reporting on AMD family 14h systems for >= 4GB
[coreboot.git] / src / northbridge / amd / agesa / family14 / northbridge.c
1 /*
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
41 static device_t __f0_dev[FX_DEVS];
42 static device_t __f1_dev[FX_DEVS];
43 static device_t __f2_dev[FX_DEVS];
44 static device_t __f4_dev[FX_DEVS];
45 static unsigned fx_devs=0;
46
47
48 device_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
54 static 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
71 static 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
79 static 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
94 static 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
103 static void northbridge_init(device_t dev)
104 {
105   printk(BIOS_DEBUG, "Northbridge init\n");
106 }
107
108
109 static 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
121 static 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
149 static 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
173 static 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
209 static 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
268 static 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
281 struct hw_mem_hole_info {
282     unsigned hole_startk;
283     int node_id;
284 };
285
286 static 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
334 extern uint64_t high_tables_base, high_tables_size;
335 #endif
336
337 #if CONFIG_GFXUMA == 1
338 extern uint64_t uma_memory_base, uma_memory_size;
339
340 static 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
354 static 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
370 static 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
421 extern device_t vga_pri;    // the primary vga device, defined in device.c
422 #endif
423
424 static 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
455 static 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
483 static 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
545 static 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
565 printk(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)((u64)d.base)) << 8;
656         limitk = (resource_t)(((u64)d.mask << 8) | 0xFFFFFF);
657 printk(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
664 printk(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)) {
668 printk(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
676 printk(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     }
730 printk(BIOS_DEBUG, "  adsr - mmio_basek = %x.\n",mmio_basek);
731 printk(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     }
743 printk(BIOS_DEBUG, "  adsr - leaving this lovely routine.\n");
744 }
745
746
747 static 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
764 static 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
777 static 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
789 static void cpu_bus_init(device_t dev)
790 {
791         struct device_path cpu_path;
792         device_t cpu;
793     int apic_id;
794
795     initialize_cpus(dev->link_list);
796
797         /* Build the AP cpu device path(s) */
798     for (apic_id = 1; apic_id < CONFIG_MAX_CPUS; apic_id++) {
799             cpu_path.type = DEVICE_PATH_APIC;
800             cpu_path.apic.apic_id = apic_id;
801         cpu = alloc_dev(dev->link_list, &cpu_path);
802         if (!cpu) return;
803         cpu->enabled = 1;
804         cpu->path.apic.node_id = 0;
805         cpu->path.apic.core_id = apic_id;
806     }
807 }
808
809
810 /* North Bridge Structures */
811
812 static struct device_operations northbridge_operations = {
813     .read_resources   = read_resources,
814     .set_resources    = set_resources,
815   .enable_resources = pci_dev_enable_resources,
816   .init             = northbridge_init,
817   .enable           = 0,
818   .ops_pci          = 0,
819 };
820
821
822 static const struct pci_driver northbridge_driver __pci_driver = {
823     .ops = &northbridge_operations,
824     .vendor = PCI_VENDOR_ID_AMD,
825     .device = 0x1510,
826 };
827
828
829 struct chip_operations northbridge_amd_agesa_family14_ops = {
830     CHIP_NAME("AMD Family 14h Northbridge")
831     .enable_dev = 0,
832 };
833
834
835 /* Root Complex Structures */
836
837
838 static struct device_operations pci_domain_ops = {
839     .read_resources   = domain_read_resources,
840     .set_resources    = domain_set_resources,
841     .enable_resources = domain_enable_resources,
842     .init             = NULL,
843     .scan_bus         = pci_domain_scan_bus,
844 };
845
846
847 static struct device_operations cpu_bus_ops = {
848     .read_resources   = cpu_bus_read_resources,
849     .set_resources    = cpu_bus_set_resources,
850     .enable_resources = NULL,
851     .init             = cpu_bus_init,
852     .scan_bus         = NULL,
853 };
854
855
856 static void root_complex_enable_dev(struct device *dev)
857 {
858     /* Set the operations if it is a special bus type */
859     if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
860         dev->ops = &pci_domain_ops;
861     }
862     else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
863         dev->ops = &cpu_bus_ops;
864     }
865 }
866
867
868 struct chip_operations northbridge_amd_agesa_family14_root_complex_ops = {
869     CHIP_NAME("AMD Family 14h Root Complex")
870     .enable_dev = root_complex_enable_dev,
871 };