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