- See Issue Tracker id-4 "lnxi-patch-4"
[coreboot.git] / src / northbridge / amd / amdk8 / northbridge.c
1 /* This should be done by Eric
2         2004.12 yhlu add dual core support
3         2005.01 yhlu add support move apic before pci_domain in MB Config.lb
4         2005.02 yhlu add e0 memory hole support
5 */
6
7 #include <console/console.h>
8 #include <arch/io.h>
9 #include <stdint.h>
10 #include <device/device.h>
11 #include <device/pci.h>
12 #include <device/pci_ids.h>
13 #include <device/hypertransport.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <bitops.h>
17 #include <cpu/cpu.h>
18
19 #include <cpu/x86/lapic.h>
20 #include <cpu/amd/dualcore.h>
21
22 #if CONFIG_LOGICAL_CPUS==1
23 #include <pc80/mc146818rtc.h>
24 #endif
25
26 #include "chip.h"
27 #include "root_complex/chip.h"
28 #include "northbridge.h"
29 #include "amdk8.h"
30 #include "cpu_rev.c"
31
32 #define FX_DEVS 8
33 static device_t __f0_dev[FX_DEVS];
34 static device_t __f1_dev[FX_DEVS];
35
36 #if 0
37 static void debug_fx_devs(void)
38 {
39         int i;
40         for(i = 0; i < FX_DEVS; i++) {
41                 device_t dev;
42                 dev = __f0_dev[i];
43                 if (dev) {
44                         printk_debug("__f0_dev[%d]: %s bus: %p\n",
45                                 i, dev_path(dev), dev->bus);
46                 }
47                 dev = __f1_dev[i];
48                 if (dev) {
49                         printk_debug("__f1_dev[%d]: %s bus: %p\n",
50                                 i, dev_path(dev), dev->bus);
51                 }
52         }
53 }
54 #endif
55
56 static void get_fx_devs(void)
57 {
58         int i;
59         if (__f1_dev[0]) {
60                 return;
61         }
62         for(i = 0; i < FX_DEVS; i++) {
63                 __f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
64                 __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
65         }
66         if (!__f1_dev[0]) {
67                 die("Cannot find 0:0x18.1\n");
68         }
69 }
70
71 static uint32_t f1_read_config32(unsigned reg)
72 {
73         get_fx_devs();
74         return pci_read_config32(__f1_dev[0], reg);
75 }
76
77 static void f1_write_config32(unsigned reg, uint32_t value)
78 {
79         int i;
80         get_fx_devs();
81         for(i = 0; i < FX_DEVS; i++) {
82                 device_t dev;
83                 dev = __f1_dev[i];
84                 if (dev && dev->enabled) {
85                         pci_write_config32(dev, reg, value);
86                 }
87         }
88 }
89
90 static unsigned int amdk8_nodeid(device_t dev)
91 {
92         return (dev->path.u.pci.devfn >> 3) - 0x18;
93 }
94
95 static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
96 {
97         unsigned nodeid;
98         unsigned link;
99         nodeid = amdk8_nodeid(dev);
100 #if 0
101         printk_debug("%s amdk8_scan_chains max: %d starting...\n", 
102                 dev_path(dev), max);
103 #endif
104         for(link = 0; link < dev->links; link++) {
105                 uint32_t link_type;
106                 uint32_t busses, config_busses;
107                 unsigned free_reg, config_reg;
108                 dev->link[link].cap = 0x80 + (link *0x20);
109                 do {
110                         link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
111                 } while(link_type & ConnectionPending);
112                 if (!(link_type & LinkConnected)) {
113                         continue;
114                 }
115                 do {
116                         link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
117                 } while(!(link_type & InitComplete));
118                 if (!(link_type & NonCoherent)) {
119                         continue;
120                 }
121                 /* See if there is an available configuration space mapping
122                  * register in function 1. 
123                  */
124                 free_reg = 0;
125                 for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
126                         uint32_t config;
127                         config = f1_read_config32(config_reg);
128                         if (!free_reg && ((config & 3) == 0)) {
129                                 free_reg = config_reg;
130                                 continue;
131                         }
132                         if (((config & 3) == 3) && 
133                                 (((config >> 4) & 7) == nodeid) &&
134                                 (((config >> 8) & 3) == link)) {
135                                 break;
136                         }
137                 }
138                 if (free_reg && (config_reg > 0xec)) {
139                         config_reg = free_reg;
140                 }
141                 /* If we can't find an available configuration space mapping
142                  * register skip this bus 
143                  */
144                 if (config_reg > 0xec) {
145                         continue;
146                 }
147
148                 /* Set up the primary, secondary and subordinate bus numbers.
149                  * We have no idea how many busses are behind this bridge yet,
150                  * so we set the subordinate bus number to 0xff for the moment.
151                  */
152                 dev->link[link].secondary = ++max;
153                 dev->link[link].subordinate = 0xff;
154
155                 /* Read the existing primary/secondary/subordinate bus
156                  * number configuration.
157                  */
158                 busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
159                 config_busses = f1_read_config32(config_reg);
160                 
161                 /* Configure the bus numbers for this bridge: the configuration
162                  * transactions will not be propagates by the bridge if it is
163                  * not correctly configured
164                  */
165                 busses &= 0xff000000;
166                 busses |= (((unsigned int)(dev->bus->secondary) << 0) |
167                         ((unsigned int)(dev->link[link].secondary) << 8) |
168                         ((unsigned int)(dev->link[link].subordinate) << 16));
169                 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
170
171                 config_busses &= 0x000fc88;
172                 config_busses |= 
173                         (3 << 0) |  /* rw enable, no device compare */
174                         (( nodeid & 7) << 4) | 
175                         (( link & 3 ) << 8) |  
176                         ((dev->link[link].secondary) << 16) |
177                         ((dev->link[link].subordinate) << 24);
178                 f1_write_config32(config_reg, config_busses);
179
180 #if 0
181                 printk_debug("%s Hyper transport scan link: %d max: %d\n", 
182                         dev_path(dev), link, max);
183 #endif
184                 /* Now we can scan all of the subordinate busses i.e. the
185                  * chain on the hypertranport link 
186                  */
187                 max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max);
188
189 #if 0
190                 printk_debug("%s Hyper transport scan link: %d new max: %d\n",
191                         dev_path(dev), link, max);
192 #endif          
193
194                 /* We know the number of busses behind this bridge.  Set the
195                  * subordinate bus number to it's real value
196                  */
197                 dev->link[link].subordinate = max;
198                 busses = (busses & 0xff00ffff) |
199                         ((unsigned int) (dev->link[link].subordinate) << 16);
200                 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
201
202                 config_busses = (config_busses & 0x00ffffff) |
203                         (dev->link[link].subordinate << 24);
204                 f1_write_config32(config_reg, config_busses);
205
206 #if 0
207                 printk_debug("%s Hypertransport scan link: %d done\n",
208                         dev_path(dev), link);
209 #endif
210         }
211 #if 0
212         printk_debug("%s amdk8_scan_chains max: %d done\n", 
213                 dev_path(dev), max);
214 #endif
215         return max;
216 }
217
218 static int reg_useable(unsigned reg, 
219         device_t goal_dev, unsigned goal_nodeid, unsigned goal_link)
220 {
221         struct resource *res;
222         unsigned nodeid, link;
223         int result;
224         res = 0;
225         for(nodeid = 0; !res && (nodeid < 8); nodeid++) {
226                 device_t dev;
227                 dev = __f0_dev[nodeid];
228                 for(link = 0; !res && (link < 3); link++) {
229                         res = probe_resource(dev, 0x100 + (reg | link));
230                 }
231         }
232         result = 2;
233         if (res) {
234                 result = 0;
235                 if (    (goal_link == (link - 1)) && 
236                         (goal_nodeid == (nodeid - 1)) &&
237                         (res->flags <= 1)) {
238                         result = 1;
239                 }
240         }
241 #if 0
242         printk_debug("reg: %02x result: %d gnodeid: %u glink: %u nodeid: %u link: %u\n",
243                 reg, result, 
244                 goal_nodeid, goal_link, 
245                 nodeid, link);
246 #endif
247         return result;
248 }
249
250 static struct resource *amdk8_find_iopair(device_t dev, unsigned nodeid, unsigned link)
251 {
252         struct resource *resource;
253         unsigned free_reg, reg;
254         resource = 0;
255         free_reg = 0;
256         for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
257                 int result;
258                 result = reg_useable(reg, dev, nodeid, link);
259                 if (result == 1) {
260                         /* I have been allocated this one */
261                         break;
262                 }
263                 else if (result > 1) {
264                         /* I have a free register pair */
265                         free_reg = reg;
266                 }
267         }
268         if (reg > 0xd8) {
269                 reg = free_reg;
270         }
271         if (reg > 0) {
272                 resource = new_resource(dev, 0x100 + (reg | link));
273         }
274         return resource;
275 }
276
277 static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsigned link)
278 {
279         struct resource *resource;
280         unsigned free_reg, reg;
281         resource = 0;
282         free_reg = 0;
283         for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
284                 int result;
285                 result = reg_useable(reg, dev, nodeid, link);
286                 if (result == 1) {
287                         /* I have been allocated this one */
288                         break;
289                 }
290                 else if (result > 1) {
291                         /* I have a free register pair */
292                         free_reg = reg;
293                 }
294         }
295         if (reg > 0xb8) {
296                 reg = free_reg;
297         }
298         if (reg > 0) {
299                 resource = new_resource(dev, 0x100 + (reg | link));
300         }
301         return resource;
302 }
303
304 static void amdk8_link_read_bases(device_t dev, unsigned nodeid, unsigned link)
305 {
306         struct resource *resource;
307         
308         /* Initialize the io space constraints on the current bus */
309         resource =  amdk8_find_iopair(dev, nodeid, link);
310         if (resource) {
311                 resource->base  = 0;
312                 resource->size  = 0;
313                 resource->align = log2(HT_IO_HOST_ALIGN);
314                 resource->gran  = log2(HT_IO_HOST_ALIGN);
315                 resource->limit = 0xffffUL;
316                 resource->flags = IORESOURCE_IO;
317                 compute_allocate_resource(&dev->link[link], resource, 
318                         IORESOURCE_IO, IORESOURCE_IO);
319         }
320
321         /* Initialize the prefetchable memory constraints on the current bus */
322         resource = amdk8_find_mempair(dev, nodeid, link);
323         if (resource) {
324                 resource->base  = 0;
325                 resource->size  = 0;
326                 resource->align = log2(HT_MEM_HOST_ALIGN);
327                 resource->gran  = log2(HT_MEM_HOST_ALIGN);
328                 resource->limit = 0xffffffffffULL;
329                 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
330                 compute_allocate_resource(&dev->link[link], resource, 
331                         IORESOURCE_MEM | IORESOURCE_PREFETCH, 
332                         IORESOURCE_MEM | IORESOURCE_PREFETCH);
333         }
334
335         /* Initialize the memory constraints on the current bus */
336         resource = amdk8_find_mempair(dev, nodeid, link);
337         if (resource) {
338                 resource->base  = 0;
339                 resource->size  = 0;
340                 resource->align = log2(HT_MEM_HOST_ALIGN);
341                 resource->gran  = log2(HT_MEM_HOST_ALIGN);
342                 resource->limit = 0xffffffffffULL;
343                 resource->flags = IORESOURCE_MEM;
344                 compute_allocate_resource(&dev->link[link], resource, 
345                         IORESOURCE_MEM | IORESOURCE_PREFETCH, 
346                         IORESOURCE_MEM);
347         }
348 }
349
350 static void amdk8_read_resources(device_t dev)
351 {
352         unsigned nodeid, link;
353         nodeid = amdk8_nodeid(dev);
354         for(link = 0; link < dev->links; link++) {
355                 if (dev->link[link].children) {
356                         amdk8_link_read_bases(dev, nodeid, link);
357                 }
358         }
359 }
360
361 static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned nodeid)
362 {
363         resource_t rbase, rend;
364         unsigned reg, link;
365         char buf[50];
366
367         /* Make certain the resource has actually been set */
368         if (!(resource->flags & IORESOURCE_ASSIGNED)) {
369                 return;
370         }
371
372         /* If I have already stored this resource don't worry about it */
373         if (resource->flags & IORESOURCE_STORED) {
374                 return;
375         }
376         
377         /* Only handle PCI memory and IO resources */
378         if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
379                 return;
380
381         /* Ensure I am actually looking at a resource of function 1 */
382         if (resource->index < 0x100) {
383                 return;
384         }
385         /* Get the base address */
386         rbase = resource->base;
387         
388         /* Get the limit (rounded up) */
389         rend  = resource_end(resource);
390
391         /* Get the register and link */
392         reg  = resource->index & 0xfc;
393         link = resource->index & 3;
394
395         if (resource->flags & IORESOURCE_IO) {
396                 uint32_t base, limit;
397                 compute_allocate_resource(&dev->link[link], resource,
398                         IORESOURCE_IO, IORESOURCE_IO);
399                 base  = f1_read_config32(reg);
400                 limit = f1_read_config32(reg + 0x4);
401                 base  &= 0xfe000fcc;
402                 base  |= rbase  & 0x01fff000;
403                 base  |= 3;
404                 limit &= 0xfe000fc8;
405                 limit |= rend & 0x01fff000;
406                 limit |= (link & 3) << 4;
407                 limit |= (nodeid & 7);
408
409                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
410                         printk_spew("%s, enabling legacy VGA IO forwarding for %s link %s\n",
411                                     __func__, dev_path(dev), link);             
412                         base |= PCI_IO_BASE_VGA_EN;
413                 }
414                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
415                         base |= PCI_IO_BASE_NO_ISA;
416                 }
417                 
418                 f1_write_config32(reg + 0x4, limit);
419                 f1_write_config32(reg, base);
420         }
421         else if (resource->flags & IORESOURCE_MEM) {
422                 uint32_t base, limit;
423                 compute_allocate_resource(&dev->link[link], resource,
424                         IORESOURCE_MEM | IORESOURCE_PREFETCH,
425                         resource->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH));
426                 base  = f1_read_config32(reg);
427                 limit = f1_read_config32(reg + 0x4);
428                 base  &= 0x000000f0;
429                 base  |= (rbase >> 8) & 0xffffff00;
430                 base  |= 3;
431                 limit &= 0x00000048;
432                 limit |= (rend >> 8) & 0xffffff00;
433                 limit |= (link & 3) << 4;
434                 limit |= (nodeid & 7);
435                 f1_write_config32(reg + 0x4, limit);
436                 f1_write_config32(reg, base);
437         }
438         resource->flags |= IORESOURCE_STORED;
439         sprintf(buf, " <node %d link %d>",
440                 nodeid, link);
441         report_resource_stored(dev, resource, buf);
442 }
443
444 /**
445  *
446  * I tried to reuse the resource allocation code in amdk8_set_resource()
447  * but it is too diffcult to deal with the resource allocation magic.
448  */
449 static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
450 {
451         struct resource *resource;
452         unsigned link;
453         uint32_t base, limit;
454         unsigned reg;
455
456         /* find out which link the VGA card is connected,
457          * we only deal with the 'first' vga card */
458         for (link = 0; link < dev->links; link++) {
459                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
460                         break;
461                 }
462         }
463         
464         printk_spew("%s: link %d has VGA device\n", __func__, link);
465
466         /* no VGA card installed */
467         if (link == dev->links)
468                 return;
469
470         /* allocate a temp resrouce for legacy VGA buffer */
471         resource = amdk8_find_mempair(dev, nodeid, link);
472         resource->base = 0xa0000;
473         resource->size = 0x20000;
474
475         /* write the resource to the hardware */
476         reg  = resource->index & 0xfc;
477         base  = f1_read_config32(reg);
478         limit = f1_read_config32(reg + 0x4);
479         base  &= 0x000000f0;
480         base  |= (resource->base >> 8) & 0xffffff00;
481         base  |= 3;
482         limit &= 0x00000048;
483         limit |= ((resource->base + resource->size) >> 8) & 0xffffff00;
484         limit |= (resource->index & 3) << 4;
485         limit |= (nodeid & 7);
486         f1_write_config32(reg + 0x4, limit);
487         f1_write_config32(reg, base);
488
489         /* release the temp resource */
490         resource->flags = 0;
491
492 }
493
494 static void amdk8_set_resources(device_t dev)
495 {
496         unsigned nodeid, link;
497         int i;
498
499         /* Find the nodeid */
500         nodeid = amdk8_nodeid(dev);
501
502         amdk8_create_vga_resource(dev, nodeid);
503         
504         /* Set each resource we have found */
505         for(i = 0; i < dev->resources; i++) {
506                 amdk8_set_resource(dev, &dev->resource[i], nodeid);
507         }
508
509         for(link = 0; link < dev->links; link++) {
510                 struct bus *bus;
511                 bus = &dev->link[link];
512                 if (bus->children) {
513                         assign_resources(bus);
514                 }
515         }
516 }
517
518 static void amdk8_enable_resources(device_t dev)
519 {
520         pci_dev_enable_resources(dev);
521         enable_childrens_resources(dev);
522 }
523
524 static void mcf0_control_init(struct device *dev)
525 {
526 #if 0   
527         printk_debug("NB: Function 0 Misc Control.. ");
528 #endif
529 #if 0
530         printk_debug("done.\n");
531 #endif
532 }
533
534 static struct device_operations northbridge_operations = {
535         .read_resources   = amdk8_read_resources,
536         .set_resources    = amdk8_set_resources,
537         .enable_resources = amdk8_enable_resources,
538         .init             = mcf0_control_init,
539         .scan_bus         = amdk8_scan_chains,
540         .enable           = 0,
541         .ops_pci          = 0,
542 };
543
544
545 static struct pci_driver mcf0_driver __pci_driver = {
546         .ops    = &northbridge_operations,
547         .vendor = PCI_VENDOR_ID_AMD,
548         .device = 0x1100,
549 };
550
551 #if CONFIG_CHIP_NAME == 1
552
553 struct chip_operations northbridge_amd_amdk8_ops = {
554         CHIP_NAME("AMD K8 Northbridge")
555         .enable_dev = 0,
556 };
557
558 #endif
559
560 static void pci_domain_read_resources(device_t dev)
561 {
562         struct resource *resource;
563         unsigned reg;
564
565         /* Find the already assigned resource pairs */
566         get_fx_devs();
567         for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
568                 uint32_t base, limit;
569                 base  = f1_read_config32(reg);
570                 limit = f1_read_config32(reg + 0x04);
571                 /* Is this register allocated? */
572                 if ((base & 3) != 0) {
573                         unsigned nodeid, link;
574                         device_t dev;
575                         nodeid = limit & 7;
576                         link   = (limit >> 4) & 3;
577                         dev = __f0_dev[nodeid];
578                         if (dev) {
579                                 /* Reserve the resource  */
580                                 struct resource *resource;
581                                 resource = new_resource(dev, 0x100 + (reg | link));
582                                 if (resource) {
583                                         resource->flags = 1;
584                                 }
585                         }
586                 }
587         }
588
589         /* Initialize the system wide io space constraints */
590         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
591         resource->base  = 0x400;
592         resource->limit = 0xffffUL;
593         resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
594
595         /* Initialize the system wide memory resources constraints */
596         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
597         resource->limit = 0xfcffffffffULL;
598         resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
599 }
600
601 static void ram_resource(device_t dev, unsigned long index, 
602         unsigned long basek, unsigned long sizek)
603 {
604         struct resource *resource;
605
606         if (!sizek) {
607                 return;
608         }
609         resource = new_resource(dev, index);
610         resource->base  = ((resource_t)basek) << 10;
611         resource->size  = ((resource_t)sizek) << 10;
612         resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
613                 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
614 }
615
616 static void tolm_test(void *gp, struct device *dev, struct resource *new)
617 {
618         struct resource **best_p = gp;
619         struct resource *best;
620         best = *best_p;
621         if (!best || (best->base > new->base)) {
622                 best = new;
623         }
624         *best_p = best;
625 }
626
627 static uint32_t find_pci_tolm(struct bus *bus)
628 {
629         struct resource *min;
630         uint32_t tolm;
631         min = 0;
632         search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
633         tolm = 0xffffffffUL;
634         if (min && tolm > min->base) {
635                 tolm = min->base;
636         }
637         return tolm;
638 }
639
640 static uint32_t hoist_memory(unsigned long mmio_basek, int i) 
641 {
642         int ii;
643         uint32_t carry_over;
644         device_t dev;
645         uint32_t base, limit;
646         uint32_t basek;
647         uint32_t hoist;
648
649         carry_over = (4*1024*1024) - mmio_basek;
650         for(ii=7;ii>i;ii--) {
651
652                 base  = f1_read_config32(0x40 + (ii << 3));
653                 limit = f1_read_config32(0x44 + (ii << 3));
654                 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
655                         continue;
656                 }
657                 f1_write_config32(0x44 + (ii << 3),limit + (carry_over << 2));
658                 f1_write_config32(0x40 + (ii << 3),base + (carry_over << 2));
659         }
660         limit = f1_read_config32(0x44 + (i << 3));
661         f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));
662         dev = __f1_dev[i];
663         base  = pci_read_config32(dev, 0x40 + (i << 3));
664         basek  = (pci_read_config32(dev, 0x40 + (i << 3)) & 0xffff0000) >> 2;
665         hoist = /* hole start address */
666                 ((mmio_basek << 10) & 0xff000000) +  
667                 /* hole address to memory controller address */ 
668                 (((basek + carry_over) >> 6) & 0x0000ff00) + 
669                 /* enable */
670                 1;
671         pci_write_config32(dev, 0xf0, hoist);
672         return carry_over;
673 }
674
675 static void pci_domain_set_resources(device_t dev)
676 {
677         unsigned long mmio_basek;
678         uint32_t pci_tolm;
679         int i, idx;
680
681         pci_tolm = find_pci_tolm(&dev->link[0]);
682
683         /* Work around for NUMA bug in all kernels before 2.6.13.
684            If pci memory hole is too small, the kernel memory to NUMA 
685            node mapping will fail to initialize and system will run in
686            non-NUMA mode.
687         */
688         if(pci_tolm > 0xf8000000) pci_tolm = 0xf8000000;
689
690 #warning "FIXME handle interleaved nodes"
691         mmio_basek = pci_tolm >> 10;
692         /* Round mmio_basek to something the processor can support */
693         mmio_basek &= ~((1 << 6) -1);
694
695         idx = 10;
696         for(i = 0; i < 8; i++) {
697                 uint32_t base, limit;
698                 unsigned basek, limitk, sizek;
699
700                 base  = f1_read_config32(0x40 + (i << 3));
701                 limit = f1_read_config32(0x44 + (i << 3));
702                 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
703                         continue;
704                 }
705                 basek = (base & 0xffff0000) >> 2;
706                 limitk = ((limit + 0x00010000) & 0xffff0000) >> 2;
707                 sizek = limitk - basek;
708
709                 /* see if we need a hole from 0xa0000 to 0xbffff */
710                 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
711                         ram_resource(dev, idx++, basek, ((8*64)+(8*16)) - basek);
712                         basek = (8*64)+(16*16);
713                         sizek = limitk - ((8*64)+(16*16));
714                         
715                 }
716
717                 
718                 /* See if I need to split the region to accomodate pci memory space */
719                 if ((basek < mmio_basek) && (limitk > mmio_basek)) {
720                         if (basek < mmio_basek) {
721                                 unsigned pre_sizek;
722                                 pre_sizek = mmio_basek - basek;
723                                 ram_resource(dev, idx++, basek, pre_sizek);
724                                 sizek -= pre_sizek;
725                                 if(! is_cpu_pre_e0() ) { 
726                                         sizek += hoist_memory(mmio_basek,i);
727                                 }
728                                 basek = mmio_basek;
729                         }
730                         if ((basek + sizek) <= 4*1024*1024) {
731                                 sizek = 0;
732                         }
733                         else {
734                                 basek = 4*1024*1024;
735                                 sizek -= (4*1024*1024 - mmio_basek);
736                         }
737                 }
738                 ram_resource(dev, idx++, basek, sizek);
739         }
740         assign_resources(&dev->link[0]);
741 }
742
743 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
744 {
745         unsigned reg;
746         int i;
747         /* Unmap all of the HT chains */
748         for(reg = 0xe0; reg <= 0xec; reg += 4) {
749                 f1_write_config32(reg, 0);
750         }
751         max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
752         
753         /* Tune the hypertransport transaction for best performance.
754          * Including enabling relaxed ordering if it is safe.
755          */
756         get_fx_devs();
757         for(i = 0; i < FX_DEVS; i++) {
758                 device_t f0_dev;
759                 f0_dev = __f0_dev[i];
760                 if (f0_dev && f0_dev->enabled) {
761                         uint32_t httc;
762                         int j;
763                         httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
764                         httc &= ~HTTC_RSP_PASS_PW;
765                         if (!dev->link[0].disable_relaxed_ordering) {
766                                 httc |= HTTC_RSP_PASS_PW;
767                         }
768                         printk_spew("%s passpw: %s\n",
769                                 dev_path(dev),
770                                 (!dev->link[0].disable_relaxed_ordering)?
771                                 "enabled":"disabled");
772                         pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
773                 }
774         }
775         return max;
776 }
777
778 static struct device_operations pci_domain_ops = {
779         .read_resources   = pci_domain_read_resources,
780         .set_resources    = pci_domain_set_resources,
781         .enable_resources = enable_childrens_resources,
782         .init             = 0,
783         .scan_bus         = pci_domain_scan_bus,
784         .ops_pci_bus      = &pci_cf8_conf1,
785 };
786
787 static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
788 {
789         struct bus *cpu_bus;
790         device_t dev_mc;
791         int i,j;
792
793         dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
794         if (!dev_mc) {
795                 die("0:18.0 not found?");
796         }
797
798         /* Find which cpus are present */
799         cpu_bus = &dev->link[0];
800         for(i = 0; i < 8; i++) {
801                 device_t dev, cpu;
802                 struct device_path cpu_path;
803
804                 /* Find the cpu's pci device */
805                 dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
806                 if (!dev) {
807                         /* If I am probing things in a weird order
808                          * ensure all of the cpu's pci devices are found.
809                          */
810                         int j;
811                         for(j = 0; j <= 3; j++) {
812                                 dev = pci_probe_dev(NULL, dev_mc->bus,
813                                         PCI_DEVFN(0x18 + i, j));
814                         }
815                 }
816                 
817                 /* Build the cpu device path */
818                 cpu_path.type = DEVICE_PATH_APIC;
819                 cpu_path.u.apic.apic_id = 0x10 + i;
820
821                 /* See if I can find the cpu */
822                 cpu = find_dev_path(cpu_bus, &cpu_path);
823
824                 /* Enable the cpu if I have the processor */
825                 if (dev && dev->enabled) {
826                         if (!cpu) {
827                                 cpu = alloc_dev(cpu_bus, &cpu_path);
828                         }
829                         if (cpu) {
830                                 cpu->enabled = 1;
831                         }
832                 }
833                         
834                 /* Disable the cpu if I don't have the processor */
835                 if (cpu && (!dev || !dev->enabled)) {
836                         cpu->enabled = 0;
837                 }
838                         
839                 /* Report what I have done */
840                 if (cpu) {
841                         printk_debug("CPU: %s %s\n",
842                         dev_path(cpu), cpu->enabled?"enabled":"disabled");
843                 }
844         }
845
846         return max;
847 }
848
849 static void cpu_bus_init(device_t dev)
850 {
851         initialize_cpus(&dev->link[0]);
852 }
853
854 static void cpu_bus_noop(device_t dev) 
855 {
856 }
857
858 static struct device_operations cpu_bus_ops = {
859         .read_resources   = cpu_bus_noop,
860         .set_resources    = cpu_bus_noop,
861         .enable_resources = cpu_bus_noop,
862         .init             = cpu_bus_init,
863         .scan_bus         = cpu_bus_scan,
864 };
865
866 static void root_complex_enable_dev(struct device *dev)
867 {
868         /* Set the operations if it is a special bus type */
869         if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
870                 dev->ops = &pci_domain_ops;
871         }
872         else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
873                 dev->ops = &cpu_bus_ops;
874         }
875 }
876
877 struct chip_operations northbridge_amd_amdk8_root_complex_ops = {
878         CHIP_NAME("AMD K8 Root Complex")
879         .enable_dev = root_complex_enable_dev,
880 };