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