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