2 * This file is part of the coreboot project.
4 * Copyright (C) 2007 Advanced Micro Devices, Inc.
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.
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.
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
20 #include <console/console.h>
23 #include <device/device.h>
24 #include <device/pci.h>
25 #include <device/pci_ids.h>
26 #include <device/hypertransport.h>
32 #include <cpu/x86/lapic.h>
34 #if CONFIG_LOGICAL_CPUS==1
35 #include <cpu/amd/multicore.h>
36 #include <pc80/mc146818rtc.h>
40 #include "root_complex/chip.h"
41 #include "northbridge.h"
45 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
46 #include <cpu/amd/model_10xxx_rev.h>
49 #include <cpu/amd/amdfam10_sysconf.h>
51 struct amdfam10_sysconf_t sysconf;
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];
59 device_t get_node_pci(u32 nodeid, u32 fn)
63 return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn));
65 return dev_find_slot(CONFIG_CBB-1, PCI_DEVFN(CONFIG_CDB + nodeid - 32, fn));
69 return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn));
73 static void get_fx_devs(void)
79 for(i = 0; i < FX_DEVS; i++) {
80 __f0_dev[i] = get_node_pci(i, 0);
81 __f1_dev[i] = get_node_pci(i, 1);
82 __f2_dev[i] = get_node_pci(i, 2);
83 __f4_dev[i] = get_node_pci(i, 4);
86 printk(BIOS_ERR, "Cannot find %02x:%02x.1", CONFIG_CBB, CONFIG_CDB);
87 die("Cannot go on\n");
91 static u32 f1_read_config32(u32 reg)
94 return pci_read_config32(__f1_dev[0], reg);
97 static void f1_write_config32(u32 reg, u32 value)
101 for(i = 0; i < FX_DEVS; i++) {
104 if (dev && dev->enabled) {
105 pci_write_config32(dev, reg, value);
111 static u32 amdfam10_nodeid(device_t dev)
115 busn = dev->bus->secondary;
116 if(busn != CONFIG_CBB) {
117 return (dev->path.pci.devfn >> 3) - CONFIG_CDB + 32;
119 return (dev->path.pci.devfn >> 3) - CONFIG_CDB;
123 return (dev->path.pci.devfn >> 3) - CONFIG_CDB;
127 #include "amdfam10_conf.c"
129 static void set_vga_enable_reg(u32 nodeid, u32 linkn)
133 val = 1 | (nodeid<<4) | (linkn<<12);
134 /* it will routing (1)mmio 0xa0000:0xbffff (2) io 0x3b0:0x3bb,
136 f1_write_config32(0xf4, val);
140 static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink,
141 u32 max, u32 offset_unitid)
143 // I want to put sb chain in bus 0 can I?
149 u32 ht_unitid_base[4]; // here assume only 4 HT device on chain
152 u32 is_sublink1 = (link>3);
156 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1
161 #if CONFIG_HT3_SUPPORT==1
165 regpos = 0x170 + 4 * (link&3); // it is only on sublink0
166 reg = pci_read_config32(dev, regpos);
167 if(reg & 1) return max; // already ganged no sblink1
168 devx = get_node_pci(nodeid, 4);
174 dev->link[link].cap = 0x80 + ((link&3) *0x20);
176 link_type = pci_read_config32(devx, dev->link[link].cap + 0x18);
177 } while(link_type & ConnectionPending);
178 if (!(link_type & LinkConnected)) {
182 link_type = pci_read_config32(devx, dev->link[link].cap + 0x18);
183 } while(!(link_type & InitComplete));
184 if (!(link_type & NonCoherent)) {
187 /* See if there is an available configuration space mapping
188 * register in function 1.
190 ht_c_index = get_ht_c_index(nodeid, link, &sysconf);
192 #if CONFIG_EXT_CONF_SUPPORT == 0
193 if(ht_c_index>=4) return max;
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.
201 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
202 // first chain will on bus 0
203 if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
206 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1
207 // second chain will be on 0x40, third 0x80, forth 0xc0
208 // i would refined that to 2, 3, 4 ==> 0, 0x, 40, 0x80, 0xc0
209 // >4 will use more segments, We can have 16 segmment and every segment have 256 bus, For that case need the kernel support mmio pci config.
211 min_bus = ((busn>>3) + 1) << 3; // one node can have 8 link and segn is the same
213 max = min_bus | (segn<<8);
223 max_bus = 0xfc | (segn<<8);
225 dev->link[link].secondary = min_bus;
226 dev->link[link].subordinate = max_bus;
227 /* Read the existing primary/secondary/subordinate bus
228 * number configuration.
230 busses = pci_read_config32(devx, dev->link[link].cap + 0x14);
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
236 busses &= 0xffff00ff;
237 busses |= ((u32)(dev->link[link].secondary) << 8);
238 pci_write_config32(devx, dev->link[link].cap + 0x14, busses);
241 /* set the config map space */
243 set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes);
245 /* Now we can scan all of the subordinate busses i.e. the
246 * chain on the hypertranport link
249 ht_unitid_base[i] = 0x20;
252 //if ext conf is enabled, only need use 0x1f
254 max_devfn = (0x17<<3) | 7;
256 max_devfn = (0x1f<<3) | 7;
258 max = hypertransport_scan_chain(&dev->link[link], 0, max_devfn, max, ht_unitid_base, offset_unitid);
261 /* We know the number of busses behind this bridge. Set the
262 * subordinate bus number to it's real value
264 if(ht_c_index>3) { // clear the extend reg
265 clear_config_map_reg(nodeid, link, ht_c_index, (max+1)>>sysconf.segbit, (dev->link[link].subordinate)>>sysconf.segbit, sysconf.nodes);
268 dev->link[link].subordinate = max;
269 set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes);
273 // config config_reg, and ht_unitid_base to update hcdn_reg;
276 temp |= (ht_unitid_base[i] & 0xff) << (i*8);
279 sysconf.hcdn_reg[ht_c_index] = temp;
283 store_ht_c_conf_bus(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, &sysconf);
289 static u32 amdfam10_scan_chains(device_t dev, u32 max)
293 u32 sblink = sysconf.sblk;
294 u32 offset_unitid = 0;
296 nodeid = amdfam10_nodeid(dev);
299 // Put sb chain in bus 0
300 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
302 #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
305 max = amdfam10_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
310 #if CONFIG_PCI_BUS_SEGN_BITS
311 max = check_segn(dev, max, sysconf.nodes, &sysconf);
315 for(link = 0; link < dev->links; link++) {
316 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
317 if( (nodeid == 0) && (sblink == link) ) continue; //already done
320 #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
321 #if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
322 if((nodeid == 0) && (sblink == link))
327 max = amdfam10_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
333 static int reg_useable(u32 reg,device_t goal_dev, u32 goal_nodeid,
336 struct resource *res;
337 u32 nodeid, link = 0;
340 for(nodeid = 0; !res && (nodeid < NODE_NUMS); nodeid++) {
342 dev = __f0_dev[nodeid];
345 for(link = 0; !res && (link < 8); link++) {
346 res = probe_resource(dev, IOINDEX(0x1000 + reg, link));
352 if ( (goal_link == (link - 1)) &&
353 (goal_nodeid == (nodeid - 1)) &&
361 static struct resource *amdfam10_find_iopair(device_t dev, u32 nodeid, u32 link)
363 struct resource *resource;
367 for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
369 result = reg_useable(reg, dev, nodeid, link);
371 /* I have been allocated this one */
374 else if (result > 1) {
375 /* I have a free register pair */
380 reg = free_reg; // if no free, the free_reg still be 0
385 //because of Extend conf space, we will never run out of reg, but we need one index to differ them. so same node and same link can have multi range
386 u32 index = get_io_addr_index(nodeid, link);
387 reg = 0x110+ (index<<24) + (4<<20); // index could be 0, 255
390 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
395 static struct resource *amdfam10_find_mempair(device_t dev, u32 nodeid, u32 link)
397 struct resource *resource;
401 for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
403 result = reg_useable(reg, dev, nodeid, link);
405 /* I have been allocated this one */
408 else if (result > 1) {
409 /* I have a free register pair */
419 //because of Extend conf space, we will never run out of reg,
420 // but we need one index to differ them. so same node and
421 // same link can have multi range
422 u32 index = get_mmio_addr_index(nodeid, link);
423 reg = 0x110+ (index<<24) + (6<<20); // index could be 0, 63
426 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
431 static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link)
433 struct resource *resource;
435 /* Initialize the io space constraints on the current bus */
436 resource = amdfam10_find_iopair(dev, nodeid, link);
439 #if CONFIG_EXT_CONF_SUPPORT == 1
440 if((resource->index & 0x1fff) == 0x1110) { // ext
445 align = log2(HT_IO_HOST_ALIGN);
448 resource->align = align;
449 resource->gran = align;
450 resource->limit = 0xffffUL;
451 resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE;
454 /* Initialize the prefetchable memory constraints on the current bus */
455 resource = amdfam10_find_mempair(dev, nodeid, link);
459 resource->align = log2(HT_MEM_HOST_ALIGN);
460 resource->gran = log2(HT_MEM_HOST_ALIGN);
461 resource->limit = 0xffffffffffULL;
462 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_BRIDGE;
464 #if CONFIG_EXT_CONF_SUPPORT == 1
465 if((resource->index & 0x1fff) == 0x1110) { // ext
466 normalize_resource(resource);
472 /* Initialize the memory constraints on the current bus */
473 resource = amdfam10_find_mempair(dev, nodeid, link);
477 resource->align = log2(HT_MEM_HOST_ALIGN);
478 resource->gran = log2(HT_MEM_HOST_ALIGN);
479 resource->limit = 0xffffffffffULL;
480 resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE;
482 #if CONFIG_EXT_CONF_SUPPORT == 1
483 if((resource->index & 0x1fff) == 0x1110) { // ext
484 normalize_resource(resource);
492 static void amdfam10_read_resources(device_t dev)
496 nodeid = amdfam10_nodeid(dev);
497 for(link = 0; link < dev->links; link++) {
498 if (dev->link[link].children) {
499 amdfam10_link_read_bases(dev, nodeid, link);
505 static void amdfam10_set_resource(device_t dev, struct resource *resource,
508 resource_t rbase, rend;
512 /* Make certain the resource has actually been set */
513 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
517 /* If I have already stored this resource don't worry about it */
518 if (resource->flags & IORESOURCE_STORED) {
522 /* Only handle PCI memory and IO resources */
523 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
526 /* Ensure I am actually looking at a resource of function 1 */
527 if ((resource->index & 0xffff) < 0x1000) {
530 /* Get the base address */
531 rbase = resource->base;
533 /* Get the limit (rounded up) */
534 rend = resource_end(resource);
536 /* Get the register and link */
537 reg = resource->index & 0xfff; // 4k
538 link = IOINDEX_LINK(resource->index);
540 if (resource->flags & IORESOURCE_IO) {
542 set_io_addr_reg(dev, nodeid, link, reg, rbase>>8, rend>>8);
543 store_conf_io_addr(nodeid, link, reg, (resource->index >> 24), rbase>>8, rend>>8);
545 else if (resource->flags & IORESOURCE_MEM) {
546 set_mmio_addr_reg(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
547 store_conf_mmio_addr(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8);
549 resource->flags |= IORESOURCE_STORED;
550 sprintf(buf, " <node %02x link %02x>",
552 report_resource_stored(dev, resource, buf);
557 * I tried to reuse the resource allocation code in amdfam10_set_resource()
558 * but it is too diffcult to deal with the resource allocation magic.
560 #if CONFIG_CONSOLE_VGA_MULTI == 1
561 extern device_t vga_pri; // the primary vga device, defined in device.c
564 static void amdfam10_create_vga_resource(device_t dev, unsigned nodeid)
568 /* find out which link the VGA card is connected,
569 * we only deal with the 'first' vga card */
570 for (link = 0; link < dev->links; link++) {
571 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
572 #if CONFIG_CONSOLE_VGA_MULTI == 1
573 printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
574 dev->link[link].secondary,dev->link[link].subordinate);
575 /* We need to make sure the vga_pri is under the link */
576 if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
577 (vga_pri->bus->secondary <= dev->link[link].subordinate )
584 /* no VGA card installed */
585 if (link == dev->links)
588 printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
589 set_vga_enable_reg(nodeid, link);
592 static void amdfam10_set_resources(device_t dev)
597 /* Find the nodeid */
598 nodeid = amdfam10_nodeid(dev);
600 amdfam10_create_vga_resource(dev, nodeid);
602 /* Set each resource we have found */
603 for(i = 0; i < dev->resources; i++) {
604 amdfam10_set_resource(dev, &dev->resource[i], nodeid);
607 for(link = 0; link < dev->links; link++) {
609 bus = &dev->link[link];
611 assign_resources(bus);
617 static void amdfam10_enable_resources(device_t dev)
619 pci_dev_enable_resources(dev);
620 enable_childrens_resources(dev);
623 static void mcf0_control_init(struct device *dev)
627 static struct device_operations northbridge_operations = {
628 .read_resources = amdfam10_read_resources,
629 .set_resources = amdfam10_set_resources,
630 .enable_resources = amdfam10_enable_resources,
631 .init = mcf0_control_init,
632 .scan_bus = amdfam10_scan_chains,
638 static const struct pci_driver mcf0_driver __pci_driver = {
639 .ops = &northbridge_operations,
640 .vendor = PCI_VENDOR_ID_AMD,
644 struct chip_operations northbridge_amd_amdfam10_ops = {
645 CHIP_NAME("AMD FAM10 Northbridge")
649 static void amdfam10_domain_read_resources(device_t dev)
653 /* Find the already assigned resource pairs */
655 for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
657 base = f1_read_config32(reg);
658 limit = f1_read_config32(reg + 0x04);
659 /* Is this register allocated? */
660 if ((base & 3) != 0) {
661 unsigned nodeid, reg_link;
663 if(reg<0xc0) { // mmio
664 nodeid = (limit & 0xf) + (base&0x30);
666 nodeid = (limit & 0xf) + ((base>>4)&0x30);
668 reg_link = (limit >> 4) & 7;
669 reg_dev = __f0_dev[nodeid];
671 /* Reserve the resource */
672 struct resource *reg_resource;
673 reg_resource = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
675 reg_resource->flags = 1;
680 /* FIXME: do we need to check extend conf space?
681 I don't believe that much preset value */
683 #if CONFIG_PCI_64BIT_PREF_MEM == 0
684 pci_domain_read_resources(dev);
687 struct resource *resource;
688 for(link=0; link<dev->links; link++) {
689 /* Initialize the system wide io space constraints */
690 resource = new_resource(dev, 0|(link<<2));
691 resource->base = 0x400;
692 resource->limit = 0xffffUL;
693 resource->flags = IORESOURCE_IO;
695 /* Initialize the system wide prefetchable memory resources constraints */
696 resource = new_resource(dev, 1|(link<<2));
697 resource->limit = 0xfcffffffffULL;
698 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
700 /* Initialize the system wide memory resources constraints */
701 resource = new_resource(dev, 2|(link<<2));
702 resource->limit = 0xfcffffffffULL;
703 resource->flags = IORESOURCE_MEM;
708 static void ram_resource(device_t dev, unsigned long index,
709 resource_t basek, resource_t sizek)
711 struct resource *resource;
716 resource = new_resource(dev, index);
717 resource->base = basek << 10;
718 resource->size = sizek << 10;
719 resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
720 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
723 static void tolm_test(void *gp, struct device *dev, struct resource *new)
725 struct resource **best_p = gp;
726 struct resource *best;
728 if (!best || (best->base > new->base)) {
734 static u32 find_pci_tolm(struct bus *bus, u32 tolm)
736 struct resource *min;
738 search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
739 if (min && tolm > min->base) {
745 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
747 struct hw_mem_hole_info {
748 unsigned hole_startk;
752 static struct hw_mem_hole_info get_hw_mem_hole_info(void)
754 struct hw_mem_hole_info mem_hole;
757 mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
758 mem_hole.node_id = -1;
760 for (i = 0; i < sysconf.nodes; i++) {
761 struct dram_base_mask_t d;
763 d = get_dram_base_mask(i);
764 if(!(d.mask & 1)) continue; // no memory on this node
766 hole = pci_read_config32(__f1_dev[i], 0xf0);
767 if(hole & 1) { // we find the hole
768 mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
769 mem_hole.node_id = i; // record the node No with hole
770 break; // only one hole
774 //We need to double check if there is speical set on base reg and limit reg are not continous instead of hole, it will find out it's hole_startk
775 if(mem_hole.node_id==-1) {
776 resource_t limitk_pri = 0;
777 for(i=0; i<sysconf.nodes; i++) {
778 struct dram_base_mask_t d;
779 resource_t base_k, limit_k;
780 d = get_dram_base_mask(i);
781 if(!(d.base & 1)) continue;
783 base_k = ((resource_t)(d.base & 0x1fffff00)) <<9;
784 if(base_k > 4 *1024 * 1024) break; // don't need to go to check
785 if(limitk_pri != base_k) { // we find the hole
786 mem_hole.hole_startk = (unsigned)limitk_pri; // must beblow 4G
787 mem_hole.node_id = i;
788 break; //only one hole
791 limit_k = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9;
792 limitk_pri = limit_k;
798 // WHY this check? CONFIG_AMDMCT is enabled on all Fam10 boards.
799 // Does it make sense not to?
800 #if CONFIG_AMDMCT == 0
801 static void disable_hoist_memory(unsigned long hole_startk, int i)
805 struct dram_base_mask_t d;
812 struct sys_info *sysinfox = (struct sys_info *)((CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
813 struct mem_info *meminfo;
814 meminfo = &sysinfox->meminfo[i];
816 one_DCT = get_one_DCT(meminfo);
818 // 1. find which node has hole
819 // 2. change limit in that node.
820 // 3. change base and limit in later node
821 // 4. clear that node f0
823 // if there is not mem hole enabled, we need to change it's base instead
825 hole_sizek = (4*1024*1024) - hole_startk;
827 for(ii=NODE_NUMS-1;ii>i;ii--) {
829 d = get_dram_base_mask(ii);
831 if(!(d.mask & 1)) continue;
833 d.base -= (hole_sizek>>9);
834 d.mask -= (hole_sizek>>9);
835 set_dram_base_mask(ii, d, sysconf.nodes);
837 if(get_DctSelHiEn(ii) & 1) {
838 sel_m = get_DctSelBaseAddr(ii);
839 sel_m -= hole_startk>>10;
840 set_DctSelBaseAddr(ii, sel_m);
844 d = get_dram_base_mask(i);
846 hoist = pci_read_config32(dev, 0xf0);
847 sel_hi_en = get_DctSelHiEn(i);
850 sel_m = get_DctSelBaseAddr(i);
854 pci_write_config32(dev, 0xf0, 0);
855 d.mask -= (hole_sizek>>9);
856 set_dram_base_mask(i, d, sysconf.nodes);
857 if(one_DCT || (sel_m >= (hole_startk>>10))) {
859 sel_m -= hole_startk>>10;
860 set_DctSelBaseAddr(i, sel_m);
864 set_DctSelBaseOffset(i, 0);
868 d.base -= (hole_sizek>>9);
869 d.mask -= (hole_sizek>>9);
870 set_dram_base_mask(i, d, sysconf.nodes);
873 sel_m -= hole_startk>>10;
874 set_DctSelBaseAddr(i, sel_m);
883 #if CONFIG_WRITE_HIGH_TABLES==1
884 #define HIGH_TABLES_SIZE 64 // maximum size of high tables in KB
885 extern uint64_t high_tables_base, high_tables_size;
888 static void pci_domain_set_resources(device_t dev)
890 #if CONFIG_PCI_64BIT_PREF_MEM == 1
891 struct resource *io, *mem1, *mem2;
892 struct resource *resource, *last;
894 unsigned long mmio_basek;
898 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
899 struct hw_mem_hole_info mem_hole;
900 u32 reset_memhole = 1;
903 #if CONFIG_PCI_64BIT_PREF_MEM == 1
905 for(link=0; link<dev->links; link++) {
906 /* Now reallocate the pci resources memory with the
907 * highest addresses I can manage.
909 mem1 = find_resource(dev, 1|(link<<2));
910 mem2 = find_resource(dev, 2|(link<<2));
912 printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
913 mem1->base, mem1->limit, mem1->size, mem1->align);
914 printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
915 mem2->base, mem2->limit, mem2->size, mem2->align);
917 /* See if both resources have roughly the same limits */
918 if (((mem1->limit <= 0xffffffff) && (mem2->limit <= 0xffffffff)) ||
919 ((mem1->limit > 0xffffffff) && (mem2->limit > 0xffffffff)))
921 /* If so place the one with the most stringent alignment first
923 if (mem2->align > mem1->align) {
924 struct resource *tmp;
929 /* Now place the memory as high up as it will go */
930 mem2->base = resource_max(mem2);
931 mem1->limit = mem2->base - 1;
932 mem1->base = resource_max(mem1);
935 /* Place the resources as high up as they will go */
936 mem2->base = resource_max(mem2);
937 mem1->base = resource_max(mem1);
940 printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
941 mem1->base, mem1->limit, mem1->size, mem1->align);
942 printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
943 mem2->base, mem2->limit, mem2->size, mem2->align);
946 last = &dev->resource[dev->resources];
947 for(resource = &dev->resource[0]; resource < last; resource++)
949 resource->flags |= IORESOURCE_ASSIGNED;
950 resource->flags &= ~IORESOURCE_STORED;
951 link = (resource>>2) & 3;
952 resource->flags |= IORESOURCE_STORED;
953 report_resource_stored(dev, resource, "");
958 pci_tolm = 0xffffffffUL;
959 for(link=0;link<dev->links; link++) {
960 pci_tolm = find_pci_tolm(&dev->link[link], pci_tolm);
963 // FIXME handle interleaved nodes. If you fix this here, please fix
965 mmio_basek = pci_tolm >> 10;
966 /* Round mmio_basek to something the processor can support */
967 mmio_basek &= ~((1 << 6) -1);
969 // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
970 // MMIO hole. If you fix this here, please fix amdk8, too.
971 /* Round the mmio hold to 64M */
972 mmio_basek &= ~((64*1024) - 1);
974 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
975 /* if the hw mem hole is already set in raminit stage, here we will compare
976 * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
977 * use hole_basek as mmio_basek and we don't need to reset hole.
978 * otherwise We reset the hole to the mmio_basek
981 mem_hole = get_hw_mem_hole_info();
983 // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
984 if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) {
985 mmio_basek = mem_hole.hole_startk;
989 #if CONFIG_AMDMCT == 0
990 //mmio_basek = 3*1024*1024; // for debug to meet boundary
993 if(mem_hole.node_id!=-1) {
994 /* We need to select CONFIG_HW_MEM_HOLE_SIZEK for raminit, it can not
995 make hole_startk to some basek too!
996 We need to reset our Mem Hole, because We want more big HOLE
998 Before that We need to disable mem hole at first, becase
999 memhole could already be set on i+1 instead
1001 disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
1004 #if CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC == 1
1005 // We need to double check if the mmio_basek is valid for hole
1006 // setting, if it is equal to basek, we need to decrease it some
1007 resource_t basek_pri;
1008 for (i = 0; i < sysconf.nodes; i++) {
1009 struct dram_base_mask_t d;
1011 d = get_dram_base_mask(i);
1013 if(!(d.mask &1)) continue;
1015 basek = ((resource_t)(d.base & 0x1fffff00)) << 9;
1016 if(mmio_basek == (u32)basek) {
1017 mmio_basek -= (uin32_t)(basek - basek_pri); // increase mem hole size to make sure it is on middle of pri node
1030 for(i = 0; i < sysconf.nodes; i++) {
1031 struct dram_base_mask_t d;
1032 resource_t basek, limitk, sizek; // 4 1T
1033 d = get_dram_base_mask(i);
1035 if(!(d.mask & 1)) continue;
1036 basek = ((resource_t)(d.base & 0x1fffff00)) << 9; // could overflow, we may lost 6 bit here
1037 limitk = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9 ;
1038 sizek = limitk - basek;
1040 /* see if we need a hole from 0xa0000 to 0xbffff */
1041 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
1042 ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
1044 basek = (8*64)+(16*16);
1045 sizek = limitk - ((8*64)+(16*16));
1049 // printk(BIOS_DEBUG, "node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk);
1051 /* split the region to accomodate pci memory space */
1052 if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) {
1053 if (basek <= mmio_basek) {
1055 pre_sizek = mmio_basek - basek;
1057 ram_resource(dev, (idx | i), basek, pre_sizek);
1060 #if CONFIG_WRITE_HIGH_TABLES==1
1061 if (i==0 && high_tables_base==0) {
1062 /* Leave some space for ACPI, PIRQ and MP tables */
1063 high_tables_base = (mmio_basek - HIGH_TABLES_SIZE) * 1024;
1064 high_tables_size = HIGH_TABLES_SIZE * 1024;
1065 printk(BIOS_DEBUG, "(split)%xK table at =%08llx\n", HIGH_TABLES_SIZE,
1070 #if CONFIG_AMDMCT == 0
1071 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
1073 struct sys_info *sysinfox = (struct sys_info *)((CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
1074 struct mem_info *meminfo;
1075 meminfo = &sysinfox->meminfo[i];
1076 sizek += hoist_memory(mmio_basek,i, get_one_DCT(meminfo), sysconf.nodes);
1083 if ((basek + sizek) <= 4*1024*1024) {
1087 basek = 4*1024*1024;
1088 sizek -= (4*1024*1024 - mmio_basek);
1091 ram_resource(dev, (idx | i), basek, sizek);
1093 #if CONFIG_WRITE_HIGH_TABLES==1
1094 printk(BIOS_DEBUG, "%d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
1095 i, mmio_basek, basek, limitk);
1096 if (i==0 && high_tables_base==0) {
1097 /* Leave some space for ACPI, PIRQ and MP tables */
1098 high_tables_base = (limitk - HIGH_TABLES_SIZE) * 1024;
1099 high_tables_size = HIGH_TABLES_SIZE * 1024;
1104 for(link = 0; link < dev->links; link++) {
1106 bus = &dev->link[link];
1107 if (bus->children) {
1108 assign_resources(bus);
1113 static u32 amdfam10_domain_scan_bus(device_t dev, u32 max)
1117 /* Unmap all of the HT chains */
1118 for(reg = 0xe0; reg <= 0xec; reg += 4) {
1119 f1_write_config32(reg, 0);
1121 #if CONFIG_EXT_CONF_SUPPORT == 1
1123 for(i = 0; i< sysconf.nodes; i++) {
1125 for(index = 0; index < 64; index++) {
1126 pci_write_config32(__f1_dev[i], 0x110, index | (6<<28));
1127 pci_write_config32(__f1_dev[i], 0x114, 0);
1134 for(i=0;i<dev->links;i++) {
1135 max = pci_scan_bus(&dev->link[i], PCI_DEVFN(CONFIG_CDB, 0), 0xff, max);
1138 /* Tune the hypertransport transaction for best performance.
1139 * Including enabling relaxed ordering if it is safe.
1142 for(i = 0; i < FX_DEVS; i++) {
1144 f0_dev = __f0_dev[i];
1145 if (f0_dev && f0_dev->enabled) {
1147 httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
1148 httc &= ~HTTC_RSP_PASS_PW;
1149 if (!dev->link[0].disable_relaxed_ordering) {
1150 httc |= HTTC_RSP_PASS_PW;
1152 printk(BIOS_SPEW, "%s passpw: %s\n",
1154 (!dev->link[0].disable_relaxed_ordering)?
1155 "enabled":"disabled");
1156 pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
1162 static struct device_operations pci_domain_ops = {
1163 .read_resources = amdfam10_domain_read_resources,
1164 .set_resources = pci_domain_set_resources,
1165 .enable_resources = enable_childrens_resources,
1167 .scan_bus = amdfam10_domain_scan_bus,
1168 #if CONFIG_MMCONF_SUPPORT_DEFAULT
1169 .ops_pci_bus = &pci_ops_mmconf,
1171 .ops_pci_bus = &pci_cf8_conf1,
1175 static void sysconf_init(device_t dev) // first node
1177 sysconf.sblk = (pci_read_config32(dev, 0x64)>>8) & 7; // don't forget sublink1
1179 sysconf.ht_c_num = 0;
1181 unsigned ht_c_index;
1183 for(ht_c_index=0; ht_c_index<32; ht_c_index++) {
1184 sysconf.ht_c_conf_bus[ht_c_index] = 0;
1187 sysconf.nodes = ((pci_read_config32(dev, 0x60)>>4) & 7) + 1;
1188 #if CONFIG_MAX_PHYSICAL_CPUS > 8
1189 sysconf.nodes += (((pci_read_config32(dev, 0x160)>>4) & 7)<<3);
1192 sysconf.enabled_apic_ext_id = 0;
1193 sysconf.lift_bsp_apicid = 0;
1195 /* Find the bootstrap processors apicid */
1196 sysconf.bsp_apicid = lapicid();
1197 sysconf.apicid_offset = sysconf.bsp_apicid;
1199 #if (CONFIG_ENABLE_APIC_EXT_ID == 1)
1200 if (pci_read_config32(dev, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
1202 sysconf.enabled_apic_ext_id = 1;
1204 #if (CONFIG_APIC_ID_OFFSET>0)
1205 if(sysconf.enabled_apic_ext_id) {
1206 if(sysconf.bsp_apicid == 0) {
1207 /* bsp apic id is not changed */
1208 sysconf.apicid_offset = CONFIG_APIC_ID_OFFSET;
1210 sysconf.lift_bsp_apicid = 1;
1219 static u32 cpu_bus_scan(device_t dev, u32 max)
1221 struct bus *cpu_bus;
1224 device_t pci_domain;
1231 int disable_siblings;
1232 unsigned ApicIdCoreIdSize;
1235 ApicIdCoreIdSize = (cpuid_ecx(0x80000008)>>12 & 0xf);
1236 if(ApicIdCoreIdSize) {
1237 siblings = (1<<ApicIdCoreIdSize)-1;
1239 siblings = 3; //quad core
1242 disable_siblings = !CONFIG_LOGICAL_CPUS;
1243 #if CONFIG_LOGICAL_CPUS == 1
1244 get_option(&disable_siblings, "multi_core");
1247 // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it
1249 // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp???
1250 // and differ d0 and e0 single core
1252 nb_cfg_54 = read_nb_cfg_54();
1255 dev_mc = dev_find_slot(0, PCI_DEVFN(CONFIG_CDB, 0)); //0x00
1256 if(dev_mc && dev_mc->bus) {
1257 printk(BIOS_DEBUG, "%s found", dev_path(dev_mc));
1258 pci_domain = dev_mc->bus->dev;
1259 if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1260 printk(BIOS_DEBUG, "\n%s move to ",dev_path(dev_mc));
1261 dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff
1262 printk(BIOS_DEBUG, "%s",dev_path(dev_mc));
1265 printk(BIOS_DEBUG, " but it is not under pci_domain directly ");
1267 printk(BIOS_DEBUG, "\n");
1270 dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
1272 dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
1273 if (dev_mc && dev_mc->bus) {
1274 printk(BIOS_DEBUG, "%s found\n", dev_path(dev_mc));
1275 pci_domain = dev_mc->bus->dev;
1276 if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1277 if((pci_domain->links==1) && (pci_domain->link[0].children == dev_mc)) {
1278 printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc));
1279 dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff
1280 printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc));
1282 printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc));
1283 dev_mc->path.pci.devfn -= PCI_DEVFN(0x18,0);
1284 printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc));
1285 dev_mc = dev_mc->sibling;
1294 dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
1296 printk(BIOS_ERR, "%02x:%02x.0 not found", CONFIG_CBB, CONFIG_CDB);
1300 sysconf_init(dev_mc);
1302 nodes = sysconf.nodes;
1304 #if CONFIG_CBB && (NODE_NUMS > 32)
1305 if(nodes>32) { // need to put node 32 to node 63 to bus 0xfe
1306 if(pci_domain->links==1) {
1307 pci_domain->links++; // from 1 to 2
1308 pci_domain->link[1].link = 1;
1309 pci_domain->link[1].dev = pci_domain;
1310 pci_domain->link[1].children = 0;
1311 printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(pci_domain), pci_domain->links);
1313 pci_domain->link[1].secondary = CONFIG_CBB - 1;
1316 /* Find which cpus are present */
1317 cpu_bus = &dev->link[0];
1318 for(i = 0; i < nodes; i++) {
1319 device_t cdb_dev, cpu;
1320 struct device_path cpu_path;
1321 unsigned busn, devn;
1325 devn = CONFIG_CDB+i;
1327 #if CONFIG_CBB && (NODE_NUMS > 32)
1331 pbus = &(pci_domain->link[1]);
1335 /* Find the cpu's pci device */
1336 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0));
1338 /* If I am probing things in a weird order
1339 * ensure all of the cpu's pci devices are found.
1342 for(fn = 0; fn <= 5; fn++) { //FBDIMM?
1343 cdb_dev = pci_probe_dev(NULL, pbus,
1344 PCI_DEVFN(devn, fn));
1346 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn,0));
1349 /* Ok, We need to set the links for that device.
1350 * otherwise the device under it will not be scanned
1354 #if CONFIG_HT3_SUPPORT==1
1359 if(cdb_dev->links < linknum) {
1360 for(link=cdb_dev->links; link<linknum; link++) {
1361 cdb_dev->link[link].link = link;
1362 cdb_dev->link[link].dev = cdb_dev;
1364 cdb_dev->links = linknum;
1365 printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(cdb_dev), cdb_dev->links);
1369 cores_found = 0; // one core
1370 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 3));
1371 if (cdb_dev && cdb_dev->enabled) {
1372 j = pci_read_config32(cdb_dev, 0xe8);
1373 cores_found = (j >> 12) & 3; // dev is func 3
1375 cores_found |= (j >> 13) & 4;
1376 printk(BIOS_DEBUG, " %s siblings=%d\n", dev_path(cdb_dev), cores_found);
1380 if(disable_siblings) {
1387 for (j = 0; j <=jj; j++ ) {
1389 /* Build the cpu device path */
1390 cpu_path.type = DEVICE_PATH_APIC;
1391 cpu_path.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ?
1393 /* See if I can find the cpu */
1394 cpu = find_dev_path(cpu_bus, &cpu_path);
1396 /* Enable the cpu if I have the processor */
1397 if (cdb_dev && cdb_dev->enabled) {
1399 cpu = alloc_dev(cpu_bus, &cpu_path);
1406 /* Disable the cpu if I don't have the processor */
1407 if (cpu && (!cdb_dev || !cdb_dev->enabled)) {
1411 /* Report what I have done */
1413 cpu->path.apic.node_id = i;
1414 cpu->path.apic.core_id = j;
1415 #if (CONFIG_ENABLE_APIC_EXT_ID == 1) && (CONFIG_APIC_ID_OFFSET>0)
1416 if(sysconf.enabled_apic_ext_id) {
1417 if(sysconf.lift_bsp_apicid) {
1418 cpu->path.apic.apic_id += sysconf.apicid_offset;
1421 if (cpu->path.apic.apic_id != 0)
1422 cpu->path.apic.apic_id += sysconf.apicid_offset;
1426 printk(BIOS_DEBUG, "CPU: %s %s\n",
1427 dev_path(cpu), cpu->enabled?"enabled":"disabled");
1436 static void cpu_bus_init(device_t dev)
1438 initialize_cpus(&dev->link[0]);
1442 static void cpu_bus_noop(device_t dev)
1447 static struct device_operations cpu_bus_ops = {
1448 .read_resources = cpu_bus_noop,
1449 .set_resources = cpu_bus_noop,
1450 .enable_resources = cpu_bus_noop,
1451 .init = cpu_bus_init,
1452 .scan_bus = cpu_bus_scan,
1456 static void root_complex_enable_dev(struct device *dev)
1458 /* Set the operations if it is a special bus type */
1459 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
1460 dev->ops = &pci_domain_ops;
1462 else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
1463 dev->ops = &cpu_bus_ops;
1467 struct chip_operations northbridge_amd_amdfam10_root_complex_ops = {
1468 CHIP_NAME("AMD FAM10 Root Complex")
1469 .enable_dev = root_complex_enable_dev,