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