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