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