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