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