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