Initial AMD Barcelona support for rev Bx.
[coreboot.git] / src / northbridge / amd / amdfam10 / northbridge.c
1 /*
2  * This file is part of the LinuxBIOS 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 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(CBB, PCI_DEVFN(CDB + nodeid, fn));
64         } else {
65                 return dev_find_slot(CBB-1, PCI_DEVFN(CDB + nodeid - 32, fn));
66         }
67
68 #else
69         return dev_find_slot(CBB, PCI_DEVFN(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", CBB, 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 != CBB) {
117                 return (dev->path.u.pci.devfn >> 3) - CDB + 32;
118         } else {
119                 return (dev->path.u.pci.devfn >> 3) - CDB;
120         }
121
122 #else
123         return (dev->path.u.pci.devfn >> 3) - 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 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 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 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 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 SB_HT_CHAIN_ON_BUS0 > 0
299         if(nodeid==0) {
300         #if ((HT_CHAIN_UNITID_BASE != 1) || (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 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 SB_HT_CHAIN_ON_BUS0 > 0
315                 if( (nodeid == 0) && (sblink == link) ) continue; //already done
316 #endif
317                 offset_unitid = 0;
318                 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
319                         #if 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                 for(link = 0; !res && (link < 8); link++) {
342                         res = probe_resource(dev, 0x1000 + reg + (link<<16)); // 8 links, 0x1000 man f1,
343                 }
344         }
345         result = 2;
346         if (res) {
347                 result = 0;
348                 if (    (goal_link == (link - 1)) &&
349                         (goal_nodeid == (nodeid - 1)) &&
350                         (res->flags <= 1)) {
351                         result = 1;
352                 }
353         }
354         return result;
355 }
356
357 static struct resource *amdfam10_find_iopair(device_t dev, u32 nodeid, u32 link)
358 {
359         struct resource *resource;
360         u32 free_reg, reg;
361         resource = 0;
362         free_reg = 0;
363         for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
364                 int result;
365                 result = reg_useable(reg, dev, nodeid, link);
366                 if (result == 1) {
367                         /* I have been allocated this one */
368                         break;
369                 }
370                 else if (result > 1) {
371                         /* I have a free register pair */
372                         free_reg = reg;
373                 }
374         }
375         if (reg > 0xd8) {
376                 reg = free_reg; // if no free, the free_reg still be 0
377         }
378
379         //Ext conf space
380         if(!reg) {
381                 //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
382                 u32 index = get_io_addr_index(nodeid, link);
383                 reg = 0x110+ (index<<24) + (4<<20); // index could be 0, 255
384         }
385
386         resource = new_resource(dev, 0x1000 + reg + (link<<16));
387
388         return resource;
389 }
390
391 static struct resource *amdfam10_find_mempair(device_t dev, u32 nodeid, u32 link)
392 {
393         struct resource *resource;
394         u32 free_reg, reg;
395         resource = 0;
396         free_reg = 0;
397         for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
398                 int result;
399                 result = reg_useable(reg, dev, nodeid, link);
400                 if (result == 1) {
401                         /* I have been allocated this one */
402                         break;
403                 }
404                 else if (result > 1) {
405                         /* I have a free register pair */
406                         free_reg = reg;
407                 }
408         }
409         if (reg > 0xb8) {
410                 reg = free_reg;
411         }
412
413         //Ext conf space
414         if(!reg) {
415                 //because of Extend conf space, we will never run out of reg,
416                 // but we need one index to differ them. so same node and
417                 // same link can have multi range
418                 u32 index = get_mmio_addr_index(nodeid, link);
419                 reg = 0x110+ (index<<24) + (6<<20); // index could be 0, 63
420
421         }
422         resource = new_resource(dev, 0x1000 + reg + (link<<16));
423         return resource;
424 }
425
426
427 static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link)
428 {
429         struct resource *resource;
430
431         /* Initialize the io space constraints on the current bus */
432         resource =  amdfam10_find_iopair(dev, nodeid, link);
433         if (resource) {
434                 u32 align;
435 #if EXT_CONF_SUPPORT == 1
436                 if((resource->index & 0x1fff) == 0x1110) { // ext
437                         align = 8;
438                 }
439                 else
440 #endif
441                         align = log2(HT_IO_HOST_ALIGN);
442                 resource->base  = 0;
443                 resource->size  = 0;
444                 resource->align = align;
445                 resource->gran  = align;
446                 resource->limit = 0xffffUL;
447                 resource->flags = IORESOURCE_IO;
448                 compute_allocate_resource(&dev->link[link], resource,
449                                         IORESOURCE_IO, IORESOURCE_IO);
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;
461                 compute_allocate_resource(&dev->link[link], resource,
462                         IORESOURCE_MEM | IORESOURCE_PREFETCH,
463                         IORESOURCE_MEM | IORESOURCE_PREFETCH);
464
465 #if EXT_CONF_SUPPORT == 1
466                 if((resource->index & 0x1fff) == 0x1110) { // ext
467                         normalize_resource(resource);
468                 }
469 #endif
470
471         }
472
473         /* Initialize the memory constraints on the current bus */
474         resource = amdfam10_find_mempair(dev, nodeid, link);
475         if (resource) {
476                 resource->base  = 0;
477                 resource->size  = 0;
478                 resource->align = log2(HT_MEM_HOST_ALIGN);
479                 resource->gran  = log2(HT_MEM_HOST_ALIGN);
480                 resource->limit = 0xffffffffffULL;
481                 resource->flags = IORESOURCE_MEM;
482                 compute_allocate_resource(&dev->link[link], resource,
483                         IORESOURCE_MEM | IORESOURCE_PREFETCH,
484                         IORESOURCE_MEM);
485
486 #if EXT_CONF_SUPPORT == 1
487                 if((resource->index & 0x1fff) == 0x1110) { // ext
488                         normalize_resource(resource);
489                 }
490 #endif
491
492         }
493 }
494
495
496 static void amdfam10_read_resources(device_t dev)
497 {
498         u32 nodeid, link;
499
500         nodeid = amdfam10_nodeid(dev);
501         for(link = 0; link < dev->links; link++) {
502                 if (dev->link[link].children) {
503                         amdfam10_link_read_bases(dev, nodeid, link);
504                 }
505         }
506 }
507
508
509 static void amdfam10_set_resource(device_t dev, struct resource *resource,
510                                 u32 nodeid)
511 {
512         resource_t rbase, rend;
513         unsigned reg, link;
514         char buf[50];
515
516         /* Make certain the resource has actually been set */
517         if (!(resource->flags & IORESOURCE_ASSIGNED)) {
518                 return;
519         }
520
521         /* If I have already stored this resource don't worry about it */
522         if (resource->flags & IORESOURCE_STORED) {
523                 return;
524         }
525
526         /* Only handle PCI memory and IO resources */
527         if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
528                 return;
529
530         /* Ensure I am actually looking at a resource of function 1 */
531         if ((resource->index & 0xffff) < 0x1000) {
532                 return;
533         }
534         /* Get the base address */
535         rbase = resource->base;
536
537         /* Get the limit (rounded up) */
538         rend  = resource_end(resource);
539
540         /* Get the register and link */
541         reg  = resource->index & 0xfff; // 4k
542         link = ( resource->index>> 16)& 0x7; // 8 links
543
544         if (resource->flags & IORESOURCE_IO) {
545                 compute_allocate_resource(&dev->link[link], resource,
546                         IORESOURCE_IO, IORESOURCE_IO);
547
548                 set_io_addr_reg(dev, nodeid, link, reg, rbase>>8, rend>>8);
549                 store_conf_io_addr(nodeid, link, reg, (resource->index >> 24), rbase>>8, rend>>8);
550         }
551         else if (resource->flags & IORESOURCE_MEM) {
552                 compute_allocate_resource(&dev->link[link], resource,
553                         IORESOURCE_MEM | IORESOURCE_PREFETCH,
554                         resource->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH));
555                 set_mmio_addr_reg(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
556                 store_conf_mmio_addr(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8);
557         }
558         resource->flags |= IORESOURCE_STORED;
559         sprintf(buf, " <node %02x link %02x>",
560                 nodeid, link);
561         report_resource_stored(dev, resource, buf);
562 }
563
564 /**
565  *
566  * I tried to reuse the resource allocation code in amdfam10_set_resource()
567  * but it is too diffcult to deal with the resource allocation magic.
568  */
569 #if CONFIG_CONSOLE_VGA_MULTI == 1
570 extern device_t vga_pri;        // the primary vga device, defined in device.c
571 #endif
572
573 static void amdfam10_create_vga_resource(device_t dev, unsigned nodeid)
574 {
575         unsigned link;
576
577         /* find out which link the VGA card is connected,
578          * we only deal with the 'first' vga card */
579         for (link = 0; link < dev->links; link++) {
580                 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
581 #if CONFIG_CONSOLE_VGA_MULTI == 1
582                         printk_debug("VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
583                                 dev->link[link].secondary,dev->link[link].subordinate);
584                         /* We need to make sure the vga_pri is under the link */
585                         if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
586                                 (vga_pri->bus->secondary <= dev->link[link].subordinate )
587                         )
588 #endif
589                         break;
590                 }
591         }
592
593         /* no VGA card installed */
594         if (link == dev->links)
595                 return;
596
597         printk_debug("VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
598         set_vga_enable_reg(nodeid, link);
599 }
600
601 static void amdfam10_set_resources(device_t dev)
602 {
603         u32 nodeid, link;
604         int i;
605
606         /* Find the nodeid */
607         nodeid = amdfam10_nodeid(dev);
608
609         amdfam10_create_vga_resource(dev, nodeid);
610
611         /* Set each resource we have found */
612         for(i = 0; i < dev->resources; i++) {
613                 amdfam10_set_resource(dev, &dev->resource[i], nodeid);
614         }
615
616         for(link = 0; link < dev->links; link++) {
617                 struct bus *bus;
618                 bus = &dev->link[link];
619                 if (bus->children) {
620                         assign_resources(bus);
621                 }
622         }
623 }
624
625
626 static void amdfam10_enable_resources(device_t dev)
627 {
628         pci_dev_enable_resources(dev);
629         enable_childrens_resources(dev);
630 }
631
632 static void mcf0_control_init(struct device *dev)
633 {
634 }
635
636 static struct device_operations northbridge_operations = {
637         .read_resources   = amdfam10_read_resources,
638         .set_resources    = amdfam10_set_resources,
639         .enable_resources = amdfam10_enable_resources,
640         .init             = mcf0_control_init,
641         .scan_bus         = amdfam10_scan_chains,
642         .enable           = 0,
643         .ops_pci          = 0,
644 };
645
646
647 static struct pci_driver mcf0_driver __pci_driver = {
648         .ops    = &northbridge_operations,
649         .vendor = PCI_VENDOR_ID_AMD,
650         .device = 0x1200,
651 };
652
653 #if CONFIG_CHIP_NAME == 1
654
655 struct chip_operations northbridge_amd_amdfam10_ops = {
656         CHIP_NAME("AMD FAM10 Northbridge")
657         .enable_dev = 0,
658 };
659
660 #endif
661
662 static void pci_domain_read_resources(device_t dev)
663 {
664         struct resource *resource;
665         unsigned reg;
666         unsigned link;
667
668         /* Find the already assigned resource pairs */
669         get_fx_devs();
670         for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
671                 u32 base, limit;
672                 base  = f1_read_config32(reg);
673                 limit = f1_read_config32(reg + 0x04);
674                 /* Is this register allocated? */
675                 if ((base & 3) != 0) {
676                         unsigned nodeid, link;
677                         device_t dev;
678                         if(reg<0xc0) { // mmio
679                                 nodeid = (limit & 0xf) + (base&0x30);
680                         } else { // io
681                                 nodeid =  (limit & 0xf) + ((base>>4)&0x30);
682                         }
683                         link   = (limit >> 4) & 7;
684                         dev = __f0_dev[nodeid];
685                         if (dev) {
686                                 /* Reserve the resource  */
687                                 struct resource *resource;
688                                 resource = new_resource(dev, 0x1000 + reg + (link<<16));
689                                 if (resource) {
690                                         resource->flags = 1;
691                                 }
692                         }
693                 }
694         }
695         /* FIXME: do we need to check extend conf space?
696            I don't believe that much preset value */
697
698 #if CONFIG_PCI_64BIT_PREF_MEM == 0
699         /* Initialize the system wide io space constraints */
700         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
701         resource->base  = 0x400;
702         resource->limit = 0xffffUL;
703         resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
704
705         /* Initialize the system wide memory resources constraints */
706         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
707         resource->limit = 0xfcffffffffULL;
708         resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
709 #else
710         for(link=0; link<dev->links; link++) {
711                 /* Initialize the system wide io space constraints */
712                 resource = new_resource(dev, 0|(link<<2));
713                 resource->base  = 0x400;
714                 resource->limit = 0xffffUL;
715                 resource->flags = IORESOURCE_IO;
716                 compute_allocate_resource(&dev->link[link], resource,
717                         IORESOURCE_IO, IORESOURCE_IO);
718
719                 /* Initialize the system wide prefetchable memory resources constraints */
720                 resource = new_resource(dev, 1|(link<<2));
721                 resource->limit = 0xfcffffffffULL;
722                 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
723                 compute_allocate_resource(&dev->link[link], resource,
724                         IORESOURCE_MEM | IORESOURCE_PREFETCH,
725                         IORESOURCE_MEM | IORESOURCE_PREFETCH);
726
727                 /* Initialize the system wide memory resources constraints */
728                 resource = new_resource(dev, 2|(link<<2));
729                 resource->limit = 0xfcffffffffULL;
730                 resource->flags = IORESOURCE_MEM;
731                 compute_allocate_resource(&dev->link[link], resource,
732                         IORESOURCE_MEM | IORESOURCE_PREFETCH,
733                         IORESOURCE_MEM);
734         }
735 #endif
736 }
737
738 static void ram_resource(device_t dev, unsigned long index,
739         resource_t basek, resource_t sizek)
740 {
741         struct resource *resource;
742
743         if (!sizek) {
744                 return;
745         }
746         resource = new_resource(dev, index);
747         resource->base  = basek << 10;
748         resource->size  = sizek << 10;
749         resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
750                 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
751 }
752
753 static void tolm_test(void *gp, struct device *dev, struct resource *new)
754 {
755         struct resource **best_p = gp;
756         struct resource *best;
757         best = *best_p;
758         if (!best || (best->base > new->base)) {
759                 best = new;
760         }
761         *best_p = best;
762 }
763
764 static u32 find_pci_tolm(struct bus *bus, u32 tolm)
765 {
766         struct resource *min;
767         min = 0;
768         search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
769         if (min && tolm > min->base) {
770                 tolm = min->base;
771         }
772         return tolm;
773 }
774
775 #if CONFIG_PCI_64BIT_PREF_MEM == 1
776 #define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
777 #endif
778
779 #if HW_MEM_HOLE_SIZEK != 0
780
781 struct hw_mem_hole_info {
782         unsigned hole_startk;
783         int node_id;
784 };
785
786 static struct hw_mem_hole_info get_hw_mem_hole_info(void)
787 {
788                 struct hw_mem_hole_info mem_hole;
789                 int i;
790
791                 mem_hole.hole_startk = HW_MEM_HOLE_SIZEK;
792                 mem_hole.node_id = -1;
793
794                 for (i = 0; i < sysconf.nodes; i++) {
795                         struct dram_base_mask_t d;
796                         u32 hole;
797                         d = get_dram_base_mask(i);
798                         if(!(d.mask & 1)) continue; // no memory on this node
799
800                         hole = pci_read_config32(__f1_dev[i], 0xf0);
801                         if(hole & 1) { // we find the hole
802                                 mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
803                                 mem_hole.node_id = i; // record the node No with hole
804                                 break; // only one hole
805                         }
806                 }
807
808                 //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
809                 if(mem_hole.node_id==-1) {
810                         resource_t limitk_pri = 0;
811                         for(i=0; i<sysconf.nodes; i++) {
812                                 struct dram_base_mask_t d;
813                                 resource_t base_k, limit_k;
814                                 d = get_dram_base_mask(i);
815                                 if(!(d.base & 1)) continue;
816
817                                 base_k = ((resource_t)(d.base & 0x1fffff00)) <<9;
818                                 if(base_k > 4 *1024 * 1024) break; // don't need to go to check
819                                 if(limitk_pri != base_k) { // we find the hole
820                                         mem_hole.hole_startk = (unsigned)limitk_pri; // must beblow 4G
821                                         mem_hole.node_id = i;
822                                         break; //only one hole
823                                 }
824
825                                 limit_k = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9;
826                                 limitk_pri = limit_k;
827                         }
828                 }
829                 return mem_hole;
830 }
831
832
833 #if CONFIG_AMDMCT == 0
834 static void disable_hoist_memory(unsigned long hole_startk, int i)
835 {
836         int ii;
837         device_t dev;
838         struct dram_base_mask_t d;
839         u32 sel_m;
840         u32 sel_hi_en;
841         u32 hoist;
842         u32 hole_sizek;
843
844         u32 one_DCT;
845         struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
846         struct mem_info *meminfo;
847         meminfo = &sysinfox->meminfo[i];
848
849         one_DCT = get_one_DCT(meminfo);
850
851         // 1. find which node has hole
852         // 2. change limit in that node.
853         // 3. change base and limit in later node
854         // 4. clear that node f0
855
856         // if there is not mem hole enabled, we need to change it's base instead
857
858         hole_sizek = (4*1024*1024) - hole_startk;
859
860         for(ii=NODE_NUMS-1;ii>i;ii--) {
861
862                 d = get_dram_base_mask(ii);
863
864                 if(!(d.mask & 1)) continue;
865
866                 d.base -= (hole_sizek>>9);
867                 d.mask -= (hole_sizek>>9);
868                 set_dram_base_mask(ii, d, sysconf.nodes);
869
870                 if(get_DctSelHiEn(ii) & 1) {
871                         sel_m = get_DctSelBaseAddr(ii);
872                         sel_m -= hole_startk>>10;
873                         set_DctSelBaseAddr(ii, sel_m);
874                 }
875         }
876
877         d = get_dram_base_mask(i);
878         dev = __f1_dev[i];
879         hoist = pci_read_config32(dev, 0xf0);
880         sel_hi_en = get_DctSelHiEn(i);
881
882         if(sel_hi_en & 1) {
883                 sel_m = get_DctSelBaseAddr(i);
884         }
885
886         if(hoist & 1) {
887                 pci_write_config32(dev, 0xf0, 0);
888                 d.mask -= (hole_sizek>>9);
889                 set_dram_base_mask(i, d, sysconf.nodes);
890                 if(one_DCT || (sel_m >= (hole_startk>>10))) {
891                         if(sel_hi_en & 1) {
892                                 sel_m -= hole_startk>>10;
893                                 set_DctSelBaseAddr(i, sel_m);
894                         }
895                 }
896                 if(sel_hi_en & 1) {
897                         set_DctSelBaseOffset(i, 0);
898                 }
899         }
900         else {
901                 d.base -= (hole_sizek>>9);
902                 d.mask -= (hole_sizek>>9);
903                 set_dram_base_mask(i, d, sysconf.nodes);
904
905                 if(sel_hi_en & 1) {
906                         sel_m -= hole_startk>>10;
907                         set_DctSelBaseAddr(i, sel_m);
908                 }
909         }
910
911 }
912 #endif
913
914 #endif
915
916 static void pci_domain_set_resources(device_t dev)
917 {
918 #if CONFIG_PCI_64BIT_PREF_MEM == 1
919         struct resource *io, *mem1, *mem2;
920         struct resource *resource, *last;
921 #endif
922         unsigned long mmio_basek;
923         u32 pci_tolm;
924         int i, idx;
925         u32 link;
926 #if HW_MEM_HOLE_SIZEK != 0
927         struct hw_mem_hole_info mem_hole;
928         u32 reset_memhole = 1;
929 #endif
930
931 #if CONFIG_PCI_64BIT_PREF_MEM == 1
932
933         for(link=0; link<dev->links; link++) {
934                 /* Now reallocate the pci resources memory with the
935                  * highest addresses I can manage.
936                  */
937                 mem1 = find_resource(dev, 1|(link<<2));
938                 mem2 = find_resource(dev, 2|(link<<2));
939
940                 printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
941                         mem1->base, mem1->limit, mem1->size, mem1->align);
942                 printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
943                         mem2->base, mem2->limit, mem2->size, mem2->align);
944
945                 /* See if both resources have roughly the same limits */
946                 if (((mem1->limit <= 0xffffffff) && (mem2->limit <= 0xffffffff)) ||
947                         ((mem1->limit > 0xffffffff) && (mem2->limit > 0xffffffff)))
948                 {
949                         /* If so place the one with the most stringent alignment first
950                          */
951                         if (mem2->align > mem1->align) {
952                                 struct resource *tmp;
953                                 tmp = mem1;
954                                 mem1 = mem2;
955                                 mem2 = tmp;
956                         }
957                         /* Now place the memory as high up as it will go */
958                         mem2->base = resource_max(mem2);
959                         mem1->limit = mem2->base - 1;
960                         mem1->base = resource_max(mem1);
961                 }
962                 else {
963                         /* Place the resources as high up as they will go */
964                         mem2->base = resource_max(mem2);
965                         mem1->base = resource_max(mem1);
966                 }
967
968                 printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
969                         mem1->base, mem1->limit, mem1->size, mem1->align);
970                 printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
971                         mem2->base, mem2->limit, mem2->size, mem2->align);
972         }
973
974         last = &dev->resource[dev->resources];
975         for(resource = &dev->resource[0]; resource < last; resource++)
976         {
977                 resource->flags |= IORESOURCE_ASSIGNED;
978                 resource->flags &= ~IORESOURCE_STORED;
979                 link = (resource>>2) & 3;
980                 compute_allocate_resource(&dev->link[link], resource,
981                         BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
982
983                 resource->flags |= IORESOURCE_STORED;
984                 report_resource_stored(dev, resource, "");
985
986         }
987 #endif
988
989         pci_tolm = 0xffffffffUL;
990         for(link=0;link<dev->links; link++) {
991                 pci_tolm = find_pci_tolm(&dev->link[link], pci_tolm);
992         }
993
994 #warning "FIXME handle interleaved nodes"
995         mmio_basek = pci_tolm >> 10;
996         /* Round mmio_basek to something the processor can support */
997         mmio_basek &= ~((1 << 6) -1);
998
999 #warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole"
1000         /* Round the mmio hold to 64M */
1001         mmio_basek &= ~((64*1024) - 1);
1002
1003 #if HW_MEM_HOLE_SIZEK != 0
1004 /* if the hw mem hole is already set in raminit stage, here we will compare
1005  * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
1006  * use hole_basek as mmio_basek and we don't need to reset hole.
1007  * otherwise We reset the hole to the mmio_basek
1008  */
1009
1010         mem_hole = get_hw_mem_hole_info();
1011
1012         // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
1013         if ((mem_hole.node_id !=  -1) && (mmio_basek > mem_hole.hole_startk)) {
1014                 mmio_basek = mem_hole.hole_startk;
1015                 reset_memhole = 0;
1016         }
1017
1018         #if CONFIG_AMDMCT == 0
1019         //mmio_basek = 3*1024*1024; // for debug to meet boundary
1020
1021         if(reset_memhole) {
1022                 if(mem_hole.node_id!=-1) {
1023                 /* We need to select HW_MEM_HOLE_SIZEK for raminit, it can not
1024                     make hole_startk to some basek too!
1025                    We need to reset our Mem Hole, because We want more big HOLE
1026                     than we already set
1027                    Before that We need to disable mem hole at first, becase
1028                     memhole could already be set on i+1 instead
1029                  */
1030                         disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
1031                 }
1032
1033         #if HW_MEM_HOLE_SIZE_AUTO_INC == 1
1034                 // We need to double check if the mmio_basek is valid for hole
1035                 // setting, if it is equal to basek, we need to decrease it some
1036                 resource_t basek_pri;
1037                 for (i = 0; i < sysconf.nodes; i++) {
1038                         struct dram_base_mask_t d;
1039                         resource_t basek;
1040                         d = get_dram_base_mask(i);
1041
1042                         if(!(d.mask &1)) continue;
1043
1044                         basek = ((resource_t)(d.base & 0x1fffff00)) << 9;
1045                         if(mmio_basek == (u32)basek) {
1046                                 mmio_basek -= (uin32_t)(basek - basek_pri); // increase mem hole size to make sure it is on middle of pri node
1047                                 break;
1048                         }
1049                         basek_pri = basek;
1050                 }
1051         #endif
1052         }
1053         #endif
1054
1055
1056 #endif
1057
1058         idx = 0x10;
1059         for(i = 0; i < sysconf.nodes; i++) {
1060                 struct dram_base_mask_t d;
1061                 resource_t basek, limitk, sizek; // 4 1T
1062                 d = get_dram_base_mask(i);
1063
1064                 if(!(d.mask & 1)) continue;
1065                 basek = ((resource_t)(d.base & 0x1fffff00)) << 9; // could overflow, we may lost 6 bit here
1066                 limitk = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9 ;
1067                 sizek = limitk - basek;
1068
1069                 /* see if we need a hole from 0xa0000 to 0xbffff */
1070                 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
1071                         ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
1072                         idx += 0x10;
1073                         basek = (8*64)+(16*16);
1074                         sizek = limitk - ((8*64)+(16*16));
1075
1076                 }
1077
1078 //              printk_debug("node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk);
1079
1080                 /* split the region to accomodate pci memory space */
1081                 if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) {
1082                         if (basek <= mmio_basek) {
1083                                 unsigned pre_sizek;
1084                                 pre_sizek = mmio_basek - basek;
1085                                 if(pre_sizek>0) {
1086                                         ram_resource(dev, (idx | i), basek, pre_sizek);
1087                                         idx += 0x10;
1088                                         sizek -= pre_sizek;
1089                                 }
1090                                 #if CONFIG_AMDMCT == 0
1091                                 #if HW_MEM_HOLE_SIZEK != 0
1092                                 if(reset_memhole) {
1093                                         struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
1094                                         struct mem_info *meminfo;
1095                                         meminfo = &sysinfox->meminfo[i];
1096                                         sizek += hoist_memory(mmio_basek,i, get_one_DCT(meminfo), sysconf.nodes);
1097                                 }
1098                                 #endif
1099                                 #endif
1100
1101                                 basek = mmio_basek;
1102                         }
1103                         if ((basek + sizek) <= 4*1024*1024) {
1104                                 sizek = 0;
1105                         }
1106                         else {
1107                                 basek = 4*1024*1024;
1108                                 sizek -= (4*1024*1024 - mmio_basek);
1109                         }
1110                 }
1111                 ram_resource(dev, (idx | i), basek, sizek);
1112                 idx += 0x10;
1113         }
1114
1115         for(link = 0; link < dev->links; link++) {
1116                 struct bus *bus;
1117                 bus = &dev->link[link];
1118                 if (bus->children) {
1119                         assign_resources(bus);
1120                 }
1121         }
1122 }
1123
1124 static u32 pci_domain_scan_bus(device_t dev, u32 max)
1125 {
1126         u32 reg;
1127         int i;
1128         /* Unmap all of the HT chains */
1129         for(reg = 0xe0; reg <= 0xec; reg += 4) {
1130                 f1_write_config32(reg, 0);
1131         }
1132 #if EXT_CONF_SUPPORT == 1
1133         // all nodes
1134         for(i = 0; i< sysconf.nodes; i++) {
1135                 int index;
1136                 for(index = 0; index < 64; index++) {
1137                         pci_write_config32(__f1_dev[i], 0x110, index | (6<<28));
1138                         pci_write_config32(__f1_dev[i], 0x114, 0);
1139                 }
1140
1141         }
1142 #endif
1143
1144
1145         for(i=0;i<dev->links;i++) {
1146                 max = pci_scan_bus(&dev->link[i], PCI_DEVFN(CDB, 0), 0xff, max);
1147         }
1148
1149         /* Tune the hypertransport transaction for best performance.
1150          * Including enabling relaxed ordering if it is safe.
1151          */
1152         get_fx_devs();
1153         for(i = 0; i < FX_DEVS; i++) {
1154                 device_t f0_dev;
1155                 f0_dev = __f0_dev[i];
1156                 if (f0_dev && f0_dev->enabled) {
1157                         u32 httc;
1158                         httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
1159                         httc &= ~HTTC_RSP_PASS_PW;
1160                         if (!dev->link[0].disable_relaxed_ordering) {
1161                                 httc |= HTTC_RSP_PASS_PW;
1162                         }
1163                         printk_spew("%s passpw: %s\n",
1164                                 dev_path(dev),
1165                                 (!dev->link[0].disable_relaxed_ordering)?
1166                                 "enabled":"disabled");
1167                         pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
1168                 }
1169         }
1170         return max;
1171 }
1172
1173 static struct device_operations pci_domain_ops = {
1174         .read_resources   = pci_domain_read_resources,
1175         .set_resources    = pci_domain_set_resources,
1176         .enable_resources = enable_childrens_resources,
1177         .init             = 0,
1178         .scan_bus         = pci_domain_scan_bus,
1179 #if MMCONF_SUPPORT
1180         .ops_pci_bus      = &pci_ops_mmconf,
1181 #else
1182         .ops_pci_bus      = &pci_cf8_conf1,
1183 #endif
1184 };
1185
1186 static void sysconf_init(device_t dev) // first node
1187 {
1188         sysconf.sblk = (pci_read_config32(dev, 0x64)>>8) & 7; // don't forget sublink1
1189         sysconf.segbit = 0;
1190         sysconf.ht_c_num = 0;
1191
1192         unsigned ht_c_index;
1193
1194         for(ht_c_index=0; ht_c_index<32; ht_c_index++) {
1195                 sysconf.ht_c_conf_bus[ht_c_index] = 0;
1196         }
1197
1198         sysconf.nodes = ((pci_read_config32(dev, 0x60)>>4) & 7) + 1;
1199 #if CONFIG_MAX_PHYSICAL_CPUS > 8
1200         sysconf.nodes += (((pci_read_config32(dev, 0x160)>>4) & 7)<<3);
1201 #endif
1202
1203         sysconf.enabled_apic_ext_id = 0;
1204         sysconf.lift_bsp_apicid = 0;
1205
1206         /* Find the bootstrap processors apicid */
1207         sysconf.bsp_apicid = lapicid();
1208         sysconf.apicid_offset = sysconf.bsp_apicid;
1209
1210 #if (ENABLE_APIC_EXT_ID == 1)
1211         if (pci_read_config32(dev, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
1212         {
1213                 sysconf.enabled_apic_ext_id = 1;
1214         }
1215         #if (APIC_ID_OFFSET>0)
1216         if(sysconf.enabled_apic_ext_id) {
1217                 if(sysconf.bsp_apicid == 0) {
1218                         /* bsp apic id is not changed */
1219                         sysconf.apicid_offset = APIC_ID_OFFSET;
1220                 } else {
1221                         sysconf.lift_bsp_apicid = 1;
1222                 }
1223
1224         }
1225         #endif
1226 #endif
1227
1228 }
1229
1230 static u32 cpu_bus_scan(device_t dev, u32 max)
1231 {
1232         struct bus *cpu_bus;
1233         device_t dev_mc;
1234         device_t pci_domain;
1235         int i,j;
1236         int nodes;
1237         unsigned nb_cfg_54;
1238         unsigned siblings;
1239         int cores_found;
1240         int disable_siblings;
1241         unsigned ApicIdCoreIdSize;
1242
1243         nb_cfg_54 = 0;
1244         ApicIdCoreIdSize = (cpuid_ecx(0x80000008)>>12 & 0xf);
1245         if(ApicIdCoreIdSize) {
1246                 siblings = (1<<ApicIdCoreIdSize)-1;
1247         } else {
1248                 siblings = 3; //quad core
1249         }
1250
1251         disable_siblings = !CONFIG_LOGICAL_CPUS;
1252 #if CONFIG_LOGICAL_CPUS == 1
1253         get_option(&disable_siblings, "quad_core");
1254 #endif
1255
1256         // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it
1257         //    still be 0)
1258         // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp???
1259         //    and differ d0 and e0 single core
1260
1261         nb_cfg_54 = read_nb_cfg_54();
1262
1263 #if CBB
1264         dev_mc = dev_find_slot(0, PCI_DEVFN(CDB, 0)); //0x00
1265         if(dev_mc && dev_mc->bus) {
1266                 printk_debug("%s found", dev_path(dev_mc));
1267                 pci_domain = dev_mc->bus->dev;
1268                 if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1269                         printk_debug("\n%s move to ",dev_path(dev_mc));
1270                         dev_mc->bus->secondary = CBB; // move to 0xff
1271                         printk_debug("%s",dev_path(dev_mc));
1272
1273                 } else {
1274                         printk_debug(" but it is not under pci_domain directly ");
1275                 }
1276                 printk_debug("\n");
1277
1278         }
1279         dev_mc = dev_find_slot(CBB, PCI_DEVFN(CDB, 0));
1280         if(!dev_mc) {
1281                 dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
1282                 if (dev_mc && dev_mc->bus) {
1283                         printk_debug("%s found\n", dev_path(dev_mc));
1284                         pci_domain = dev_mc->bus->dev;
1285                         if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1286                                 if((pci_domain->links==1) && (pci_domain->link[0].children == dev_mc)) {
1287                                         printk_debug("%s move to ",dev_path(dev_mc));
1288                                         dev_mc->bus->secondary = CBB; // move to 0xff
1289                                         printk_debug("%s\n",dev_path(dev_mc));
1290                                         while(dev_mc){
1291                                                 printk_debug("%s move to ",dev_path(dev_mc));
1292                                                 dev_mc->path.u.pci.devfn -= PCI_DEVFN(0x18,0);
1293                                                 printk_debug("%s\n",dev_path(dev_mc));
1294                                                 dev_mc = dev_mc->sibling;
1295                                         }
1296                                 }
1297                         }
1298                 }
1299         }
1300
1301 #endif
1302
1303         dev_mc = dev_find_slot(CBB, PCI_DEVFN(CDB, 0));
1304         if (!dev_mc) {
1305                 printk_err("%02x:%02x.0 not found", CBB, CDB);
1306                 die("");
1307         }
1308
1309         sysconf_init(dev_mc);
1310
1311         nodes = sysconf.nodes;
1312
1313 #if CBB && (NODE_NUMS > 32)
1314         if(nodes>32) { // need to put node 32 to node 63 to bus 0xfe
1315                 if(pci_domain->links==1) {
1316                         pci_domain->links++; // from 1 to 2
1317                         pci_domain->link[1].link = 1;
1318                         pci_domain->link[1].dev = pci_domain;
1319                         pci_domain->link[1].children = 0;
1320                         printk_debug("%s links increase to %d\n", dev_path(pci_domain), pci_domain->links);
1321                 }
1322                 pci_domain->link[1].secondary = CBB - 1;
1323         }
1324 #endif
1325         /* Find which cpus are present */
1326         cpu_bus = &dev->link[0];
1327         for(i = 0; i < nodes; i++) {
1328                 device_t dev, cpu;
1329                 struct device_path cpu_path;
1330                 unsigned busn, devn;
1331                 struct bus *pbus;
1332
1333                 busn = CBB;
1334                 devn = CDB+i;
1335                 pbus = dev_mc->bus;
1336 #if CBB && (NODE_NUMS > 32)
1337                 if(i>=32) {
1338                         busn--;
1339                         devn-=32;
1340                         pbus = &(pci_domain->link[1]);
1341                 }
1342 #endif
1343
1344                 /* Find the cpu's pci device */
1345                 dev = dev_find_slot(busn, PCI_DEVFN(devn, 0));
1346                 if (!dev) {
1347                         /* If I am probing things in a weird order
1348                          * ensure all of the cpu's pci devices are found.
1349                          */
1350                         int j;
1351                         for(j = 0; j <= 5; j++) { //FBDIMM?
1352                                 dev = pci_probe_dev(NULL, pbus,
1353                                         PCI_DEVFN(devn, j));
1354                         }
1355                         dev = dev_find_slot(busn, PCI_DEVFN(devn,0));
1356                 }
1357                 if(dev) {
1358                         /* Ok, We need to set the links for that device.
1359                          * otherwise the device under it will not be scanned
1360                          */
1361                         int j;
1362                         int linknum;
1363 #if HT3_SUPPORT==1
1364                         linknum = 8;
1365 #else
1366                         linknum = 4;
1367 #endif
1368                         if(dev->links < linknum) {
1369                                 for(j=dev->links; j<linknum; j++) {
1370                                          dev->link[j].link = j;
1371                                          dev->link[j].dev = dev;
1372                                 }
1373                                 dev->links = linknum;
1374                                 printk_debug("%s links increase to %d\n", dev_path(dev), dev->links);
1375                         }
1376                 }
1377
1378                 cores_found = 0; // one core
1379                 dev = dev_find_slot(busn, PCI_DEVFN(devn, 3));
1380                 if (dev && dev->enabled) {
1381                         j = pci_read_config32(dev, 0xe8);
1382                         cores_found = (j >> 12) & 3; // dev is func 3
1383                         printk_debug("  %s siblings=%d\n", dev_path(dev), cores_found);
1384                 }
1385
1386                 u32 jj;
1387                 if(disable_siblings) {
1388                         jj = 0;
1389                 } else
1390                 {
1391                         jj = cores_found;
1392                 }
1393
1394                 for (j = 0; j <=jj; j++ ) {
1395
1396                         /* Build the cpu device path */
1397                         cpu_path.type = DEVICE_PATH_APIC;
1398                         cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ?
1399
1400                         /* See if I can find the cpu */
1401                         cpu = find_dev_path(cpu_bus, &cpu_path);
1402
1403                         /* Enable the cpu if I have the processor */
1404                         if (dev && dev->enabled) {
1405                                 if (!cpu) {
1406                                         cpu = alloc_dev(cpu_bus, &cpu_path);
1407                                 }
1408                                 if (cpu) {
1409                                         cpu->enabled = 1;
1410                                 }
1411                         }
1412
1413                         /* Disable the cpu if I don't have the processor */
1414                         if (cpu && (!dev || !dev->enabled)) {
1415                                 cpu->enabled = 0;
1416                         }
1417
1418                         /* Report what I have done */
1419                         if (cpu) {
1420                                 cpu->path.u.apic.node_id = i;
1421                                 cpu->path.u.apic.core_id = j;
1422         #if (ENABLE_APIC_EXT_ID == 1) && (APIC_ID_OFFSET>0)
1423                                  if(sysconf.enabled_apic_ext_id) {
1424                                         if(sysconf.lift_bsp_apicid) {
1425                                                 cpu->path.u.apic.apic_id += sysconf.apicid_offset;
1426                                         } else
1427                                         {
1428                                                 if (cpu->path.u.apic.apic_id != 0)
1429                                                         cpu->path.u.apic.apic_id += sysconf.apicid_offset;
1430                                          }
1431                                 }
1432         #endif
1433                                 printk_debug("CPU: %s %s\n",
1434                                         dev_path(cpu), cpu->enabled?"enabled":"disabled");
1435                         }
1436
1437                 } //j
1438         }
1439         return max;
1440 }
1441
1442
1443 static void cpu_bus_init(device_t dev)
1444 {
1445         initialize_cpus(&dev->link[0]);
1446 }
1447
1448
1449 static void cpu_bus_noop(device_t dev)
1450 {
1451 }
1452
1453
1454 static struct device_operations cpu_bus_ops = {
1455         .read_resources   = cpu_bus_noop,
1456         .set_resources    = cpu_bus_noop,
1457         .enable_resources = cpu_bus_noop,
1458         .init             = cpu_bus_init,
1459         .scan_bus         = cpu_bus_scan,
1460 };
1461
1462
1463 static void root_complex_enable_dev(struct device *dev)
1464 {
1465         /* Set the operations if it is a special bus type */
1466         if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
1467                 dev->ops = &pci_domain_ops;
1468         }
1469         else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
1470                 dev->ops = &cpu_bus_ops;
1471         }
1472 }
1473
1474 struct chip_operations northbridge_amd_amdfam10_root_complex_ops = {
1475         CHIP_NAME("AMD FAM10 Root Complex")
1476         .enable_dev = root_complex_enable_dev,
1477 };