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