from issue 47, put chain on bus 0, 0x40, 0x80, 0xc0
[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         2005.11 yhlu add put sb ht chain on bus 0
6 */
7
8 #include <console/console.h>
9 #include <arch/io.h>
10 #include <stdint.h>
11 #include <device/device.h>
12 #include <device/pci.h>
13 #include <device/pci_ids.h>
14 #include <device/hypertransport.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <bitops.h>
18 #include <cpu/cpu.h>
19
20 #include <cpu/x86/lapic.h>
21
22 #if CONFIG_LOGICAL_CPUS==1
23 #include <cpu/amd/dualcore.h>
24 #include <pc80/mc146818rtc.h>
25 #endif
26
27 #include "chip.h"
28 #include "root_complex/chip.h"
29 #include "northbridge.h"
30
31 #include "amdk8.h"
32
33 #if K8_HW_MEM_HOLE_SIZEK != 0
34 #include <cpu/amd/model_fxx_rev.h>
35 #endif
36
37 #define FX_DEVS 8
38 static device_t __f0_dev[FX_DEVS];
39 static device_t __f1_dev[FX_DEVS];
40
41 #if 0
42 static void debug_fx_devs(void)
43 {
44         int i;
45         for(i = 0; i < FX_DEVS; i++) {
46                 device_t dev;
47                 dev = __f0_dev[i];
48                 if (dev) {
49                         printk_debug("__f0_dev[%d]: %s bus: %p\n",
50                                 i, dev_path(dev), dev->bus);
51                 }
52                 dev = __f1_dev[i];
53                 if (dev) {
54                         printk_debug("__f1_dev[%d]: %s bus: %p\n",
55                                 i, dev_path(dev), dev->bus);
56                 }
57         }
58 }
59 #endif
60
61 static void get_fx_devs(void)
62 {
63         int i;
64         if (__f1_dev[0]) {
65                 return;
66         }
67         for(i = 0; i < FX_DEVS; i++) {
68                 __f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
69                 __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
70         }
71         if (!__f1_dev[0]) {
72                 die("Cannot find 0:0x18.1\n");
73         }
74 }
75
76 static uint32_t f1_read_config32(unsigned reg)
77 {
78         get_fx_devs();
79         return pci_read_config32(__f1_dev[0], reg);
80 }
81
82 static void f1_write_config32(unsigned reg, uint32_t value)
83 {
84         int i;
85         get_fx_devs();
86         for(i = 0; i < FX_DEVS; i++) {
87                 device_t dev;
88                 dev = __f1_dev[i];
89                 if (dev && dev->enabled) {
90                         pci_write_config32(dev, reg, value);
91                 }
92         }
93 }
94
95 static unsigned int amdk8_nodeid(device_t dev)
96 {
97         return (dev->path.u.pci.devfn >> 3) - 0x18;
98 }
99
100 unsigned hcdn_reg[4]; // it will be used by get_sblk_pci1234
101
102 static unsigned int amdk8_scan_chain(device_t dev, unsigned nodeid, unsigned link, unsigned sblink, unsigned int max, unsigned offset_unitid)
103 {
104 #if 0
105         printk_debug("%s amdk8_scan_chains max: %d starting...\n", 
106                 dev_path(dev), max);
107 #endif
108 //      I want to put sb chain in bus 0 can I?
109
110          
111                 uint32_t link_type;
112                 int i;
113                 uint32_t busses, config_busses;
114                 unsigned free_reg, config_reg;
115                 unsigned ht_unitid_base[4]; // here assume only 4 HT device on chain
116                 unsigned max_bus;
117                 unsigned min_bus;
118
119                 dev->link[link].cap = 0x80 + (link *0x20);
120                 do {
121                         link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
122                 } while(link_type & ConnectionPending);
123                 if (!(link_type & LinkConnected)) {
124                         return max;
125                 }
126                 do {
127                         link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
128                 } while(!(link_type & InitComplete));
129                 if (!(link_type & NonCoherent)) {
130                         return max;
131                 }
132                 /* See if there is an available configuration space mapping
133                  * register in function 1. 
134                  */
135                 free_reg = 0;
136                 for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
137                         uint32_t config;
138                         config = f1_read_config32(config_reg);
139                         if (!free_reg && ((config & 3) == 0)) {
140                                 free_reg = config_reg;
141                                 continue;
142                         }
143                         if (((config & 3) == 3) && 
144                                 (((config >> 4) & 7) == nodeid) &&
145                                 (((config >> 8) & 3) == link)) {
146                                 break;
147                         }
148                 }
149                 if (free_reg && (config_reg > 0xec)) {
150                         config_reg = free_reg;
151                 }
152                 /* If we can't find an available configuration space mapping
153                  * register skip this bus 
154                  */
155                 if (config_reg > 0xec) {
156                         return max;
157                 }
158
159                 /* Set up the primary, secondary and subordinate bus numbers.
160                  * We have no idea how many busses are behind this bridge yet,
161                  * so we set the subordinate bus number to 0xff for the moment.
162                  */
163 #if K8_SB_HT_CHAIN_ON_BUS0 > 0
164         # if K8_SB_HT_CHAIN_ON_BUS0 > 1
165                 // first chain will on bus 0, second chain will be on 0x40, third 0x80, forth 0xc0
166                 if(max == 0) {
167                         min_bus = 0;
168                         max_bus = 0x3f;
169                 } else if (max<0x40) {
170                         min_bus = 0x40;
171                         max_bus = 0x7f;
172                 } else if (max<0x80) {
173                         min_bus = 0x80;
174                         max_bus = 0xbf;
175                 } else {
176                         min_bus = 0xc0;
177                         max_bus = 0xff;
178                 }
179                 max = min_bus;
180         #else
181                 // only sb ht chain will on bus 0, other ...
182                 if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
183                         min_bus = max;
184                 }
185                 else  {
186                         min_bus = ++max;
187                 }
188                 max_bus = 0xff;
189         #endif
190 #else
191                 min_bus = ++max;
192                 max_bus = 0xff;
193 #endif
194
195                 dev->link[link].secondary = min_bus;
196                 dev->link[link].subordinate = max_bus;
197
198                 /* Read the existing primary/secondary/subordinate bus
199                  * number configuration.
200                  */
201                 busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
202                 config_busses = f1_read_config32(config_reg);
203                 
204                 /* Configure the bus numbers for this bridge: the configuration
205                  * transactions will not be propagates by the bridge if it is
206                  * not correctly configured
207                  */
208                 busses &= 0xff000000;
209                 busses |= (((unsigned int)(dev->bus->secondary) << 0) |
210                         ((unsigned int)(dev->link[link].secondary) << 8) |
211                         ((unsigned int)(dev->link[link].subordinate) << 16));
212                 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
213
214                 config_busses &= 0x000fc88;
215                 config_busses |= 
216                         (3 << 0) |  /* rw enable, no device compare */
217                         (( nodeid & 7) << 4) | 
218                         (( link & 3 ) << 8) |  
219                         ((dev->link[link].secondary) << 16) |
220                         ((dev->link[link].subordinate) << 24);
221                 f1_write_config32(config_reg, config_busses);
222
223 #if 0
224                 printk_debug("%s Hyper transport scan link: %d max: %d\n", 
225                         dev_path(dev), link, max);
226 #endif
227                 /* Now we can scan all of the subordinate busses i.e. the
228                  * chain on the hypertranport link 
229                  */
230                 for(i=0;i<4;i++) {
231                         ht_unitid_base[i] = 0x20;
232                 }
233                 max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max, ht_unitid_base, offset_unitid);
234
235 #if 0
236                 printk_debug("%s Hyper transport scan link: %d new max: %d\n",
237                         dev_path(dev), link, max);
238 #endif          
239
240                 /* We know the number of busses behind this bridge.  Set the
241                  * subordinate bus number to it's real value
242                  */
243                 dev->link[link].subordinate = max;
244                 busses = (busses & 0xff00ffff) |
245                         ((unsigned int) (dev->link[link].subordinate) << 16);
246                 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
247
248                 config_busses = (config_busses & 0x00ffffff) |
249                         (dev->link[link].subordinate << 24);
250                 f1_write_config32(config_reg, config_busses);
251
252                 {
253                         // config config_reg, and ht_unitid_base to update hcdn_reg;
254                         int index;
255                         unsigned temp = 0;
256                         index = (config_reg-0xe0) >> 2;
257                         for(i=0;i<4;i++) {
258                                 temp |= (ht_unitid_base[i] & 0xff) << (i*8);
259                         }
260
261                         hcdn_reg[index] = temp;
262
263                 }
264
265 #if 0
266                 printk_debug("%s Hypertransport scan link: %d done\n",
267                         dev_path(dev), link);
268 #endif
269
270         return max;
271 }
272
273 static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
274 {
275         unsigned nodeid;
276         unsigned link;
277         unsigned sblink = 0;
278         unsigned offset_unitid = 0;
279         nodeid = amdk8_nodeid(dev);
280         
281
282 #if 0
283         printk_debug("%s amdk8_scan_chains max: %d starting...\n",
284                 dev_path(dev), max);
285 #endif
286 //      I want to put sb chain in bus 0 
287
288         if(nodeid==0) {
289                 sblink = (pci_read_config32(dev, 0x64)>>8) & 3;
290 #if K8_SB_HT_CHAIN_ON_BUS0 == 1
291         #if HT_CHAIN_UNITID_BASE != 1
292                 offset_unitid = 1;
293         #endif
294                 max = amdk8_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
295 #endif
296         }
297
298         for(link = 0; link < dev->links; link++) {
299 #if K8_SB_HT_CHAIN_ON_BUS0 == 1
300                 if( (nodeid == 0) && (sblink == link) ) continue; //already done
301 #endif
302                 offset_unitid = 0;
303                 #if HT_CHAIN_UNITID_BASE != 1
304                         #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
305                         if((nodeid == 0) && (sblink == link))
306                         #endif
307                                 offset_unitid = 1;
308                 #endif
309
310                 max = amdk8_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
311         }
312 #if 0
313         printk_debug("%s amdk8_scan_chains max: %d done\n",
314                 dev_path(dev), max);
315 #endif
316         return max;
317 }
318
319
320 static int reg_useable(unsigned reg, 
321         device_t goal_dev, unsigned goal_nodeid, unsigned goal_link)
322 {
323         struct resource *res;
324         unsigned nodeid, link;
325         int result;
326         res = 0;
327         for(nodeid = 0; !res && (nodeid < 8); nodeid++) {
328                 device_t dev;
329                 dev = __f0_dev[nodeid];
330                 for(link = 0; !res && (link < 3); link++) {
331                         res = probe_resource(dev, 0x100 + (reg | link));
332                 }
333         }
334         result = 2;
335         if (res) {
336                 result = 0;
337                 if (    (goal_link == (link - 1)) && 
338                         (goal_nodeid == (nodeid - 1)) &&
339                         (res->flags <= 1)) {
340                         result = 1;
341                 }
342         }
343 #if 0
344         printk_debug("reg: %02x result: %d gnodeid: %u glink: %u nodeid: %u link: %u\n",
345                 reg, result, 
346                 goal_nodeid, goal_link, 
347                 nodeid, link);
348 #endif
349         return result;
350 }
351
352 static struct resource *amdk8_find_iopair(device_t dev, unsigned nodeid, unsigned link)
353 {
354         struct resource *resource;
355         unsigned free_reg, reg;
356         resource = 0;
357         free_reg = 0;
358         for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
359                 int result;
360                 result = reg_useable(reg, dev, nodeid, link);
361                 if (result == 1) {
362                         /* I have been allocated this one */
363                         break;
364                 }
365                 else if (result > 1) {
366                         /* I have a free register pair */
367                         free_reg = reg;
368                 }
369         }
370         if (reg > 0xd8) {
371                 reg = free_reg;
372         }
373         if (reg > 0) {
374                 resource = new_resource(dev, 0x100 + (reg | link));
375         }
376         return resource;
377 }
378
379 static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsigned link)
380 {
381         struct resource *resource;
382         unsigned free_reg, reg;
383         resource = 0;
384         free_reg = 0;
385         for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
386                 int result;
387                 result = reg_useable(reg, dev, nodeid, link);
388                 if (result == 1) {
389                         /* I have been allocated this one */
390                         break;
391                 }
392                 else if (result > 1) {
393                         /* I have a free register pair */
394                         free_reg = reg;
395                 }
396         }
397         if (reg > 0xb8) {
398                 reg = free_reg;
399         }
400         if (reg > 0) {
401                 resource = new_resource(dev, 0x100 + (reg | link));
402         }
403         return resource;
404 }
405
406 static void amdk8_link_read_bases(device_t dev, unsigned nodeid, unsigned link)
407 {
408         struct resource *resource;
409         
410         /* Initialize the io space constraints on the current bus */
411         resource =  amdk8_find_iopair(dev, nodeid, link);
412         if (resource) {
413                 resource->base  = 0;
414                 resource->size  = 0;
415                 resource->align = log2(HT_IO_HOST_ALIGN);
416                 resource->gran  = log2(HT_IO_HOST_ALIGN);
417                 resource->limit = 0xffffUL;
418                 resource->flags = IORESOURCE_IO;
419                 compute_allocate_resource(&dev->link[link], resource, 
420                         IORESOURCE_IO, IORESOURCE_IO);
421         }
422
423         /* Initialize the prefetchable memory constraints on the current bus */
424         resource = amdk8_find_mempair(dev, nodeid, link);
425         if (resource) {
426                 resource->base  = 0;
427                 resource->size  = 0;
428                 resource->align = log2(HT_MEM_HOST_ALIGN);
429                 resource->gran  = log2(HT_MEM_HOST_ALIGN);
430                 resource->limit = 0xffffffffffULL;
431                 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
432                 compute_allocate_resource(&dev->link[link], resource, 
433                         IORESOURCE_MEM | IORESOURCE_PREFETCH, 
434                         IORESOURCE_MEM | IORESOURCE_PREFETCH);
435         }
436
437         /* Initialize the memory constraints on the current bus */
438         resource = amdk8_find_mempair(dev, nodeid, link);
439         if (resource) {
440                 resource->base  = 0;
441                 resource->size  = 0;
442                 resource->align = log2(HT_MEM_HOST_ALIGN);
443                 resource->gran  = log2(HT_MEM_HOST_ALIGN);
444                 resource->limit = 0xffffffffffULL;
445                 resource->flags = IORESOURCE_MEM;
446                 compute_allocate_resource(&dev->link[link], resource, 
447                         IORESOURCE_MEM | IORESOURCE_PREFETCH, 
448                         IORESOURCE_MEM);
449         }
450 }
451
452 static void amdk8_read_resources(device_t dev)
453 {
454         unsigned nodeid, link;
455         nodeid = amdk8_nodeid(dev);
456         for(link = 0; link < dev->links; link++) {
457                 if (dev->link[link].children) {
458                         amdk8_link_read_bases(dev, nodeid, link);
459                 }
460         }
461 }
462
463 static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned nodeid)
464 {
465         resource_t rbase, rend;
466         unsigned reg, link;
467         char buf[50];
468
469         /* Make certain the resource has actually been set */
470         if (!(resource->flags & IORESOURCE_ASSIGNED)) {
471                 return;
472         }
473
474         /* If I have already stored this resource don't worry about it */
475         if (resource->flags & IORESOURCE_STORED) {
476                 return;
477         }
478         
479         /* Only handle PCI memory and IO resources */
480         if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
481                 return;
482
483         /* Ensure I am actually looking at a resource of function 1 */
484         if (resource->index < 0x100) {
485                 return;
486         }
487         /* Get the base address */
488         rbase = resource->base;
489         
490         /* Get the limit (rounded up) */
491         rend  = resource_end(resource);
492
493         /* Get the register and link */
494         reg  = resource->index & 0xfc;
495         link = resource->index & 3;
496
497         if (resource->flags & IORESOURCE_IO) {
498                 uint32_t base, limit;
499                 compute_allocate_resource(&dev->link[link], resource,
500                         IORESOURCE_IO, IORESOURCE_IO);
501                 base  = f1_read_config32(reg);
502                 limit = f1_read_config32(reg + 0x4);
503                 base  &= 0xfe000fcc;
504                 base  |= rbase  & 0x01fff000;
505                 base  |= 3;
506                 limit &= 0xfe000fc8;
507                 limit |= rend & 0x01fff000;
508                 limit |= (link & 3) << 4;
509                 limit |= (nodeid & 7);
510
511                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
512                         printk_spew("%s, enabling legacy VGA IO forwarding for %s link %s\n",
513                                     __func__, dev_path(dev), link);             
514                         base |= PCI_IO_BASE_VGA_EN;
515                 }
516                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
517                         base |= PCI_IO_BASE_NO_ISA;
518                 }
519                 
520                 f1_write_config32(reg + 0x4, limit);
521                 f1_write_config32(reg, base);
522         }
523         else if (resource->flags & IORESOURCE_MEM) {
524                 uint32_t base, limit;
525                 compute_allocate_resource(&dev->link[link], resource,
526                         IORESOURCE_MEM | IORESOURCE_PREFETCH,
527                         resource->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH));
528                 base  = f1_read_config32(reg);
529                 limit = f1_read_config32(reg + 0x4);
530                 base  &= 0x000000f0;
531                 base  |= (rbase >> 8) & 0xffffff00;
532                 base  |= 3;
533                 limit &= 0x00000048;
534                 limit |= (rend >> 8) & 0xffffff00;
535                 limit |= (link & 3) << 4;
536                 limit |= (nodeid & 7);
537                 f1_write_config32(reg + 0x4, limit);
538                 f1_write_config32(reg, base);
539         }
540         resource->flags |= IORESOURCE_STORED;
541         sprintf(buf, " <node %d link %d>",
542                 nodeid, link);
543         report_resource_stored(dev, resource, buf);
544 }
545
546 /**
547  *
548  * I tried to reuse the resource allocation code in amdk8_set_resource()
549  * but it is too diffcult to deal with the resource allocation magic.
550  */
551 #if CONFIG_CONSOLE_VGA_MULTI == 1
552 extern device_t vga_pri;        // the primary vga device, defined in device.c
553 #endif
554
555 static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
556 {
557         struct resource *resource;
558         unsigned link;
559         uint32_t base, limit;
560         unsigned reg;
561
562         /* find out which link the VGA card is connected,
563          * we only deal with the 'first' vga card */
564         for (link = 0; link < dev->links; link++) {
565                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
566 #if CONFIG_CONSOLE_VGA_MULTI == 1
567                         printk_debug("VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary, 
568                                 dev->link[link].secondary,dev->link[link].subordinate);
569                         /* We need to make sure the vga_pri is under the link */
570                         if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
571                                 (vga_pri->bus->secondary <= dev->link[link].subordinate )
572                         )
573 #endif
574                         break;
575                 }
576         }
577         
578         /* no VGA card installed */
579         if (link == dev->links)
580                 return;
581
582         printk_debug("VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
583
584         /* allocate a temp resrouce for legacy VGA buffer */
585         resource = amdk8_find_mempair(dev, nodeid, link);
586         if(!resource){
587                 printk_debug("VGA: Can not find free mmio reg for legacy VGA buffer\n");
588                 return;
589         }
590         resource->base = 0xa0000;
591         resource->size = 0x20000;
592
593         /* write the resource to the hardware */
594         reg  = resource->index & 0xfc;
595         base  = f1_read_config32(reg);
596         limit = f1_read_config32(reg + 0x4);
597         base  &= 0x000000f0;
598         base  |= (resource->base >> 8) & 0xffffff00;
599         base  |= 3;
600         limit &= 0x00000048;
601         limit |= ((resource->base + resource->size) >> 8) & 0xffffff00;
602         limit |= (resource->index & 3) << 4;
603         limit |= (nodeid & 7);
604         f1_write_config32(reg + 0x4, limit);
605         f1_write_config32(reg, base);
606
607         /* release the temp resource */
608         resource->flags = 0;
609 }
610
611 static void amdk8_set_resources(device_t dev)
612 {
613         unsigned nodeid, link;
614         int i;
615
616         /* Find the nodeid */
617         nodeid = amdk8_nodeid(dev);
618
619         amdk8_create_vga_resource(dev, nodeid);
620         
621         /* Set each resource we have found */
622         for(i = 0; i < dev->resources; i++) {
623                 amdk8_set_resource(dev, &dev->resource[i], nodeid);
624         }
625
626         for(link = 0; link < dev->links; link++) {
627                 struct bus *bus;
628                 bus = &dev->link[link];
629                 if (bus->children) {
630                         assign_resources(bus);
631                 }
632         }
633 }
634
635 static void amdk8_enable_resources(device_t dev)
636 {
637         pci_dev_enable_resources(dev);
638         enable_childrens_resources(dev);
639 }
640
641 static void mcf0_control_init(struct device *dev)
642 {
643 #if 0   
644         printk_debug("NB: Function 0 Misc Control.. ");
645 #endif
646 #if 0
647         printk_debug("done.\n");
648 #endif
649 }
650
651 static struct device_operations northbridge_operations = {
652         .read_resources   = amdk8_read_resources,
653         .set_resources    = amdk8_set_resources,
654         .enable_resources = amdk8_enable_resources,
655         .init             = mcf0_control_init,
656         .scan_bus         = amdk8_scan_chains,
657         .enable           = 0,
658         .ops_pci          = 0,
659 };
660
661
662 static struct pci_driver mcf0_driver __pci_driver = {
663         .ops    = &northbridge_operations,
664         .vendor = PCI_VENDOR_ID_AMD,
665         .device = 0x1100,
666 };
667
668 #if CONFIG_CHIP_NAME == 1
669
670 struct chip_operations northbridge_amd_amdk8_ops = {
671         CHIP_NAME("AMD K8 Northbridge")
672         .enable_dev = 0,
673 };
674
675 #endif
676
677 static void pci_domain_read_resources(device_t dev)
678 {
679         struct resource *resource;
680         unsigned reg;
681
682         /* Find the already assigned resource pairs */
683         get_fx_devs();
684         for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
685                 uint32_t base, limit;
686                 base  = f1_read_config32(reg);
687                 limit = f1_read_config32(reg + 0x04);
688                 /* Is this register allocated? */
689                 if ((base & 3) != 0) {
690                         unsigned nodeid, link;
691                         device_t dev;
692                         nodeid = limit & 7;
693                         link   = (limit >> 4) & 3;
694                         dev = __f0_dev[nodeid];
695                         if (dev) {
696                                 /* Reserve the resource  */
697                                 struct resource *resource;
698                                 resource = new_resource(dev, 0x100 + (reg | link));
699                                 if (resource) {
700                                         resource->flags = 1;
701                                 }
702                         }
703                 }
704         }
705 #if CONFIG_PCI_64BIT_PREF_MEM == 0
706         /* Initialize the system wide io space constraints */
707         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
708         resource->base  = 0x400;
709         resource->limit = 0xffffUL;
710         resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
711
712         /* Initialize the system wide memory resources constraints */
713         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
714         resource->limit = 0xfcffffffffULL;
715         resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
716 #else
717         /* Initialize the system wide io space constraints */
718         resource = new_resource(dev, 0);
719         resource->base  = 0x400;
720         resource->limit = 0xffffUL;
721         resource->flags = IORESOURCE_IO;
722         compute_allocate_resource(&dev->link[0], resource,
723                 IORESOURCE_IO, IORESOURCE_IO);
724
725         /* Initialize the system wide prefetchable memory resources constraints */
726         resource = new_resource(dev, 1);
727         resource->limit = 0xfcffffffffULL;
728         resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
729         compute_allocate_resource(&dev->link[0], resource,
730                 IORESOURCE_MEM | IORESOURCE_PREFETCH,
731                 IORESOURCE_MEM | IORESOURCE_PREFETCH);
732
733         /* Initialize the system wide memory resources constraints */
734         resource = new_resource(dev, 2);
735         resource->limit = 0xfcffffffffULL;
736         resource->flags = IORESOURCE_MEM;
737         compute_allocate_resource(&dev->link[0], resource,
738                 IORESOURCE_MEM | IORESOURCE_PREFETCH,
739                 IORESOURCE_MEM);
740 #endif
741 }
742
743 static void ram_resource(device_t dev, unsigned long index, 
744         unsigned long basek, unsigned long sizek)
745 {
746         struct resource *resource;
747
748         if (!sizek) {
749                 return;
750         }
751         resource = new_resource(dev, index);
752         resource->base  = ((resource_t)basek) << 10;
753         resource->size  = ((resource_t)sizek) << 10;
754         resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
755                 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
756 }
757
758 static void tolm_test(void *gp, struct device *dev, struct resource *new)
759 {
760         struct resource **best_p = gp;
761         struct resource *best;
762         best = *best_p;
763         if (!best || (best->base > new->base)) {
764                 best = new;
765         }
766         *best_p = best;
767 }
768
769 static uint32_t find_pci_tolm(struct bus *bus)
770 {
771         struct resource *min;
772         uint32_t tolm;
773         min = 0;
774         search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
775         tolm = 0xffffffffUL;
776         if (min && tolm > min->base) {
777                 tolm = min->base;
778         }
779         return tolm;
780 }
781
782 #if CONFIG_PCI_64BIT_PREF_MEM == 1
783 #define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
784 #endif
785
786 #if K8_HW_MEM_HOLE_SIZEK != 0
787
788 struct hw_mem_hole_info {
789         unsigned hole_startk;
790         int node_id;
791 };
792
793 static struct hw_mem_hole_info get_hw_mem_hole_info(void)
794 {
795                 struct hw_mem_hole_info mem_hole;
796                 int i;
797
798                 mem_hole.hole_startk = K8_HW_MEM_HOLE_SIZEK;
799                 mem_hole.node_id = -1;
800
801                 for (i = 0; i < 8; i++) {
802                         uint32_t base;
803                         uint32_t hole;
804                         base  = f1_read_config32(0x40 + (i << 3));
805                         if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
806                                 continue;
807                         }
808
809                         hole = pci_read_config32(__f1_dev[i], 0xf0);
810                         if(hole & 1) { // we find the hole 
811                                 mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
812                                 mem_hole.node_id = i; // record the node No with hole
813                                 break; // only one hole
814                         }
815                 }
816
817                 //We need to double check if there is speical set on base reg and limit reg are not continous instead of hole, it will find out it's hole_startk
818                 if(mem_hole.node_id!=-1) {
819                         uint32_t limitk_pri = 0;
820                         for(i=0; i<8; i++) {
821                                 uint32_t base, limit;
822                                 unsigned base_k, limit_k;
823                                 base  = f1_read_config32(0x40 + (i << 3));
824                                 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
825                                         continue;
826                                 }
827
828                                 base_k = (base & 0xffff0000) >> 2;
829                                 if(limitk_pri != base_k) { // we find the hole 
830                                         mem_hole.hole_startk = limitk_pri;
831                                         mem_hole.node_id = i;
832                                         break; //only one hole
833                                 }
834
835                                 limit = f1_read_config32(0x44 + (i << 3));
836                                 limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
837                                 limitk_pri = limit_k;
838                         }
839                 }
840                 
841                 return mem_hole;
842                 
843 }
844 static void disable_hoist_memory(unsigned long hole_startk, int i)
845 {
846         int ii;
847         device_t dev;
848         uint32_t base, limit;
849         uint32_t hoist;
850         uint32_t hole_sizek;
851
852
853         //1. find which node has hole
854         //2. change limit in that node.
855         //3. change base and limit in later node
856         //4. clear that node f0
857
858         //if there is not mem hole enabled, we need to change it's base instead
859
860         hole_sizek = (4*1024*1024) - hole_startk;
861
862         for(ii=7;ii>i;ii--) {
863
864                 base  = f1_read_config32(0x40 + (ii << 3));
865                 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
866                         continue;
867                 }
868                 limit = f1_read_config32(0x44 + (ii << 3));
869                 f1_write_config32(0x44 + (ii << 3),limit - (hole_sizek << 2));
870                 f1_write_config32(0x40 + (ii << 3),base - (hole_sizek << 2));
871         }
872         limit = f1_read_config32(0x44 + (i << 3));
873         f1_write_config32(0x44 + (i << 3),limit - (hole_sizek << 2));
874         dev = __f1_dev[i];
875         hoist = pci_read_config32(dev, 0xf0);
876         if(hoist & 1) {
877                 pci_write_config32(dev, 0xf0, 0);
878         }
879         else {
880                 base = pci_read_config32(dev, 0x40 + (i << 3));
881                 f1_write_config32(0x40 + (i << 3),base - (hole_sizek << 2));
882         }
883                 
884 }
885
886 static uint32_t hoist_memory(unsigned long hole_startk, int i)
887 {
888         int ii;
889         uint32_t carry_over;
890         device_t dev;
891         uint32_t base, limit;
892         uint32_t basek;
893         uint32_t hoist;
894
895         carry_over = (4*1024*1024) - hole_startk;
896
897         for(ii=7;ii>i;ii--) {
898
899                 base  = f1_read_config32(0x40 + (ii << 3));
900                 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
901                         continue;
902                 }
903                 limit = f1_read_config32(0x44 + (ii << 3));
904                 f1_write_config32(0x44 + (ii << 3),limit + (carry_over << 2));
905                 f1_write_config32(0x40 + (ii << 3),base + (carry_over << 2));
906         }
907         limit = f1_read_config32(0x44 + (i << 3));
908         f1_write_config32(0x44 + (i << 3),limit + (carry_over << 2));
909         dev = __f1_dev[i];
910         base  = pci_read_config32(dev, 0x40 + (i << 3));
911         basek  = (base & 0xffff0000) >> 2;
912         if(basek == hole_startk) {
913                 //don't need set memhole here, because hole off set will be 0, overflow
914                 //so need to change base reg instead, new basek will be 4*1024*1024
915                 base &= 0x0000ffff;
916                 base |= (4*1024*1024)<<2;
917                 f1_write_config32(0x40 + (i<<3), base);
918         }
919         else 
920         {
921                 hoist = /* hole start address */
922                         ((hole_startk << 10) & 0xff000000) +
923                         /* hole address to memory controller address */
924                         (((basek + carry_over) >> 6) & 0x0000ff00) +
925                         /* enable */
926                         1;
927         
928                 pci_write_config32(dev, 0xf0, hoist);
929         }
930
931         return carry_over;
932 }
933 #endif
934
935 static void pci_domain_set_resources(device_t dev)
936 {
937 #if CONFIG_PCI_64BIT_PREF_MEM == 1
938         struct resource *io, *mem1, *mem2;
939         struct resource *resource, *last;
940 #endif
941         unsigned long mmio_basek;
942         uint32_t pci_tolm;
943         int i, idx;
944 #if K8_HW_MEM_HOLE_SIZEK != 0
945         struct hw_mem_hole_info mem_hole;
946         unsigned reset_memhole = 1;
947 #endif
948
949 #if 0
950         /* Place the IO devices somewhere safe */
951         io = find_resource(dev, 0);
952         io->base = DEVICE_IO_START;
953 #endif
954 #if CONFIG_PCI_64BIT_PREF_MEM == 1
955         /* Now reallocate the pci resources memory with the
956          * highest addresses I can manage.
957          */
958         mem1 = find_resource(dev, 1);
959         mem2 = find_resource(dev, 2);
960
961 #if 1
962                 printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
963                         mem1->base, mem1->limit, mem1->size, mem1->align);
964                 printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
965                         mem2->base, mem2->limit, mem2->size, mem2->align);
966 #endif
967
968         /* See if both resources have roughly the same limits */
969         if (((mem1->limit <= 0xffffffff) && (mem2->limit <= 0xffffffff)) ||
970                 ((mem1->limit > 0xffffffff) && (mem2->limit > 0xffffffff)))
971         {
972                 /* If so place the one with the most stringent alignment first
973                  */
974                 if (mem2->align > mem1->align) {
975                         struct resource *tmp;
976                         tmp = mem1;
977                         mem1 = mem2;
978                         mem2 = tmp;
979                 }
980                 /* Now place the memory as high up as it will go */
981                 mem2->base = resource_max(mem2);
982                 mem1->limit = mem2->base - 1;
983                 mem1->base = resource_max(mem1);
984         }
985         else {
986                 /* Place the resources as high up as they will go */
987                 mem2->base = resource_max(mem2);
988                 mem1->base = resource_max(mem1);
989         }
990
991 #if 1
992                 printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
993                         mem1->base, mem1->limit, mem1->size, mem1->align);
994                 printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
995                         mem2->base, mem2->limit, mem2->size, mem2->align);
996 #endif
997
998         last = &dev->resource[dev->resources];
999         for(resource = &dev->resource[0]; resource < last; resource++)
1000         {
1001 #if 1
1002                 resource->flags |= IORESOURCE_ASSIGNED;
1003                 resource->flags &= ~IORESOURCE_STORED;
1004 #endif
1005                 compute_allocate_resource(&dev->link[0], resource,
1006                         BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
1007
1008                 resource->flags |= IORESOURCE_STORED;
1009                 report_resource_stored(dev, resource, "");
1010
1011         }
1012 #endif
1013
1014
1015         pci_tolm = find_pci_tolm(&dev->link[0]);
1016
1017 #warning "FIXME handle interleaved nodes"
1018         mmio_basek = pci_tolm >> 10;
1019         /* Round mmio_basek to something the processor can support */
1020         mmio_basek &= ~((1 << 6) -1);
1021
1022 #if 1
1023 #warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole"
1024         /* Round the mmio hold to 64M */
1025         mmio_basek &= ~((64*1024) - 1);
1026 #endif
1027
1028 #if K8_HW_MEM_HOLE_SIZEK != 0
1029     /* if the hw mem hole is already set in raminit stage, here we will compare mmio_basek and hole_basek
1030      * if mmio_basek is bigger that hole_basek and will use hole_basek as mmio_basek and we don't need to reset hole.
1031      * otherwise We reset the hole to the mmio_basek
1032      */
1033         if (!is_cpu_pre_e0()) {
1034
1035                 mem_hole = get_hw_mem_hole_info();
1036
1037                 if ((mem_hole.node_id !=  -1) && (mmio_basek > mem_hole.hole_startk)) { //We will use hole_basek as mmio_basek, and we don't need to reset hole anymore
1038                         mmio_basek = mem_hole.hole_startk;
1039                         reset_memhole = 0;
1040                 }
1041                 
1042                 //mmio_basek = 3*1024*1024; // for debug to meet boundary
1043
1044                 if(reset_memhole) {
1045                         if(mem_hole.node_id!=-1) { // We need to select K8_HW_MEM_HOLE_SIZEK for raminit, it can not make hole_startk to some basek too....!
1046                                // We need to reset our Mem Hole, because We want more big HOLE than we already set
1047                                //Before that We need to disable mem hole at first, becase memhole could already be set on i+1 instead
1048                                 disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
1049                         }
1050
1051                 #if K8_HW_MEM_HOLE_SIZE_AUTO_INC == 1
1052                         //We need to double check if the mmio_basek is valid for hole setting, if it is equal to basek, we need to decrease it some
1053                         uint32_t basek_pri; 
1054                         for (i = 0; i < 8; i++) {
1055                                 uint32_t base;
1056                                 uint32_t basek;
1057                                 base  = f1_read_config32(0x40 + (i << 3));
1058                                 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
1059                                         continue;
1060                                 }
1061
1062                                 basek = (base & 0xffff0000) >> 2;
1063                                 if(mmio_basek == basek) {
1064                                         mmio_basek -= (basek - basek_pri)>>1; // increase mem hole size to make sure it is on middle of pri node 
1065                                         break; 
1066                                 }
1067                                 basek_pri = basek;
1068                         }       
1069                 #endif  
1070                 }
1071
1072         } // is_cpu_pre_e0
1073
1074 #endif
1075
1076         idx = 0x10;
1077         for(i = 0; i < 8; i++) {
1078                 uint32_t base, limit;
1079                 unsigned basek, limitk, sizek;
1080                 base  = f1_read_config32(0x40 + (i << 3));
1081                 limit = f1_read_config32(0x44 + (i << 3));
1082                 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
1083                         continue;
1084                 }
1085                 basek = (base & 0xffff0000) >> 2;
1086                 limitk = ((limit + 0x00010000) & 0xffff0000) >> 2;
1087                 sizek = limitk - basek;
1088
1089                 /* see if we need a hole from 0xa0000 to 0xbffff */
1090                 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
1091                         ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
1092                         idx += 0x10;
1093                         basek = (8*64)+(16*16);
1094                         sizek = limitk - ((8*64)+(16*16));
1095                         
1096                 }
1097
1098         
1099 //              printk_debug("node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk); //yhlu 
1100                         
1101                 /* See if I need to split the region to accomodate pci memory space */
1102                 if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) {
1103                         if (basek <= mmio_basek) {
1104                                 unsigned pre_sizek;
1105                                 pre_sizek = mmio_basek - basek;
1106                                 if(pre_sizek>0) {
1107                                         ram_resource(dev, (idx | i), basek, pre_sizek);
1108                                         idx += 0x10;
1109                                         sizek -= pre_sizek;
1110                                 }
1111                                 #if K8_HW_MEM_HOLE_SIZEK != 0
1112                                 if(reset_memhole) 
1113                                         if(!is_cpu_pre_e0() ) 
1114                                                  sizek += hoist_memory(mmio_basek,i);
1115                                 #endif
1116                                 
1117                                 basek = mmio_basek;
1118                         }
1119                         if ((basek + sizek) <= 4*1024*1024) {
1120                                 sizek = 0;
1121                         }
1122                         else {
1123                                 basek = 4*1024*1024;
1124                                 sizek -= (4*1024*1024 - mmio_basek);
1125                         }
1126                 }
1127                 ram_resource(dev, (idx | i), basek, sizek);
1128                 idx += 0x10;
1129         }
1130         assign_resources(&dev->link[0]);
1131 }
1132
1133 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
1134 {
1135         unsigned reg;
1136         int i;
1137         /* Unmap all of the HT chains */
1138         for(reg = 0xe0; reg <= 0xec; reg += 4) {
1139                 f1_write_config32(reg, 0);
1140         }
1141         max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);  
1142         
1143         /* Tune the hypertransport transaction for best performance.
1144          * Including enabling relaxed ordering if it is safe.
1145          */
1146         get_fx_devs();
1147         for(i = 0; i < FX_DEVS; i++) {
1148                 device_t f0_dev;
1149                 f0_dev = __f0_dev[i];
1150                 if (f0_dev && f0_dev->enabled) {
1151                         uint32_t httc;
1152                         int j;
1153                         httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
1154                         httc &= ~HTTC_RSP_PASS_PW;
1155                         if (!dev->link[0].disable_relaxed_ordering) {
1156                                 httc |= HTTC_RSP_PASS_PW;
1157                         }
1158                         printk_spew("%s passpw: %s\n",
1159                                 dev_path(dev),
1160                                 (!dev->link[0].disable_relaxed_ordering)?
1161                                 "enabled":"disabled");
1162                         pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
1163                 }
1164         }
1165         return max;
1166 }
1167
1168 static struct device_operations pci_domain_ops = {
1169         .read_resources   = pci_domain_read_resources,
1170         .set_resources    = pci_domain_set_resources,
1171         .enable_resources = enable_childrens_resources,
1172         .init             = 0,
1173         .scan_bus         = pci_domain_scan_bus,
1174         .ops_pci_bus      = &pci_cf8_conf1,
1175 };
1176
1177 static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
1178 {
1179         struct bus *cpu_bus;
1180         device_t dev_mc;
1181         int bsp_apicid;
1182         int apicid_offset;
1183         int i,j;
1184         int nodes;
1185         unsigned nb_cfg_54;
1186         int enable_apic_ext_id;
1187         unsigned siblings;
1188         int e0_later_single_core; 
1189         int disable_siblings;
1190         unsigned lift_bsp_apicid;
1191
1192         nb_cfg_54 = 0;
1193         enable_apic_ext_id = 0;
1194         lift_bsp_apicid = 0;
1195         siblings = 0;
1196
1197         /* Find the bootstrap processors apicid */
1198         bsp_apicid = lapicid();
1199         apicid_offset = bsp_apicid;
1200
1201         disable_siblings = !CONFIG_LOGICAL_CPUS;
1202 #if CONFIG_LOGICAL_CPUS == 1
1203         get_option(&disable_siblings, "dual_core");
1204 #endif
1205
1206         // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it still be 0)
1207         // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp??? and differ d0 and e0 single core
1208
1209         nb_cfg_54 = read_nb_cfg_54();
1210
1211         dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
1212         if (!dev_mc) {
1213                 die("0:18.0 not found?");
1214         }
1215
1216         nodes = ((pci_read_config32(dev_mc, 0x60)>>4) & 7) + 1;
1217
1218         if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
1219         {
1220                 enable_apic_ext_id = 1;
1221                 if(bsp_apicid == 0) {
1222                         /* bsp apic id is not changed */
1223                         apicid_offset = APIC_ID_OFFSET;
1224                 } else 
1225                 {
1226                         lift_bsp_apicid = 1;
1227                 }       
1228                 
1229         }
1230
1231         /* Find which cpus are present */
1232         cpu_bus = &dev->link[0];
1233         for(i = 0; i < nodes; i++) {
1234                 device_t dev, cpu;
1235                 struct device_path cpu_path;
1236
1237                 /* Find the cpu's pci device */
1238                 dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
1239                 if (!dev) {
1240                         /* If I am probing things in a weird order
1241                          * ensure all of the cpu's pci devices are found.
1242                          */
1243                         int j;
1244                         device_t dev_f0;
1245                         for(j = 0; j <= 3; j++) {
1246                                 dev = pci_probe_dev(NULL, dev_mc->bus,
1247                                         PCI_DEVFN(0x18 + i, j));
1248                         }
1249                         /* Ok, We need to set the links for that device.
1250                          * otherwise the device under it will not be scanned
1251                          */
1252                         dev_f0 = dev_find_slot(0, PCI_DEVFN(0x18+i,0));
1253                         if(dev_f0) {
1254                                 dev_f0->links = 3;
1255                                 for(j=0;j<3;j++) {
1256                                         dev_f0->link[j].link = j;
1257                                         dev_f0->link[j].dev = dev_f0;
1258                                 }
1259                         }
1260
1261                 }
1262
1263                 e0_later_single_core = 0;
1264                 if (dev && dev->enabled) {
1265                         j = pci_read_config32(dev, 0xe8);
1266                         j = (j >> 12) & 3; // dev is func 3
1267                         printk_debug("  %s siblings=%d\r\n", dev_path(dev), j);
1268
1269                         if(nb_cfg_54) {
1270                                 // For e0 single core if nb_cfg_54 is set, apicid will be 0, 2, 4.... 
1271                                 //  ----> you can mixed single core e0 and dual core e0 at any sequence
1272                                 // That is the typical case
1273
1274                                 if(j == 0 ){
1275                                         e0_later_single_core = is_e0_later_in_bsp(i);  // single core 
1276                                 } else {
1277                                        e0_later_single_core = 0;
1278                                 }
1279                                 if(e0_later_single_core) { 
1280                                         printk_debug("\tFound Rev E or Rev F later single core\r\n");
1281
1282                                         j=1; 
1283                                 }
1284         
1285                                 if(siblings > j ) {
1286                                 }
1287                                 else {
1288                                         siblings = j;
1289                                 }
1290                         } else {
1291                                 siblings = j;
1292                         }
1293                 }
1294                 
1295                 unsigned jj;
1296                 if(e0_later_single_core || disable_siblings) {
1297                         jj = 0;
1298                 } else 
1299                 {
1300                         jj = siblings;
1301                 }
1302 #if 0   
1303                 jj = 0; // if create cpu core1 path in amd_siblings by core0
1304 #endif
1305         
1306                 for (j = 0; j <=jj; j++ ) {
1307                 
1308                         /* Build the cpu device path */
1309                         cpu_path.type = DEVICE_PATH_APIC;
1310                         cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
1311                         
1312                         /* See if I can find the cpu */
1313                         cpu = find_dev_path(cpu_bus, &cpu_path);
1314                         
1315                         /* Enable the cpu if I have the processor */
1316                         if (dev && dev->enabled) {
1317                                 if (!cpu) {
1318                                         cpu = alloc_dev(cpu_bus, &cpu_path);
1319                                 }
1320                                 if (cpu) {
1321                                         cpu->enabled = 1;
1322                                 }
1323                         }
1324                 
1325                         /* Disable the cpu if I don't have the processor */
1326                         if (cpu && (!dev || !dev->enabled)) {
1327                                 cpu->enabled = 0;
1328                         }
1329
1330                         /* Report what I have done */
1331                         if (cpu) {
1332                                 cpu->path.u.apic.node_id = i;
1333                                 cpu->path.u.apic.core_id = j;
1334                                 if(enable_apic_ext_id) {
1335                                         if(lift_bsp_apicid) { 
1336                                                 cpu->path.u.apic.apic_id += apicid_offset;
1337                                         } else 
1338                                         {
1339                                                if (cpu->path.u.apic.apic_id != 0) 
1340                                                        cpu->path.u.apic.apic_id += apicid_offset;
1341                                         }
1342                                 }
1343                                 printk_debug("CPU: %s %s\n",
1344                                         dev_path(cpu), cpu->enabled?"enabled":"disabled");
1345                         }
1346
1347                 } //j
1348         }
1349         return max;
1350 }
1351
1352 static void cpu_bus_init(device_t dev)
1353 {
1354         initialize_cpus(&dev->link[0]);
1355 }
1356
1357 static void cpu_bus_noop(device_t dev) 
1358 {
1359 }
1360
1361 static struct device_operations cpu_bus_ops = {
1362         .read_resources   = cpu_bus_noop,
1363         .set_resources    = cpu_bus_noop,
1364         .enable_resources = cpu_bus_noop,
1365         .init             = cpu_bus_init,
1366         .scan_bus         = cpu_bus_scan,
1367 };
1368
1369 static void root_complex_enable_dev(struct device *dev)
1370 {
1371         /* Set the operations if it is a special bus type */
1372         if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
1373                 dev->ops = &pci_domain_ops;
1374         }
1375         else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
1376                 dev->ops = &cpu_bus_ops;
1377         }
1378 }
1379
1380 struct chip_operations northbridge_amd_amdk8_root_complex_ops = {
1381         CHIP_NAME("AMD K8 Root Complex")
1382         .enable_dev = root_complex_enable_dev,
1383 };