- Apply 11_24_a_s1_core.diff from
[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 = 0x10;
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 | i), basek, ((8*64)+(8*16)) - basek);
712                         idx += 0x10;
713                         basek = (8*64)+(16*16);
714                         sizek = limitk - ((8*64)+(16*16));
715                         
716                 }
717
718                 
719                 /* See if I need to split the region to accomodate pci memory space */
720                 if ((basek < mmio_basek) && (limitk > mmio_basek)) {
721                         if (basek < mmio_basek) {
722                                 unsigned pre_sizek;
723                                 pre_sizek = mmio_basek - basek;
724                                 ram_resource(dev, (idx | i), basek, pre_sizek);
725                                 idx += 0x10;
726                                 sizek -= pre_sizek;
727                                 if(! is_cpu_pre_e0() ) { 
728                                         sizek += hoist_memory(mmio_basek,i);
729                                 }
730                                 basek = mmio_basek;
731                         }
732                         if ((basek + sizek) <= 4*1024*1024) {
733                                 sizek = 0;
734                         }
735                         else {
736                                 basek = 4*1024*1024;
737                                 sizek -= (4*1024*1024 - mmio_basek);
738                         }
739                 }
740                 ram_resource(dev, (idx | i), basek, sizek);
741                 idx += 0x10;
742         }
743         assign_resources(&dev->link[0]);
744 }
745
746 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
747 {
748         unsigned reg;
749         int i;
750         /* Unmap all of the HT chains */
751         for(reg = 0xe0; reg <= 0xec; reg += 4) {
752                 f1_write_config32(reg, 0);
753         }
754         max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
755         
756         /* Tune the hypertransport transaction for best performance.
757          * Including enabling relaxed ordering if it is safe.
758          */
759         get_fx_devs();
760         for(i = 0; i < FX_DEVS; i++) {
761                 device_t f0_dev;
762                 f0_dev = __f0_dev[i];
763                 if (f0_dev && f0_dev->enabled) {
764                         uint32_t httc;
765                         int j;
766                         httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
767                         httc &= ~HTTC_RSP_PASS_PW;
768                         if (!dev->link[0].disable_relaxed_ordering) {
769                                 httc |= HTTC_RSP_PASS_PW;
770                         }
771                         printk_spew("%s passpw: %s\n",
772                                 dev_path(dev),
773                                 (!dev->link[0].disable_relaxed_ordering)?
774                                 "enabled":"disabled");
775                         pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
776                 }
777         }
778         return max;
779 }
780
781 static struct device_operations pci_domain_ops = {
782         .read_resources   = pci_domain_read_resources,
783         .set_resources    = pci_domain_set_resources,
784         .enable_resources = enable_childrens_resources,
785         .init             = 0,
786         .scan_bus         = pci_domain_scan_bus,
787         .ops_pci_bus      = &pci_cf8_conf1,
788 };
789
790 static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
791 {
792         struct bus *cpu_bus;
793         device_t dev_mc;
794         int i,j;
795
796         dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
797         if (!dev_mc) {
798                 die("0:18.0 not found?");
799         }
800
801         /* Find which cpus are present */
802         cpu_bus = &dev->link[0];
803         for(i = 0; i < 8; i++) {
804                 device_t dev, cpu;
805                 struct device_path cpu_path;
806
807                 /* Find the cpu's pci device */
808                 dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
809                 if (!dev) {
810                         /* If I am probing things in a weird order
811                          * ensure all of the cpu's pci devices are found.
812                          */
813                         int j;
814                         for(j = 0; j <= 3; j++) {
815                                 dev = pci_probe_dev(NULL, dev_mc->bus,
816                                         PCI_DEVFN(0x18 + i, j));
817                         }
818                 }
819                 
820                 /* Build the cpu device path */
821                 cpu_path.type = DEVICE_PATH_APIC;
822                 cpu_path.u.apic.apic_id = 0x10 + i;
823
824                 /* See if I can find the cpu */
825                 cpu = find_dev_path(cpu_bus, &cpu_path);
826
827                 /* Enable the cpu if I have the processor */
828                 if (dev && dev->enabled) {
829                         if (!cpu) {
830                                 cpu = alloc_dev(cpu_bus, &cpu_path);
831                         }
832                         if (cpu) {
833                                 cpu->enabled = 1;
834                         }
835                 }
836                         
837                 /* Disable the cpu if I don't have the processor */
838                 if (cpu && (!dev || !dev->enabled)) {
839                         cpu->enabled = 0;
840                 }
841                         
842                 /* Report what I have done */
843                 if (cpu) {
844                         cpu->path.u.apic.node_id = i;
845                         cpu->path.u.apic.core_id = 0;
846                         printk_debug("CPU: %s %s\n",
847                         dev_path(cpu), cpu->enabled?"enabled":"disabled");
848                 }
849         }
850
851         return max;
852 }
853
854 static void cpu_bus_init(device_t dev)
855 {
856         initialize_cpus(&dev->link[0]);
857 }
858
859 static void cpu_bus_noop(device_t dev) 
860 {
861 }
862
863 static struct device_operations cpu_bus_ops = {
864         .read_resources   = cpu_bus_noop,
865         .set_resources    = cpu_bus_noop,
866         .enable_resources = cpu_bus_noop,
867         .init             = cpu_bus_init,
868         .scan_bus         = cpu_bus_scan,
869 };
870
871 static void root_complex_enable_dev(struct device *dev)
872 {
873         /* Set the operations if it is a special bus type */
874         if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
875                 dev->ops = &pci_domain_ops;
876         }
877         else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
878                 dev->ops = &cpu_bus_ops;
879         }
880 }
881
882 struct chip_operations northbridge_amd_amdk8_root_complex_ops = {
883         CHIP_NAME("AMD K8 Root Complex")
884         .enable_dev = root_complex_enable_dev,
885 };