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