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