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