2 * This file is part of the LinuxBIOS 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/quadcore.h>
36 #include <pc80/mc146818rtc.h>
40 #include "root_complex/chip.h"
41 #include "northbridge.h"
45 #if 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(CBB, PCI_DEVFN(CDB + nodeid, fn));
65 return dev_find_slot(CBB-1, PCI_DEVFN(CDB + nodeid - 32, fn));
69 return dev_find_slot(CBB, PCI_DEVFN(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_err("Cannot find %02x:%02x.1", CBB, 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;
117 return (dev->path.u.pci.devfn >> 3) - CDB + 32;
119 return (dev->path.u.pci.devfn >> 3) - CDB;
123 return (dev->path.u.pci.devfn >> 3) - 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);
163 regpos = 0x170 + 4 * (link&3); // it is only on sublink0
164 reg = pci_read_config32(dev, regpos);
165 if(reg & 1) return max; // already ganged no sblink1
166 devx = get_node_pci(nodeid, 4);
172 dev->link[link].cap = 0x80 + ((link&3) *0x20);
174 link_type = pci_read_config32(devx, dev->link[link].cap + 0x18);
175 } while(link_type & ConnectionPending);
176 if (!(link_type & LinkConnected)) {
180 link_type = pci_read_config32(devx, dev->link[link].cap + 0x18);
181 } while(!(link_type & InitComplete));
182 if (!(link_type & NonCoherent)) {
185 /* See if there is an available configuration space mapping
186 * register in function 1.
188 ht_c_index = get_ht_c_index(nodeid, link, &sysconf);
190 #if EXT_CONF_SUPPORT == 0
191 if(ht_c_index>=4) return max;
194 /* Set up the primary, secondary and subordinate bus numbers.
195 * We have no idea how many busses are behind this bridge yet,
196 * so we set the subordinate bus number to 0xff for the moment.
199 #if SB_HT_CHAIN_ON_BUS0 > 0
200 // first chain will on bus 0
201 if((nodeid == 0) && (sblink==link)) { // actually max is 0 here
204 #if SB_HT_CHAIN_ON_BUS0 > 1
205 // second chain will be on 0x40, third 0x80, forth 0xc0
206 // i would refined that to 2, 3, 4 ==> 0, 0x, 40, 0x80, 0xc0
207 // >4 will use more segments, We can have 16 segmment and every segment have 256 bus, For that case need the kernel support mmio pci config.
209 min_bus = ((busn>>3) + 1) << 3; // one node can have 8 link and segn is the same
211 max = min_bus | (segn<<8);
221 max_bus = 0xfc | (segn<<8);
223 dev->link[link].secondary = min_bus;
224 dev->link[link].subordinate = max_bus;
225 /* Read the existing primary/secondary/subordinate bus
226 * number configuration.
228 busses = pci_read_config32(devx, dev->link[link].cap + 0x14);
230 /* Configure the bus numbers for this bridge: the configuration
231 * transactions will not be propagates by the bridge if it is
232 * not correctly configured
234 busses &= 0xffff00ff;
235 busses |= ((u32)(dev->link[link].secondary) << 8);
236 pci_write_config32(devx, dev->link[link].cap + 0x14, busses);
239 /* set the config map space */
241 set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes);
243 /* Now we can scan all of the subordinate busses i.e. the
244 * chain on the hypertranport link
247 ht_unitid_base[i] = 0x20;
250 //if ext conf is enabled, only need use 0x1f
252 max_devfn = (0x17<<3) | 7;
254 max_devfn = (0x1f<<3) | 7;
256 max = hypertransport_scan_chain(&dev->link[link], 0, max_devfn, max, ht_unitid_base, offset_unitid);
259 /* We know the number of busses behind this bridge. Set the
260 * subordinate bus number to it's real value
262 if(ht_c_index>3) { // clear the extend reg
263 clear_config_map_reg(nodeid, link, ht_c_index, (max+1)>>sysconf.segbit, (dev->link[link].subordinate)>>sysconf.segbit, sysconf.nodes);
266 dev->link[link].subordinate = max;
267 set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes);
271 // config config_reg, and ht_unitid_base to update hcdn_reg;
274 temp |= (ht_unitid_base[i] & 0xff) << (i*8);
277 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);
287 static u32 amdfam10_scan_chains(device_t dev, u32 max)
291 u32 sblink = sysconf.sblk;
292 u32 offset_unitid = 0;
294 nodeid = amdfam10_nodeid(dev);
297 // Put sb chain in bus 0
298 #if SB_HT_CHAIN_ON_BUS0 > 0
300 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
303 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
308 #if PCI_BUS_SEGN_BITS
309 max = check_segn(dev, max, sysconf.nodes, &sysconf);
313 for(link = 0; link < dev->links; link++) {
314 #if SB_HT_CHAIN_ON_BUS0 > 0
315 if( (nodeid == 0) && (sblink == link) ) continue; //already done
318 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
319 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
320 if((nodeid == 0) && (sblink == link))
325 max = amdfam10_scan_chain(dev, nodeid, link, sblink, max, offset_unitid);
331 static int reg_useable(u32 reg,device_t goal_dev, u32 goal_nodeid,
334 struct resource *res;
338 for(nodeid = 0; !res && (nodeid < NODE_NUMS); nodeid++) {
340 dev = __f0_dev[nodeid];
341 for(link = 0; !res && (link < 8); link++) {
342 res = probe_resource(dev, 0x1000 + reg + (link<<16)); // 8 links, 0x1000 man f1,
348 if ( (goal_link == (link - 1)) &&
349 (goal_nodeid == (nodeid - 1)) &&
357 static struct resource *amdfam10_find_iopair(device_t dev, u32 nodeid, u32 link)
359 struct resource *resource;
363 for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
365 result = reg_useable(reg, dev, nodeid, link);
367 /* I have been allocated this one */
370 else if (result > 1) {
371 /* I have a free register pair */
376 reg = free_reg; // if no free, the free_reg still be 0
381 //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
382 u32 index = get_io_addr_index(nodeid, link);
383 reg = 0x110+ (index<<24) + (4<<20); // index could be 0, 255
386 resource = new_resource(dev, 0x1000 + reg + (link<<16));
391 static struct resource *amdfam10_find_mempair(device_t dev, u32 nodeid, u32 link)
393 struct resource *resource;
397 for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
399 result = reg_useable(reg, dev, nodeid, link);
401 /* I have been allocated this one */
404 else if (result > 1) {
405 /* I have a free register pair */
415 //because of Extend conf space, we will never run out of reg,
416 // but we need one index to differ them. so same node and
417 // same link can have multi range
418 u32 index = get_mmio_addr_index(nodeid, link);
419 reg = 0x110+ (index<<24) + (6<<20); // index could be 0, 63
422 resource = new_resource(dev, 0x1000 + reg + (link<<16));
427 static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link)
429 struct resource *resource;
431 /* Initialize the io space constraints on the current bus */
432 resource = amdfam10_find_iopair(dev, nodeid, link);
435 #if EXT_CONF_SUPPORT == 1
436 if((resource->index & 0x1fff) == 0x1110) { // ext
441 align = log2(HT_IO_HOST_ALIGN);
444 resource->align = align;
445 resource->gran = align;
446 resource->limit = 0xffffUL;
447 resource->flags = IORESOURCE_IO;
448 compute_allocate_resource(&dev->link[link], resource,
449 IORESOURCE_IO, IORESOURCE_IO);
452 /* Initialize the prefetchable memory constraints on the current bus */
453 resource = amdfam10_find_mempair(dev, nodeid, link);
457 resource->align = log2(HT_MEM_HOST_ALIGN);
458 resource->gran = log2(HT_MEM_HOST_ALIGN);
459 resource->limit = 0xffffffffffULL;
460 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
461 compute_allocate_resource(&dev->link[link], resource,
462 IORESOURCE_MEM | IORESOURCE_PREFETCH,
463 IORESOURCE_MEM | IORESOURCE_PREFETCH);
465 #if EXT_CONF_SUPPORT == 1
466 if((resource->index & 0x1fff) == 0x1110) { // ext
467 normalize_resource(resource);
473 /* Initialize the memory constraints on the current bus */
474 resource = amdfam10_find_mempair(dev, nodeid, link);
478 resource->align = log2(HT_MEM_HOST_ALIGN);
479 resource->gran = log2(HT_MEM_HOST_ALIGN);
480 resource->limit = 0xffffffffffULL;
481 resource->flags = IORESOURCE_MEM;
482 compute_allocate_resource(&dev->link[link], resource,
483 IORESOURCE_MEM | IORESOURCE_PREFETCH,
486 #if EXT_CONF_SUPPORT == 1
487 if((resource->index & 0x1fff) == 0x1110) { // ext
488 normalize_resource(resource);
496 static void amdfam10_read_resources(device_t dev)
500 nodeid = amdfam10_nodeid(dev);
501 for(link = 0; link < dev->links; link++) {
502 if (dev->link[link].children) {
503 amdfam10_link_read_bases(dev, nodeid, link);
509 static void amdfam10_set_resource(device_t dev, struct resource *resource,
512 resource_t rbase, rend;
516 /* Make certain the resource has actually been set */
517 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
521 /* If I have already stored this resource don't worry about it */
522 if (resource->flags & IORESOURCE_STORED) {
526 /* Only handle PCI memory and IO resources */
527 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
530 /* Ensure I am actually looking at a resource of function 1 */
531 if ((resource->index & 0xffff) < 0x1000) {
534 /* Get the base address */
535 rbase = resource->base;
537 /* Get the limit (rounded up) */
538 rend = resource_end(resource);
540 /* Get the register and link */
541 reg = resource->index & 0xfff; // 4k
542 link = ( resource->index>> 16)& 0x7; // 8 links
544 if (resource->flags & IORESOURCE_IO) {
545 compute_allocate_resource(&dev->link[link], resource,
546 IORESOURCE_IO, IORESOURCE_IO);
548 set_io_addr_reg(dev, nodeid, link, reg, rbase>>8, rend>>8);
549 store_conf_io_addr(nodeid, link, reg, (resource->index >> 24), rbase>>8, rend>>8);
551 else if (resource->flags & IORESOURCE_MEM) {
552 compute_allocate_resource(&dev->link[link], resource,
553 IORESOURCE_MEM | IORESOURCE_PREFETCH,
554 resource->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH));
555 set_mmio_addr_reg(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8]
556 store_conf_mmio_addr(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8);
558 resource->flags |= IORESOURCE_STORED;
559 sprintf(buf, " <node %02x link %02x>",
561 report_resource_stored(dev, resource, buf);
566 * I tried to reuse the resource allocation code in amdfam10_set_resource()
567 * but it is too diffcult to deal with the resource allocation magic.
569 #if CONFIG_CONSOLE_VGA_MULTI == 1
570 extern device_t vga_pri; // the primary vga device, defined in device.c
573 static void amdfam10_create_vga_resource(device_t dev, unsigned nodeid)
577 /* find out which link the VGA card is connected,
578 * we only deal with the 'first' vga card */
579 for (link = 0; link < dev->links; link++) {
580 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
581 #if CONFIG_CONSOLE_VGA_MULTI == 1
582 printk_debug("VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary,
583 dev->link[link].secondary,dev->link[link].subordinate);
584 /* We need to make sure the vga_pri is under the link */
585 if((vga_pri->bus->secondary >= dev->link[link].secondary ) &&
586 (vga_pri->bus->secondary <= dev->link[link].subordinate )
593 /* no VGA card installed */
594 if (link == dev->links)
597 printk_debug("VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link);
598 set_vga_enable_reg(nodeid, link);
601 static void amdfam10_set_resources(device_t dev)
606 /* Find the nodeid */
607 nodeid = amdfam10_nodeid(dev);
609 amdfam10_create_vga_resource(dev, nodeid);
611 /* Set each resource we have found */
612 for(i = 0; i < dev->resources; i++) {
613 amdfam10_set_resource(dev, &dev->resource[i], nodeid);
616 for(link = 0; link < dev->links; link++) {
618 bus = &dev->link[link];
620 assign_resources(bus);
626 static void amdfam10_enable_resources(device_t dev)
628 pci_dev_enable_resources(dev);
629 enable_childrens_resources(dev);
632 static void mcf0_control_init(struct device *dev)
636 static struct device_operations northbridge_operations = {
637 .read_resources = amdfam10_read_resources,
638 .set_resources = amdfam10_set_resources,
639 .enable_resources = amdfam10_enable_resources,
640 .init = mcf0_control_init,
641 .scan_bus = amdfam10_scan_chains,
647 static struct pci_driver mcf0_driver __pci_driver = {
648 .ops = &northbridge_operations,
649 .vendor = PCI_VENDOR_ID_AMD,
653 #if CONFIG_CHIP_NAME == 1
655 struct chip_operations northbridge_amd_amdfam10_ops = {
656 CHIP_NAME("AMD FAM10 Northbridge")
662 static void pci_domain_read_resources(device_t dev)
664 struct resource *resource;
668 /* Find the already assigned resource pairs */
670 for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
672 base = f1_read_config32(reg);
673 limit = f1_read_config32(reg + 0x04);
674 /* Is this register allocated? */
675 if ((base & 3) != 0) {
676 unsigned nodeid, link;
678 if(reg<0xc0) { // mmio
679 nodeid = (limit & 0xf) + (base&0x30);
681 nodeid = (limit & 0xf) + ((base>>4)&0x30);
683 link = (limit >> 4) & 7;
684 dev = __f0_dev[nodeid];
686 /* Reserve the resource */
687 struct resource *resource;
688 resource = new_resource(dev, 0x1000 + reg + (link<<16));
695 /* FIXME: do we need to check extend conf space?
696 I don't believe that much preset value */
698 #if CONFIG_PCI_64BIT_PREF_MEM == 0
699 /* Initialize the system wide io space constraints */
700 resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
701 resource->base = 0x400;
702 resource->limit = 0xffffUL;
703 resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
705 /* Initialize the system wide memory resources constraints */
706 resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
707 resource->limit = 0xfcffffffffULL;
708 resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
710 for(link=0; link<dev->links; link++) {
711 /* Initialize the system wide io space constraints */
712 resource = new_resource(dev, 0|(link<<2));
713 resource->base = 0x400;
714 resource->limit = 0xffffUL;
715 resource->flags = IORESOURCE_IO;
716 compute_allocate_resource(&dev->link[link], resource,
717 IORESOURCE_IO, IORESOURCE_IO);
719 /* Initialize the system wide prefetchable memory resources constraints */
720 resource = new_resource(dev, 1|(link<<2));
721 resource->limit = 0xfcffffffffULL;
722 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
723 compute_allocate_resource(&dev->link[link], resource,
724 IORESOURCE_MEM | IORESOURCE_PREFETCH,
725 IORESOURCE_MEM | IORESOURCE_PREFETCH);
727 /* Initialize the system wide memory resources constraints */
728 resource = new_resource(dev, 2|(link<<2));
729 resource->limit = 0xfcffffffffULL;
730 resource->flags = IORESOURCE_MEM;
731 compute_allocate_resource(&dev->link[link], resource,
732 IORESOURCE_MEM | IORESOURCE_PREFETCH,
738 static void ram_resource(device_t dev, unsigned long index,
739 resource_t basek, resource_t sizek)
741 struct resource *resource;
746 resource = new_resource(dev, index);
747 resource->base = basek << 10;
748 resource->size = sizek << 10;
749 resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
750 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
753 static void tolm_test(void *gp, struct device *dev, struct resource *new)
755 struct resource **best_p = gp;
756 struct resource *best;
758 if (!best || (best->base > new->base)) {
764 static u32 find_pci_tolm(struct bus *bus, u32 tolm)
766 struct resource *min;
768 search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
769 if (min && tolm > min->base) {
775 #if CONFIG_PCI_64BIT_PREF_MEM == 1
776 #define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH)
779 #if HW_MEM_HOLE_SIZEK != 0
781 struct hw_mem_hole_info {
782 unsigned hole_startk;
786 static struct hw_mem_hole_info get_hw_mem_hole_info(void)
788 struct hw_mem_hole_info mem_hole;
791 mem_hole.hole_startk = HW_MEM_HOLE_SIZEK;
792 mem_hole.node_id = -1;
794 for (i = 0; i < sysconf.nodes; i++) {
795 struct dram_base_mask_t d;
797 d = get_dram_base_mask(i);
798 if(!(d.mask & 1)) continue; // no memory on this node
800 hole = pci_read_config32(__f1_dev[i], 0xf0);
801 if(hole & 1) { // we find the hole
802 mem_hole.hole_startk = (hole & (0xff<<24)) >> 10;
803 mem_hole.node_id = i; // record the node No with hole
804 break; // only one hole
808 //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
809 if(mem_hole.node_id==-1) {
810 resource_t limitk_pri = 0;
811 for(i=0; i<sysconf.nodes; i++) {
812 struct dram_base_mask_t d;
813 resource_t base_k, limit_k;
814 d = get_dram_base_mask(i);
815 if(!(d.base & 1)) continue;
817 base_k = ((resource_t)(d.base & 0x1fffff00)) <<9;
818 if(base_k > 4 *1024 * 1024) break; // don't need to go to check
819 if(limitk_pri != base_k) { // we find the hole
820 mem_hole.hole_startk = (unsigned)limitk_pri; // must beblow 4G
821 mem_hole.node_id = i;
822 break; //only one hole
825 limit_k = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9;
826 limitk_pri = limit_k;
833 #if CONFIG_AMDMCT == 0
834 static void disable_hoist_memory(unsigned long hole_startk, int i)
838 struct dram_base_mask_t d;
845 struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
846 struct mem_info *meminfo;
847 meminfo = &sysinfox->meminfo[i];
849 one_DCT = get_one_DCT(meminfo);
851 // 1. find which node has hole
852 // 2. change limit in that node.
853 // 3. change base and limit in later node
854 // 4. clear that node f0
856 // if there is not mem hole enabled, we need to change it's base instead
858 hole_sizek = (4*1024*1024) - hole_startk;
860 for(ii=NODE_NUMS-1;ii>i;ii--) {
862 d = get_dram_base_mask(ii);
864 if(!(d.mask & 1)) continue;
866 d.base -= (hole_sizek>>9);
867 d.mask -= (hole_sizek>>9);
868 set_dram_base_mask(ii, d, sysconf.nodes);
870 if(get_DctSelHiEn(ii) & 1) {
871 sel_m = get_DctSelBaseAddr(ii);
872 sel_m -= hole_startk>>10;
873 set_DctSelBaseAddr(ii, sel_m);
877 d = get_dram_base_mask(i);
879 hoist = pci_read_config32(dev, 0xf0);
880 sel_hi_en = get_DctSelHiEn(i);
883 sel_m = get_DctSelBaseAddr(i);
887 pci_write_config32(dev, 0xf0, 0);
888 d.mask -= (hole_sizek>>9);
889 set_dram_base_mask(i, d, sysconf.nodes);
890 if(one_DCT || (sel_m >= (hole_startk>>10))) {
892 sel_m -= hole_startk>>10;
893 set_DctSelBaseAddr(i, sel_m);
897 set_DctSelBaseOffset(i, 0);
901 d.base -= (hole_sizek>>9);
902 d.mask -= (hole_sizek>>9);
903 set_dram_base_mask(i, d, sysconf.nodes);
906 sel_m -= hole_startk>>10;
907 set_DctSelBaseAddr(i, sel_m);
916 static void pci_domain_set_resources(device_t dev)
918 #if CONFIG_PCI_64BIT_PREF_MEM == 1
919 struct resource *io, *mem1, *mem2;
920 struct resource *resource, *last;
922 unsigned long mmio_basek;
926 #if HW_MEM_HOLE_SIZEK != 0
927 struct hw_mem_hole_info mem_hole;
928 u32 reset_memhole = 1;
931 #if CONFIG_PCI_64BIT_PREF_MEM == 1
933 for(link=0; link<dev->links; link++) {
934 /* Now reallocate the pci resources memory with the
935 * highest addresses I can manage.
937 mem1 = find_resource(dev, 1|(link<<2));
938 mem2 = find_resource(dev, 2|(link<<2));
940 printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
941 mem1->base, mem1->limit, mem1->size, mem1->align);
942 printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
943 mem2->base, mem2->limit, mem2->size, mem2->align);
945 /* See if both resources have roughly the same limits */
946 if (((mem1->limit <= 0xffffffff) && (mem2->limit <= 0xffffffff)) ||
947 ((mem1->limit > 0xffffffff) && (mem2->limit > 0xffffffff)))
949 /* If so place the one with the most stringent alignment first
951 if (mem2->align > mem1->align) {
952 struct resource *tmp;
957 /* Now place the memory as high up as it will go */
958 mem2->base = resource_max(mem2);
959 mem1->limit = mem2->base - 1;
960 mem1->base = resource_max(mem1);
963 /* Place the resources as high up as they will go */
964 mem2->base = resource_max(mem2);
965 mem1->base = resource_max(mem1);
968 printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n",
969 mem1->base, mem1->limit, mem1->size, mem1->align);
970 printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n",
971 mem2->base, mem2->limit, mem2->size, mem2->align);
974 last = &dev->resource[dev->resources];
975 for(resource = &dev->resource[0]; resource < last; resource++)
977 resource->flags |= IORESOURCE_ASSIGNED;
978 resource->flags &= ~IORESOURCE_STORED;
979 link = (resource>>2) & 3;
980 compute_allocate_resource(&dev->link[link], resource,
981 BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK);
983 resource->flags |= IORESOURCE_STORED;
984 report_resource_stored(dev, resource, "");
989 pci_tolm = 0xffffffffUL;
990 for(link=0;link<dev->links; link++) {
991 pci_tolm = find_pci_tolm(&dev->link[link], pci_tolm);
994 #warning "FIXME handle interleaved nodes"
995 mmio_basek = pci_tolm >> 10;
996 /* Round mmio_basek to something the processor can support */
997 mmio_basek &= ~((1 << 6) -1);
999 #warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole"
1000 /* Round the mmio hold to 64M */
1001 mmio_basek &= ~((64*1024) - 1);
1003 #if HW_MEM_HOLE_SIZEK != 0
1004 /* if the hw mem hole is already set in raminit stage, here we will compare
1005 * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will
1006 * use hole_basek as mmio_basek and we don't need to reset hole.
1007 * otherwise We reset the hole to the mmio_basek
1010 mem_hole = get_hw_mem_hole_info();
1012 // Use hole_basek as mmio_basek, and we don't need to reset hole anymore
1013 if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) {
1014 mmio_basek = mem_hole.hole_startk;
1018 #if CONFIG_AMDMCT == 0
1019 //mmio_basek = 3*1024*1024; // for debug to meet boundary
1022 if(mem_hole.node_id!=-1) {
1023 /* We need to select HW_MEM_HOLE_SIZEK for raminit, it can not
1024 make hole_startk to some basek too!
1025 We need to reset our Mem Hole, because We want more big HOLE
1027 Before that We need to disable mem hole at first, becase
1028 memhole could already be set on i+1 instead
1030 disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id);
1033 #if HW_MEM_HOLE_SIZE_AUTO_INC == 1
1034 // We need to double check if the mmio_basek is valid for hole
1035 // setting, if it is equal to basek, we need to decrease it some
1036 resource_t basek_pri;
1037 for (i = 0; i < sysconf.nodes; i++) {
1038 struct dram_base_mask_t d;
1040 d = get_dram_base_mask(i);
1042 if(!(d.mask &1)) continue;
1044 basek = ((resource_t)(d.base & 0x1fffff00)) << 9;
1045 if(mmio_basek == (u32)basek) {
1046 mmio_basek -= (uin32_t)(basek - basek_pri); // increase mem hole size to make sure it is on middle of pri node
1059 for(i = 0; i < sysconf.nodes; i++) {
1060 struct dram_base_mask_t d;
1061 resource_t basek, limitk, sizek; // 4 1T
1062 d = get_dram_base_mask(i);
1064 if(!(d.mask & 1)) continue;
1065 basek = ((resource_t)(d.base & 0x1fffff00)) << 9; // could overflow, we may lost 6 bit here
1066 limitk = ((resource_t)((d.mask + 0x00000100) & 0x1fffff00)) << 9 ;
1067 sizek = limitk - basek;
1069 /* see if we need a hole from 0xa0000 to 0xbffff */
1070 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
1071 ram_resource(dev, (idx | i), basek, ((8*64)+(8*16)) - basek);
1073 basek = (8*64)+(16*16);
1074 sizek = limitk - ((8*64)+(16*16));
1078 // printk_debug("node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk);
1080 /* split the region to accomodate pci memory space */
1081 if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) {
1082 if (basek <= mmio_basek) {
1084 pre_sizek = mmio_basek - basek;
1086 ram_resource(dev, (idx | i), basek, pre_sizek);
1090 #if CONFIG_AMDMCT == 0
1091 #if HW_MEM_HOLE_SIZEK != 0
1093 struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM
1094 struct mem_info *meminfo;
1095 meminfo = &sysinfox->meminfo[i];
1096 sizek += hoist_memory(mmio_basek,i, get_one_DCT(meminfo), sysconf.nodes);
1103 if ((basek + sizek) <= 4*1024*1024) {
1107 basek = 4*1024*1024;
1108 sizek -= (4*1024*1024 - mmio_basek);
1111 ram_resource(dev, (idx | i), basek, sizek);
1115 for(link = 0; link < dev->links; link++) {
1117 bus = &dev->link[link];
1118 if (bus->children) {
1119 assign_resources(bus);
1124 static u32 pci_domain_scan_bus(device_t dev, u32 max)
1128 /* Unmap all of the HT chains */
1129 for(reg = 0xe0; reg <= 0xec; reg += 4) {
1130 f1_write_config32(reg, 0);
1132 #if EXT_CONF_SUPPORT == 1
1134 for(i = 0; i< sysconf.nodes; i++) {
1136 for(index = 0; index < 64; index++) {
1137 pci_write_config32(__f1_dev[i], 0x110, index | (6<<28));
1138 pci_write_config32(__f1_dev[i], 0x114, 0);
1145 for(i=0;i<dev->links;i++) {
1146 max = pci_scan_bus(&dev->link[i], PCI_DEVFN(CDB, 0), 0xff, max);
1149 /* Tune the hypertransport transaction for best performance.
1150 * Including enabling relaxed ordering if it is safe.
1153 for(i = 0; i < FX_DEVS; i++) {
1155 f0_dev = __f0_dev[i];
1156 if (f0_dev && f0_dev->enabled) {
1158 httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
1159 httc &= ~HTTC_RSP_PASS_PW;
1160 if (!dev->link[0].disable_relaxed_ordering) {
1161 httc |= HTTC_RSP_PASS_PW;
1163 printk_spew("%s passpw: %s\n",
1165 (!dev->link[0].disable_relaxed_ordering)?
1166 "enabled":"disabled");
1167 pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
1173 static struct device_operations pci_domain_ops = {
1174 .read_resources = pci_domain_read_resources,
1175 .set_resources = pci_domain_set_resources,
1176 .enable_resources = enable_childrens_resources,
1178 .scan_bus = pci_domain_scan_bus,
1180 .ops_pci_bus = &pci_ops_mmconf,
1182 .ops_pci_bus = &pci_cf8_conf1,
1186 static void sysconf_init(device_t dev) // first node
1188 sysconf.sblk = (pci_read_config32(dev, 0x64)>>8) & 7; // don't forget sublink1
1190 sysconf.ht_c_num = 0;
1192 unsigned ht_c_index;
1194 for(ht_c_index=0; ht_c_index<32; ht_c_index++) {
1195 sysconf.ht_c_conf_bus[ht_c_index] = 0;
1198 sysconf.nodes = ((pci_read_config32(dev, 0x60)>>4) & 7) + 1;
1199 #if CONFIG_MAX_PHYSICAL_CPUS > 8
1200 sysconf.nodes += (((pci_read_config32(dev, 0x160)>>4) & 7)<<3);
1203 sysconf.enabled_apic_ext_id = 0;
1204 sysconf.lift_bsp_apicid = 0;
1206 /* Find the bootstrap processors apicid */
1207 sysconf.bsp_apicid = lapicid();
1208 sysconf.apicid_offset = sysconf.bsp_apicid;
1210 #if (ENABLE_APIC_EXT_ID == 1)
1211 if (pci_read_config32(dev, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
1213 sysconf.enabled_apic_ext_id = 1;
1215 #if (APIC_ID_OFFSET>0)
1216 if(sysconf.enabled_apic_ext_id) {
1217 if(sysconf.bsp_apicid == 0) {
1218 /* bsp apic id is not changed */
1219 sysconf.apicid_offset = APIC_ID_OFFSET;
1221 sysconf.lift_bsp_apicid = 1;
1230 static u32 cpu_bus_scan(device_t dev, u32 max)
1232 struct bus *cpu_bus;
1234 device_t pci_domain;
1240 int disable_siblings;
1241 unsigned ApicIdCoreIdSize;
1244 ApicIdCoreIdSize = (cpuid_ecx(0x80000008)>>12 & 0xf);
1245 if(ApicIdCoreIdSize) {
1246 siblings = (1<<ApicIdCoreIdSize)-1;
1248 siblings = 3; //quad core
1251 disable_siblings = !CONFIG_LOGICAL_CPUS;
1252 #if CONFIG_LOGICAL_CPUS == 1
1253 get_option(&disable_siblings, "quad_core");
1256 // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it
1258 // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp???
1259 // and differ d0 and e0 single core
1261 nb_cfg_54 = read_nb_cfg_54();
1264 dev_mc = dev_find_slot(0, PCI_DEVFN(CDB, 0)); //0x00
1265 if(dev_mc && dev_mc->bus) {
1266 printk_debug("%s found", dev_path(dev_mc));
1267 pci_domain = dev_mc->bus->dev;
1268 if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1269 printk_debug("\n%s move to ",dev_path(dev_mc));
1270 dev_mc->bus->secondary = CBB; // move to 0xff
1271 printk_debug("%s",dev_path(dev_mc));
1274 printk_debug(" but it is not under pci_domain directly ");
1279 dev_mc = dev_find_slot(CBB, PCI_DEVFN(CDB, 0));
1281 dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
1282 if (dev_mc && dev_mc->bus) {
1283 printk_debug("%s found\n", dev_path(dev_mc));
1284 pci_domain = dev_mc->bus->dev;
1285 if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) {
1286 if((pci_domain->links==1) && (pci_domain->link[0].children == dev_mc)) {
1287 printk_debug("%s move to ",dev_path(dev_mc));
1288 dev_mc->bus->secondary = CBB; // move to 0xff
1289 printk_debug("%s\n",dev_path(dev_mc));
1291 printk_debug("%s move to ",dev_path(dev_mc));
1292 dev_mc->path.u.pci.devfn -= PCI_DEVFN(0x18,0);
1293 printk_debug("%s\n",dev_path(dev_mc));
1294 dev_mc = dev_mc->sibling;
1303 dev_mc = dev_find_slot(CBB, PCI_DEVFN(CDB, 0));
1305 printk_err("%02x:%02x.0 not found", CBB, CDB);
1309 sysconf_init(dev_mc);
1311 nodes = sysconf.nodes;
1313 #if CBB && (NODE_NUMS > 32)
1314 if(nodes>32) { // need to put node 32 to node 63 to bus 0xfe
1315 if(pci_domain->links==1) {
1316 pci_domain->links++; // from 1 to 2
1317 pci_domain->link[1].link = 1;
1318 pci_domain->link[1].dev = pci_domain;
1319 pci_domain->link[1].children = 0;
1320 printk_debug("%s links increase to %d\n", dev_path(pci_domain), pci_domain->links);
1322 pci_domain->link[1].secondary = CBB - 1;
1325 /* Find which cpus are present */
1326 cpu_bus = &dev->link[0];
1327 for(i = 0; i < nodes; i++) {
1329 struct device_path cpu_path;
1330 unsigned busn, devn;
1336 #if CBB && (NODE_NUMS > 32)
1340 pbus = &(pci_domain->link[1]);
1344 /* Find the cpu's pci device */
1345 dev = dev_find_slot(busn, PCI_DEVFN(devn, 0));
1347 /* If I am probing things in a weird order
1348 * ensure all of the cpu's pci devices are found.
1351 for(j = 0; j <= 5; j++) { //FBDIMM?
1352 dev = pci_probe_dev(NULL, pbus,
1353 PCI_DEVFN(devn, j));
1355 dev = dev_find_slot(busn, PCI_DEVFN(devn,0));
1358 /* Ok, We need to set the links for that device.
1359 * otherwise the device under it will not be scanned
1368 if(dev->links < linknum) {
1369 for(j=dev->links; j<linknum; j++) {
1370 dev->link[j].link = j;
1371 dev->link[j].dev = dev;
1373 dev->links = linknum;
1374 printk_debug("%s links increase to %d\n", dev_path(dev), dev->links);
1378 cores_found = 0; // one core
1379 dev = dev_find_slot(busn, PCI_DEVFN(devn, 3));
1380 if (dev && dev->enabled) {
1381 j = pci_read_config32(dev, 0xe8);
1382 cores_found = (j >> 12) & 3; // dev is func 3
1383 printk_debug(" %s siblings=%d\n", dev_path(dev), cores_found);
1387 if(disable_siblings) {
1394 for (j = 0; j <=jj; j++ ) {
1396 /* Build the cpu device path */
1397 cpu_path.type = DEVICE_PATH_APIC;
1398 cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:64); // ?
1400 /* See if I can find the cpu */
1401 cpu = find_dev_path(cpu_bus, &cpu_path);
1403 /* Enable the cpu if I have the processor */
1404 if (dev && dev->enabled) {
1406 cpu = alloc_dev(cpu_bus, &cpu_path);
1413 /* Disable the cpu if I don't have the processor */
1414 if (cpu && (!dev || !dev->enabled)) {
1418 /* Report what I have done */
1420 cpu->path.u.apic.node_id = i;
1421 cpu->path.u.apic.core_id = j;
1422 #if (ENABLE_APIC_EXT_ID == 1) && (APIC_ID_OFFSET>0)
1423 if(sysconf.enabled_apic_ext_id) {
1424 if(sysconf.lift_bsp_apicid) {
1425 cpu->path.u.apic.apic_id += sysconf.apicid_offset;
1428 if (cpu->path.u.apic.apic_id != 0)
1429 cpu->path.u.apic.apic_id += sysconf.apicid_offset;
1433 printk_debug("CPU: %s %s\n",
1434 dev_path(cpu), cpu->enabled?"enabled":"disabled");
1443 static void cpu_bus_init(device_t dev)
1445 initialize_cpus(&dev->link[0]);
1449 static void cpu_bus_noop(device_t dev)
1454 static struct device_operations cpu_bus_ops = {
1455 .read_resources = cpu_bus_noop,
1456 .set_resources = cpu_bus_noop,
1457 .enable_resources = cpu_bus_noop,
1458 .init = cpu_bus_init,
1459 .scan_bus = cpu_bus_scan,
1463 static void root_complex_enable_dev(struct device *dev)
1465 /* Set the operations if it is a special bus type */
1466 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
1467 dev->ops = &pci_domain_ops;
1469 else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
1470 dev->ops = &cpu_bus_ops;
1474 struct chip_operations northbridge_amd_amdfam10_root_complex_ops = {
1475 CHIP_NAME("AMD FAM10 Root Complex")
1476 .enable_dev = root_complex_enable_dev,