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