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];
58 static unsigned fx_devs=0;
60 device_t get_node_pci(u32 nodeid, u32 fn)
64 return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn));
66 return dev_find_slot(CONFIG_CBB-1, PCI_DEVFN(CONFIG_CDB + nodeid - 32, fn));
70 return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn));
74 static void get_fx_devs(void)
77 for(i = 0; i < FX_DEVS; i++) {
78 __f0_dev[i] = get_node_pci(i, 0);
79 __f1_dev[i] = get_node_pci(i, 1);
80 __f2_dev[i] = get_node_pci(i, 2);
81 __f4_dev[i] = get_node_pci(i, 4);
82 if (__f0_dev[i] != NULL && __f1_dev[i] != NULL)
85 if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) {
86 die("Cannot find 0:0x18.[0|1]\n");
90 static u32 f1_read_config32(unsigned reg)
94 return pci_read_config32(__f1_dev[0], reg);
97 static void f1_write_config32(unsigned reg, u32 value)
102 for(i = 0; i < fx_devs; i++) {
105 if (dev && dev->enabled) {
106 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.
200 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
201 // first chain will on bus 0
202 if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
205 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1
206 // second chain will be on 0x40, third 0x80, forth 0xc0
207 // i would refined that to 2, 3, 4 ==> 0, 0x, 40, 0x80, 0xc0
208 // >4 will use more segments, We can have 16 segmment and every segment have 256 bus, For that case need the kernel support mmio pci config.
210 min_bus = ((busn>>3) + 1) << 3; // one node can have 8 link and segn is the same
212 max = min_bus | (segn<<8);
222 max_bus = 0xfc | (segn<<8);
224 dev->link[link].secondary = min_bus;
225 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);
260 /* We know the number of busses behind this bridge. Set the
261 * subordinate bus number to it's real value
263 if(ht_c_index>3) { // clear the extend reg
264 clear_config_map_reg(nodeid, link, ht_c_index, (max+1)>>sysconf.segbit, (dev->link[link].subordinate)>>sysconf.segbit, sysconf.nodes);
267 dev->link[link].subordinate = max;
268 set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes);
272 // use ht_unitid_base to update hcdn_reg
275 temp |= (ht_unitid_base[i] & 0xff) << (i*8);
278 sysconf.hcdn_reg[ht_c_index] = temp;
281 store_ht_c_conf_bus(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, &sysconf);
285 static u32 amdfam10_scan_chains(device_t dev, u32 max)
289 unsigned sblink = sysconf.sblk;
290 unsigned offset_unitid = 0;
292 nodeid = amdfam10_nodeid(dev);
294 // Put sb chain in bus 0
295 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
297 #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
300 max = amdfam10_scan_chain(dev, nodeid, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0
304 #if CONFIG_PCI_BUS_SEGN_BITS
305 max = check_segn(dev, max, sysconf.nodes, &sysconf);
308 for(link = 0; link < dev->links; link++) {
309 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0
310 if( (nodeid == 0) && (sblink == link) ) continue; //already done
313 #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20))
314 #if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
315 if((nodeid == 0) && (sblink == link))
320 max = amdfam10_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
326 static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid,
329 struct resource *res;
330 unsigned nodeid, link = 0;
333 for(nodeid = 0; !res && (nodeid < fx_devs); nodeid++) {
335 dev = __f0_dev[nodeid];
338 for(link = 0; !res && (link < 8); link++) {
339 res = probe_resource(dev, IOINDEX(0x1000 + reg, link));
345 if ( (goal_link == (link - 1)) &&
346 (goal_nodeid == (nodeid - 1)) &&
354 static struct resource *amdfam10_find_iopair(device_t dev, unsigned nodeid, unsigned link)
356 struct resource *resource;
360 for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
362 result = reg_useable(reg, dev, nodeid, link);
364 /* I have been allocated this one */
367 else if (result > 1) {
368 /* I have a free register pair */
373 reg = free_reg; // if no free, the free_reg still be 0
378 //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
379 u32 index = get_io_addr_index(nodeid, link);
380 reg = 0x110+ (index<<24) + (4<<20); // index could be 0, 255
383 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
388 static struct resource *amdfam10_find_mempair(device_t dev, u32 nodeid, u32 link)
390 struct resource *resource;
394 for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
396 result = reg_useable(reg, dev, nodeid, link);
398 /* I have been allocated this one */
401 else if (result > 1) {
402 /* I have a free register pair */
412 //because of Extend conf space, we will never run out of reg,
413 // but we need one index to differ them. so same node and
414 // same link can have multi range
415 u32 index = get_mmio_addr_index(nodeid, link);
416 reg = 0x110+ (index<<24) + (6<<20); // index could be 0, 63
419 resource = new_resource(dev, IOINDEX(0x1000 + reg, link));
424 static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link)
426 struct resource *resource;
428 /* Initialize the io space constraints on the current bus */
429 resource = amdfam10_find_iopair(dev, nodeid, link);
432 #if CONFIG_EXT_CONF_SUPPORT == 1
433 if((resource->index & 0x1fff) == 0x1110) { // ext
438 align = log2(HT_IO_HOST_ALIGN);
441 resource->align = align;
442 resource->gran = align;
443 resource->limit = 0xffffUL;
444 resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE;
447 /* Initialize the prefetchable memory constraints on the current bus */
448 resource = amdfam10_find_mempair(dev, nodeid, link);
452 resource->align = log2(HT_MEM_HOST_ALIGN);
453 resource->gran = log2(HT_MEM_HOST_ALIGN);
454 resource->limit = 0xffffffffffULL;
455 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
456 resource->flags |= IORESOURCE_BRIDGE;
458 #if CONFIG_EXT_CONF_SUPPORT == 1
459 if((resource->index & 0x1fff) == 0x1110) { // ext
460 normalize_resource(resource);
466 /* Initialize the memory constraints on the current bus */
467 resource = amdfam10_find_mempair(dev, nodeid, link);
471 resource->align = log2(HT_MEM_HOST_ALIGN);
472 resource->gran = log2(HT_MEM_HOST_ALIGN);
473 resource->limit = 0xffffffffffULL;
474 resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE;
475 #if CONFIG_EXT_CONF_SUPPORT == 1
476 if((resource->index & 0x1fff) == 0x1110) { // ext
477 normalize_resource(resource);
483 static void amdfam10_read_resources(device_t dev)
487 nodeid = amdfam10_nodeid(dev);
488 for(link = 0; link < dev->links; link++) {
489 if (dev->link[link].children) {
490 amdfam10_link_read_bases(dev, nodeid, link);
495 static void amdfam10_set_resource(device_t dev, struct resource *resource,
498 resource_t rbase, rend;
502 /* Make certain the resource has actually been set */
503 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
507 /* If I have already stored this resource don't worry about it */
508 if (resource->flags & IORESOURCE_STORED) {
512 /* Only handle PCI memory and IO resources */
513 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
516 /* Ensure I am actually looking at a resource of function 1 */
517 if ((resource->index & 0xffff) < 0x1000) {
520 /* Get the base address */
521 rbase = resource->base;
523 /* Get the limit (rounded up) */
524 rend = resource_end(resource);
526 /* Get the register and link */
527 reg = resource->index & 0xfff; // 4k
528 link = IOINDEX_LINK(resource->index);
530 if (resource->flags & IORESOURCE_IO) {
532 set_io_addr_reg(dev, nodeid, link, reg, rbase>>8, rend>>8);
533 store_conf_io_addr(nodeid, link, reg, (resource->index >> 24), rbase>>8, rend>>8);
535 else if (resource->flags & IORESOURCE_MEM) {
536 set_mmio_addr_reg(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
537 store_conf_mmio_addr(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8);
539 resource->flags |= IORESOURCE_STORED;
540 sprintf(buf, " <node %02x link %02x>",
542 report_resource_stored(dev, resource, buf);
547 * I tried to reuse the resource allocation code in amdfam10_set_resource()
548 * but it is too diffcult to deal with the resource allocation magic.
550 #if CONFIG_CONSOLE_VGA_MULTI == 1
551 extern device_t vga_pri; // the primary vga device, defined in device.c
554 static void amdfam10_create_vga_resource(device_t dev, unsigned nodeid)
558 /* find out which link the VGA card is connected,
559 * we only deal with the 'first' vga card */
560 for (link = 0; link < dev->links; link++) {
561 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
562 #if CONFIG_CONSOLE_VGA_MULTI == 1
563 printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
564 dev->link[link].secondary,dev->link[link].subordinate);
565 /* We need to make sure the vga_pri is under the link */
566 if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
567 (vga_pri->bus->secondary <= dev->link[link].subordinate )
574 /* no VGA card installed */
575 if (link == dev->links)
578 printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
579 set_vga_enable_reg(nodeid, link);
582 static void amdfam10_set_resources(device_t dev)
585 struct resource *res;
587 /* Find the nodeid */
588 nodeid = amdfam10_nodeid(dev);
590 amdfam10_create_vga_resource(dev, nodeid);
592 /* Set each resource we have found */
593 for(res = dev->resource_list; res; res = res->next) {
594 amdfam10_set_resource(dev, res, nodeid);
597 for(link = 0; link < dev->links; link++) {
599 bus = &dev->link[link];
601 assign_resources(bus);
606 static void amdfam10_enable_resources(device_t dev)
608 pci_dev_enable_resources(dev);
609 enable_childrens_resources(dev);
612 static void mcf0_control_init(struct device *dev)
616 static struct device_operations northbridge_operations = {
617 .read_resources = amdfam10_read_resources,
618 .set_resources = amdfam10_set_resources,
619 .enable_resources = amdfam10_enable_resources,
620 .init = mcf0_control_init,
621 .scan_bus = amdfam10_scan_chains,
627 static const struct pci_driver mcf0_driver __pci_driver = {
628 .ops = &northbridge_operations,
629 .vendor = PCI_VENDOR_ID_AMD,
633 struct chip_operations northbridge_amd_amdfam10_ops = {
634 CHIP_NAME("AMD FAM10 Northbridge")
638 static void amdfam10_domain_read_resources(device_t dev)
642 /* Find the already assigned resource pairs */
644 for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
646 base = f1_read_config32(reg);
647 limit = f1_read_config32(reg + 0x04);
648 /* Is this register allocated? */
649 if ((base & 3) != 0) {
650 unsigned nodeid, reg_link;
652 if(reg<0xc0) { // mmio
653 nodeid = (limit & 0xf) + (base&0x30);
655 nodeid = (limit & 0xf) + ((base>>4)&0x30);
657 reg_link = (limit >> 4) & 7;
658 reg_dev = __f0_dev[nodeid];
660 /* Reserve the resource */
661 struct resource *res;
662 res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link));
669 /* FIXME: do we need to check extend conf space?
670 I don't believe that much preset value */
672 #if CONFIG_PCI_64BIT_PREF_MEM == 0
673 pci_domain_read_resources(dev);
676 struct resource *resource;
677 for(link=0; link<dev->links; link++) {
678 /* Initialize the system wide io space constraints */
679 resource = new_resource(dev, 0|(link<<2));
680 resource->base = 0x400;
681 resource->limit = 0xffffUL;
682 resource->flags = IORESOURCE_IO;
684 /* Initialize the system wide prefetchable memory resources constraints */
685 resource = new_resource(dev, 1|(link<<2));
686 resource->limit = 0xfcffffffffULL;
687 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
689 /* Initialize the system wide memory resources constraints */
690 resource = new_resource(dev, 2|(link<<2));
691 resource->limit = 0xfcffffffffULL;
692 resource->flags = IORESOURCE_MEM;
697 static void ram_resource(device_t dev, unsigned long index,
698 resource_t basek, resource_t sizek)
700 struct resource *resource;
705 resource = new_resource(dev, index);
706 resource->base = basek << 10;
707 resource->size = sizek << 10;
708 resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
709 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
712 static void tolm_test(void *gp, struct device *dev, struct resource *new)
714 struct resource **best_p = gp;
715 struct resource *best;
717 if (!best || (best->base > new->base)) {
723 static u32 find_pci_tolm(struct bus *bus, u32 tolm)
725 struct resource *min;
727 search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
728 if (min && tolm > min->base) {
734 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
736 struct hw_mem_hole_info {
737 unsigned hole_startk;
741 static struct hw_mem_hole_info get_hw_mem_hole_info(void)
743 struct hw_mem_hole_info mem_hole;
746 mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK;
747 mem_hole.node_id = -1;
749 for (i = 0; i < sysconf.nodes; i++) {
750 struct dram_base_mask_t d;
752 d = get_dram_base_mask(i);
753 if(!(d.mask & 1)) continue; // no memory on this node
755 hole = pci_read_config32(__f1_dev[i], 0xf0);
756 if(hole & 1) { // we find the hole
757 mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
758 mem_hole.node_id = i; // record the node No with hole
759 break; // only one hole
763 //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
764 if(mem_hole.node_id==-1) {
765 resource_t limitk_pri = 0;
766 for(i=0; i<sysconf.nodes; i++) {
767 struct dram_base_mask_t d;
768 resource_t base_k, limit_k;
769 d = get_dram_base_mask(i);
770 if(!(d.base & 1)) continue;
772 base_k = ((resource_t)(d.base & 0x1fffff00)) <<9;
773 if(base_k > 4 *1024 * 1024) break; // don't need to go to check
774 if(limitk_pri != base_k) { // we find the hole
775 mem_hole.hole_startk = (unsigned)limitk_pri; // must beblow 4G
776 mem_hole.node_id = i;
777 break; //only one hole
780 limit_k = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9;
781 limitk_pri = limit_k;
787 // WHY this check? CONFIG_AMDMCT is enabled on all Fam10 boards.
788 // Does it make sense not to?
789 #if CONFIG_AMDMCT == 0
790 static void disable_hoist_memory(unsigned long hole_startk, int node_id)
794 struct dram_base_mask_t d;
801 struct sys_info *sysinfox = (struct sys_info *)((CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
802 struct mem_info *meminfo;
803 meminfo = &sysinfox->meminfo[node_id];
805 one_DCT = get_one_DCT(meminfo);
807 // 1. find which node has hole
808 // 2. change limit in that node.
809 // 3. change base and limit in later node
810 // 4. clear that node f0
812 // if there is not mem hole enabled, we need to change it's base instead
814 hole_sizek = (4*1024*1024) - hole_startk;
816 for(i=NODE_NUMS-1;i>node_id;i--) {
818 d = get_dram_base_mask(i);
820 if(!(d.mask & 1)) continue;
822 d.base -= (hole_sizek>>9);
823 d.mask -= (hole_sizek>>9);
824 set_dram_base_mask(i, d, sysconf.nodes);
826 if(get_DctSelHiEn(i) & 1) {
827 sel_m = get_DctSelBaseAddr(i);
828 sel_m -= hole_startk>>10;
829 set_DctSelBaseAddr(i, sel_m);
833 d = get_dram_base_mask(node_id);
834 dev = __f1_dev[node_id];
835 sel_hi_en = get_DctSelHiEn(node_id);
838 sel_m = get_DctSelBaseAddr(node_id);
840 hoist = pci_read_config32(dev, 0xf0);
842 pci_write_config32(dev, 0xf0, 0);
843 d.mask -= (hole_sizek>>9);
844 set_dram_base_mask(node_id, d, sysconf.nodes);
845 if(one_DCT || (sel_m >= (hole_startk>>10))) {
847 sel_m -= hole_startk>>10;
848 set_DctSelBaseAddr(node_id, sel_m);
852 set_DctSelBaseOffset(node_id, 0);
855 d.base -= (hole_sizek>>9);
856 d.mask -= (hole_sizek>>9);
857 set_dram_base_mask(node_id, d, sysconf.nodes);
860 sel_m -= hole_startk>>10;
861 set_DctSelBaseAddr(node_id, sel_m);
870 #if CONFIG_WRITE_HIGH_TABLES==1
871 #define HIGH_TABLES_SIZE 64 // maximum size of high tables in KB
872 extern uint64_t high_tables_base, high_tables_size;
875 static void amdfam10_domain_set_resources(device_t dev)
877 #if CONFIG_PCI_64BIT_PREF_MEM == 1
878 struct resource *io, *mem1, *mem2;
879 struct resource *res;
881 unsigned long mmio_basek;
885 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
886 struct hw_mem_hole_info mem_hole;
887 u32 reset_memhole = 1;
890 #if CONFIG_PCI_64BIT_PREF_MEM == 1
892 for(link = 0; link < dev->links; link++) {
893 /* Now reallocate the pci resources memory with the
894 * highest addresses I can manage.
896 mem1 = find_resource(dev, 1|(link<<2));
897 mem2 = find_resource(dev, 2|(link<<2));
899 printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
900 mem1->base, mem1->limit, mem1->size, mem1->align);
901 printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
902 mem2->base, mem2->limit, mem2->size, mem2->align);
904 /* See if both resources have roughly the same limits */
905 if (((mem1->limit <= 0xffffffff) && (mem2->limit <= 0xffffffff)) ||
906 ((mem1->limit > 0xffffffff) && (mem2->limit > 0xffffffff)))
908 /* If so place the one with the most stringent alignment first
910 if (mem2->align > mem1->align) {
911 struct resource *tmp;
916 /* Now place the memory as high up as it will go */
917 mem2->base = resource_max(mem2);
918 mem1->limit = mem2->base - 1;
919 mem1->base = resource_max(mem1);
922 /* Place the resources as high up as they will go */
923 mem2->base = resource_max(mem2);
924 mem1->base = resource_max(mem1);
927 printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
928 mem1->base, mem1->limit, mem1->size, mem1->align);
929 printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
930 mem2->base, mem2->limit, mem2->size, mem2->align);
933 for(res = &dev->resource_list; res; res = res->next)
935 res->flags |= IORESOURCE_ASSIGNED;
936 res->flags |= IORESOURCE_STORED;
937 report_resource_stored(dev, res, "");
941 pci_tolm = 0xffffffffUL;
942 for(link = 0; link<dev->links; link++) {
943 pci_tolm = find_pci_tolm(&dev->link[link], pci_tolm);
946 // FIXME handle interleaved nodes. If you fix this here, please fix
948 mmio_basek = pci_tolm >> 10;
949 /* Round mmio_basek to something the processor can support */
950 mmio_basek &= ~((1 << 6) -1);
952 // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M
953 // MMIO hole. If you fix this here, please fix amdk8, too.
954 /* Round the mmio hole to 64M */
955 mmio_basek &= ~((64*1024) - 1);
957 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
958 /* if the hw mem hole is already set in raminit stage, here we will compare
959 * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
960 * use hole_basek as mmio_basek and we don't need to reset hole.
961 * otherwise We reset the hole to the mmio_basek
964 mem_hole = get_hw_mem_hole_info();
966 // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
967 if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) {
968 mmio_basek = mem_hole.hole_startk;
972 #if CONFIG_AMDMCT == 0
973 //mmio_basek = 3*1024*1024; // for debug to meet boundary
976 if(mem_hole.node_id!=-1) {
977 /* We need to select CONFIG_HW_MEM_HOLE_SIZEK for raminit, it can not
978 make hole_startk to some basek too!
979 We need to reset our Mem Hole, because We want more big HOLE
981 Before that We need to disable mem hole at first, becase
982 memhole could already be set on i+1 instead
984 disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
987 #if CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC == 1
988 // We need to double check if the mmio_basek is valid for hole
989 // setting, if it is equal to basek, we need to decrease it some
990 resource_t basek_pri;
991 for (i = 0; i < sysconf.nodes; i++) {
992 struct dram_base_mask_t d;
994 d = get_dram_base_mask(i);
996 if(!(d.mask &1)) continue;
998 basek = ((resource_t)(d.base & 0x1fffff00)) << 9;
999 if(mmio_basek == (u32)basek) {
1000 mmio_basek -= (uin32_t)(basek - basek_pri); // increase mem hole size to make sure it is on middle of pri node
1013 for(i = 0; i < sysconf.nodes; i++) {
1014 struct dram_base_mask_t d;
1015 resource_t basek, limitk, sizek; // 4 1T
1016 d = get_dram_base_mask(i);
1018 if(!(d.mask & 1)) continue;
1019 basek = ((resource_t)(d.base & 0x1fffff00)) << 9; // could overflow, we may lost 6 bit here
1020 limitk = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9 ;
1021 sizek = limitk - basek;
1023 /* see if we need a hole from 0xa0000 to 0xbffff */
1024 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
1025 ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
1027 basek = (8*64)+(16*16);
1028 sizek = limitk - ((8*64)+(16*16));
1032 // printk(BIOS_DEBUG, "node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk);
1034 /* split the region to accomodate pci memory space */
1035 if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) {
1036 if (basek <= mmio_basek) {
1038 pre_sizek = mmio_basek - basek;
1040 ram_resource(dev, (idx | i), basek, pre_sizek);
1043 #if CONFIG_WRITE_HIGH_TABLES==1
1044 if (high_tables_base==0) {
1045 /* Leave some space for ACPI, PIRQ and MP tables */
1046 high_tables_base = (mmio_basek - HIGH_TABLES_SIZE) * 1024;
1047 high_tables_size = HIGH_TABLES_SIZE * 1024;
1048 printk(BIOS_DEBUG, " split: %dK table at =%08llx\n", HIGH_TABLES_SIZE,
1053 #if CONFIG_AMDMCT == 0
1054 #if CONFIG_HW_MEM_HOLE_SIZEK != 0
1056 struct sys_info *sysinfox = (struct sys_info *)((CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
1057 struct mem_info *meminfo;
1058 meminfo = &sysinfox->meminfo[i];
1059 sizek += hoist_memory(mmio_basek,i, get_one_DCT(meminfo), sysconf.nodes);
1066 if ((basek + sizek) <= 4*1024*1024) {
1070 basek = 4*1024*1024;
1071 sizek -= (4*1024*1024 - mmio_basek);
1074 ram_resource(dev, (idx | i), basek, sizek);
1076 #if CONFIG_WRITE_HIGH_TABLES==1
1077 printk(BIOS_DEBUG, "%d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n",
1078 i, mmio_basek, basek, limitk);
1079 if (high_tables_base==0) {
1080 /* Leave some space for ACPI, PIRQ and MP tables */
1081 high_tables_base = (limitk - HIGH_TABLES_SIZE) * 1024;
1082 high_tables_size = HIGH_TABLES_SIZE * 1024;
1087 for(link = 0; link < dev->links; link++) {
1089 bus = &dev->link[link];
1090 if (bus->children) {
1091 assign_resources(bus);
1096 static u32 amdfam10_domain_scan_bus(device_t dev, u32 max)
1100 /* Unmap all of the HT chains */
1101 for(reg = 0xe0; reg <= 0xec; reg += 4) {
1102 f1_write_config32(reg, 0);
1104 #if CONFIG_EXT_CONF_SUPPORT == 1
1106 for(i = 0; i< sysconf.nodes; i++) {
1108 for(index = 0; index < 64; index++) {
1109 pci_write_config32(__f1_dev[i], 0x110, index | (6<<28));
1110 pci_write_config32(__f1_dev[i], 0x114, 0);
1117 for(i = 0; i < dev->links; i++) {
1118 max = pci_scan_bus(&dev->link[i], PCI_DEVFN(CONFIG_CDB, 0), 0xff, max);
1121 /* Tune the hypertransport transaction for best performance.
1122 * Including enabling relaxed ordering if it is safe.
1125 for(i = 0; i < fx_devs; i++) {
1127 f0_dev = __f0_dev[i];
1128 if (f0_dev && f0_dev->enabled) {
1130 httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
1131 httc &= ~HTTC_RSP_PASS_PW;
1132 if (!dev->link[0].disable_relaxed_ordering) {
1133 httc |= HTTC_RSP_PASS_PW;
1135 printk(BIOS_SPEW, "%s passpw: %s\n",
1137 (!dev->link[0].disable_relaxed_ordering)?
1138 "enabled":"disabled");
1139 pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
1145 static struct device_operations pci_domain_ops = {
1146 .read_resources = amdfam10_domain_read_resources,
1147 .set_resources = amdfam10_domain_set_resources,
1148 .enable_resources = enable_childrens_resources,
1150 .scan_bus = amdfam10_domain_scan_bus,
1151 #if CONFIG_MMCONF_SUPPORT_DEFAULT
1152 .ops_pci_bus = &pci_ops_mmconf,
1154 .ops_pci_bus = &pci_cf8_conf1,
1158 static void sysconf_init(device_t dev) // first node
1160 sysconf.sblk = (pci_read_config32(dev, 0x64)>>8) & 7; // don't forget sublink1
1162 sysconf.ht_c_num = 0;
1164 unsigned ht_c_index;
1166 for(ht_c_index=0; ht_c_index<32; ht_c_index++) {
1167 sysconf.ht_c_conf_bus[ht_c_index] = 0;
1170 sysconf.nodes = ((pci_read_config32(dev, 0x60)>>4) & 7) + 1;
1171 #if CONFIG_MAX_PHYSICAL_CPUS > 8
1172 sysconf.nodes += (((pci_read_config32(dev, 0x160)>>4) & 7)<<3);
1175 sysconf.enabled_apic_ext_id = 0;
1176 sysconf.lift_bsp_apicid = 0;
1178 /* Find the bootstrap processors apicid */
1179 sysconf.bsp_apicid = lapicid();
1180 sysconf.apicid_offset = sysconf.bsp_apicid;
1182 #if (CONFIG_ENABLE_APIC_EXT_ID == 1)
1183 if (pci_read_config32(dev, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
1185 sysconf.enabled_apic_ext_id = 1;
1187 #if (CONFIG_APIC_ID_OFFSET>0)
1188 if(sysconf.enabled_apic_ext_id) {
1189 if(sysconf.bsp_apicid == 0) {
1190 /* bsp apic id is not changed */
1191 sysconf.apicid_offset = CONFIG_APIC_ID_OFFSET;
1193 sysconf.lift_bsp_apicid = 1;
1200 static u32 cpu_bus_scan(device_t dev, u32 max)
1202 struct bus *cpu_bus;
1205 device_t pci_domain;
1212 int disable_siblings;
1213 unsigned ApicIdCoreIdSize;
1216 ApicIdCoreIdSize = (cpuid_ecx(0x80000008)>>12 & 0xf);
1217 if(ApicIdCoreIdSize) {
1218 siblings = (1<<ApicIdCoreIdSize)-1;
1220 siblings = 3; //quad core
1223 disable_siblings = !CONFIG_LOGICAL_CPUS;
1224 #if CONFIG_LOGICAL_CPUS == 1
1225 get_option(&disable_siblings, "multi_core");
1228 // How can I get the nb_cfg_54 of every node's nb_cfg_54 in bsp???
1229 nb_cfg_54 = read_nb_cfg_54();
1232 dev_mc = dev_find_slot(0, PCI_DEVFN(CONFIG_CDB, 0)); //0x00
1233 if(dev_mc && dev_mc->bus) {
1234 printk(BIOS_DEBUG, "%s found", dev_path(dev_mc));
1235 pci_domain = dev_mc->bus->dev;
1236 if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1237 printk(BIOS_DEBUG, "\n%s move to ",dev_path(dev_mc));
1238 dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff
1239 printk(BIOS_DEBUG, "%s",dev_path(dev_mc));
1242 printk(BIOS_DEBUG, " but it is not under pci_domain directly ");
1244 printk(BIOS_DEBUG, "\n");
1246 dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
1248 dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
1249 if (dev_mc && dev_mc->bus) {
1250 printk(BIOS_DEBUG, "%s found\n", dev_path(dev_mc));
1251 pci_domain = dev_mc->bus->dev;
1252 if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1253 if((pci_domain->links==1) && (pci_domain->link[0].children == dev_mc)) {
1254 printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc));
1255 dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff
1256 printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc));
1258 printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc));
1259 dev_mc->path.pci.devfn -= PCI_DEVFN(0x18,0);
1260 printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc));
1261 dev_mc = dev_mc->sibling;
1270 dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0));
1272 printk(BIOS_ERR, "%02x:%02x.0 not found", CONFIG_CBB, CONFIG_CDB);
1276 sysconf_init(dev_mc);
1278 nodes = sysconf.nodes;
1280 #if CONFIG_CBB && (NODE_NUMS > 32)
1281 if(nodes>32) { // need to put node 32 to node 63 to bus 0xfe
1282 if(pci_domain->links==1) {
1283 pci_domain->links++; // from 1 to 2
1284 pci_domain->link[1].link = 1;
1285 pci_domain->link[1].dev = pci_domain;
1286 pci_domain->link[1].children = 0;
1287 printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(pci_domain), pci_domain->links);
1289 pci_domain->link[1].secondary = CONFIG_CBB - 1;
1292 /* Find which cpus are present */
1293 cpu_bus = &dev->link[0];
1294 for(i = 0; i < nodes; i++) {
1295 device_t cdb_dev, cpu;
1296 struct device_path cpu_path;
1297 unsigned busn, devn;
1301 devn = CONFIG_CDB+i;
1303 #if CONFIG_CBB && (NODE_NUMS > 32)
1307 pbus = &(pci_domain->link[1]);
1311 /* Find the cpu's pci device */
1312 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0));
1314 /* If I am probing things in a weird order
1315 * ensure all of the cpu's pci devices are found.
1318 for(fn = 0; fn <= 5; fn++) { //FBDIMM?
1319 cdb_dev = pci_probe_dev(NULL, pbus,
1320 PCI_DEVFN(devn, fn));
1322 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0));
1325 /* Ok, We need to set the links for that device.
1326 * otherwise the device under it will not be scanned
1330 #if CONFIG_HT3_SUPPORT==1
1335 if (cdb_dev->links < linknum) {
1336 for(link=cdb_dev->links; link<linknum; link++) {
1337 cdb_dev->link[link].link = link;
1338 cdb_dev->link[link].dev = cdb_dev;
1340 cdb_dev->links = linknum;
1341 printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(cdb_dev), cdb_dev->links);
1345 cores_found = 0; // one core
1346 cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 3));
1347 if (cdb_dev && cdb_dev->enabled) {
1348 j = pci_read_config32(cdb_dev, 0xe8);
1349 cores_found = (j >> 12) & 3; // dev is func 3
1351 cores_found |= (j >> 13) & 4;
1352 printk(BIOS_DEBUG, " %s siblings=%d\n", dev_path(cdb_dev), cores_found);
1356 if(disable_siblings) {
1363 for (j = 0; j <=jj; j++ ) {
1365 /* Build the cpu device path */
1366 cpu_path.type = DEVICE_PATH_APIC;
1367 cpu_path.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ?
1369 /* See if I can find the cpu */
1370 cpu = find_dev_path(cpu_bus, &cpu_path);
1372 /* Enable the cpu if I have the processor */
1373 if (cdb_dev && cdb_dev->enabled) {
1375 cpu = alloc_dev(cpu_bus, &cpu_path);
1382 /* Disable the cpu if I don't have the processor */
1383 if (cpu && (!cdb_dev || !cdb_dev->enabled)) {
1387 /* Report what I have done */
1389 cpu->path.apic.node_id = i;
1390 cpu->path.apic.core_id = j;
1391 #if (CONFIG_ENABLE_APIC_EXT_ID == 1) && (CONFIG_APIC_ID_OFFSET>0)
1392 if(sysconf.enabled_apic_ext_id) {
1393 if(sysconf.lift_bsp_apicid) {
1394 cpu->path.apic.apic_id += sysconf.apicid_offset;
1397 if (cpu->path.apic.apic_id != 0)
1398 cpu->path.apic.apic_id += sysconf.apicid_offset;
1402 printk(BIOS_DEBUG, "CPU: %s %s\n",
1403 dev_path(cpu), cpu->enabled?"enabled":"disabled");
1411 static void cpu_bus_init(device_t dev)
1413 initialize_cpus(&dev->link[0]);
1416 static void cpu_bus_noop(device_t dev)
1420 static struct device_operations cpu_bus_ops = {
1421 .read_resources = cpu_bus_noop,
1422 .set_resources = cpu_bus_noop,
1423 .enable_resources = cpu_bus_noop,
1424 .init = cpu_bus_init,
1425 .scan_bus = cpu_bus_scan,
1428 static void root_complex_enable_dev(struct device *dev)
1430 /* Set the operations if it is a special bus type */
1431 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
1432 dev->ops = &pci_domain_ops;
1434 else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
1435 dev->ops = &cpu_bus_ops;
1439 struct chip_operations northbridge_amd_amdfam10_root_complex_ops = {
1440 CHIP_NAME("AMD FAM10 Root Complex")
1441 .enable_dev = root_complex_enable_dev,