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