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