X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnorthbridge%2Famd%2Famdfam10%2Fnorthbridge.c;h=018b6c83b0d8e81dc3be08340885918f266e1b5b;hb=2143d3737553b293923ad566ef4cda3aec742f75;hp=bdb743387d5eeedfdbdf065f7463a7e40ddedfcd;hpb=43b29cf891c78a2cd01d22a2731c7da828d79e0a;p=coreboot.git diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index bdb743387..018b6c83b 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -32,7 +32,7 @@ #include #if CONFIG_LOGICAL_CPUS==1 -#include +#include #include #endif @@ -42,11 +42,16 @@ #include "amdfam10.h" -#if HW_MEM_HOLE_SIZEK != 0 +#if CONFIG_HW_MEM_HOLE_SIZEK != 0 #include #endif #include +#if CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 +#include +#elif CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 +#include +#endif struct amdfam10_sysconf_t sysconf; @@ -55,50 +60,51 @@ static device_t __f0_dev[FX_DEVS]; static device_t __f1_dev[FX_DEVS]; static device_t __f2_dev[FX_DEVS]; static device_t __f4_dev[FX_DEVS]; +static unsigned fx_devs=0; device_t get_node_pci(u32 nodeid, u32 fn) { #if NODE_NUMS == 64 if(nodeid<32) { - return dev_find_slot(CBB, PCI_DEVFN(CDB + nodeid, fn)); + return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn)); } else { - return dev_find_slot(CBB-1, PCI_DEVFN(CDB + nodeid - 32, fn)); + return dev_find_slot(CONFIG_CBB-1, PCI_DEVFN(CONFIG_CDB + nodeid - 32, fn)); } #else - return dev_find_slot(CBB, PCI_DEVFN(CDB + nodeid, fn)); + return dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB + nodeid, fn)); #endif - } + static void get_fx_devs(void) { int i; - if (__f1_dev[0]) { - return; - } for(i = 0; i < FX_DEVS; i++) { __f0_dev[i] = get_node_pci(i, 0); __f1_dev[i] = get_node_pci(i, 1); __f2_dev[i] = get_node_pci(i, 2); __f4_dev[i] = get_node_pci(i, 4); + if (__f0_dev[i] != NULL && __f1_dev[i] != NULL) + fx_devs = i+1; } - if (!__f1_dev[0]) { - printk_err("Cannot find %02x:%02x.1", CBB, CDB); - die("Cannot go on\n"); + if (__f1_dev[0] == NULL || __f0_dev[0] == NULL || fx_devs == 0) { + die("Cannot find 0:0x18.[0|1]\n"); } } -static u32 f1_read_config32(u32 reg) +static u32 f1_read_config32(unsigned reg) { - get_fx_devs(); + if (fx_devs == 0) + get_fx_devs(); return pci_read_config32(__f1_dev[0], reg); } -static void f1_write_config32(u32 reg, u32 value) +static void f1_write_config32(unsigned reg, u32 value) { int i; - get_fx_devs(); - for(i = 0; i < FX_DEVS; i++) { + if (fx_devs == 0) + get_fx_devs(); + for(i = 0; i < fx_devs; i++) { device_t dev; dev = __f1_dev[i]; if (dev && dev->enabled) { @@ -107,24 +113,23 @@ static void f1_write_config32(u32 reg, u32 value) } } - static u32 amdfam10_nodeid(device_t dev) { #if NODE_NUMS == 64 unsigned busn; busn = dev->bus->secondary; - if(busn != CBB) { - return (dev->path.pci.devfn >> 3) - CDB + 32; + if(busn != CONFIG_CBB) { + return (dev->path.pci.devfn >> 3) - CONFIG_CDB + 32; } else { - return (dev->path.pci.devfn >> 3) - CDB; + return (dev->path.pci.devfn >> 3) - CONFIG_CDB; } #else - return (dev->path.pci.devfn >> 3) - CDB; + return (dev->path.pci.devfn >> 3) - CONFIG_CDB; #endif } -#include "amdfam10_conf.c" +#include "conf.c" static void set_vga_enable_reg(u32 nodeid, u32 linkn) { @@ -137,7 +142,7 @@ static void set_vga_enable_reg(u32 nodeid, u32 linkn) } -static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, +static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, struct bus *link, u32 link_num, u32 sblink, u32 max, u32 offset_unitid) { // I want to put sb chain in bus 0 can I? @@ -149,18 +154,20 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, u32 ht_unitid_base[4]; // here assume only 4 HT device on chain u32 max_bus; u32 min_bus; - u32 is_sublink1 = (link>3); + u32 is_sublink1 = (link_num>3); device_t devx; u32 busses; u32 segn = max>>8; +#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1 u32 busn = max&0xff; +#endif u32 max_devfn; -#if HT3_SUPPORT==1 +#if CONFIG_HT3_SUPPORT==1 if(is_sublink1) { u32 regpos; u32 reg; - regpos = 0x170 + 4 * (link&3); // it is only on sublink0 + regpos = 0x170 + 4 * (link_num&3); // it is only on sublink0 reg = pci_read_config32(dev, regpos); if(reg & 1) return max; // already ganged no sblink1 devx = get_node_pci(nodeid, 4); @@ -169,15 +176,15 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, devx = dev; - dev->link[link].cap = 0x80 + ((link&3) *0x20); + link->cap = 0x80 + ((link_num&3) *0x20); do { - link_type = pci_read_config32(devx, dev->link[link].cap + 0x18); + link_type = pci_read_config32(devx, link->cap + 0x18); } while(link_type & ConnectionPending); if (!(link_type & LinkConnected)) { return max; } do { - link_type = pci_read_config32(devx, dev->link[link].cap + 0x18); + link_type = pci_read_config32(devx, link->cap + 0x18); } while(!(link_type & InitComplete)); if (!(link_type & NonCoherent)) { return max; @@ -185,9 +192,9 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, /* See if there is an available configuration space mapping * register in function 1. */ - ht_c_index = get_ht_c_index(nodeid, link, &sysconf); + ht_c_index = get_ht_c_index(nodeid, link_num, &sysconf); -#if EXT_CONF_SUPPORT == 0 +#if CONFIG_EXT_CONF_SUPPORT == 0 if(ht_c_index>=4) return max; #endif @@ -195,13 +202,12 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, * We have no idea how many busses are behind this bridge yet, * so we set the subordinate bus number to 0xff for the moment. */ - -#if SB_HT_CHAIN_ON_BUS0 > 0 +#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0 // first chain will on bus 0 - if((nodeid == 0) && (sblink==link)) { // actually max is 0 here - min_bus = max; + if((nodeid == 0) && (sblink==link_num)) { // actually max is 0 here + min_bus = max; } - #if SB_HT_CHAIN_ON_BUS0 > 1 + #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 1 // second chain will be on 0x40, third 0x80, forth 0xc0 // i would refined that to 2, 3, 4 ==> 0, 0x, 40, 0x80, 0xc0 // >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,36 +215,37 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, min_bus = ((busn>>3) + 1) << 3; // one node can have 8 link and segn is the same } max = min_bus | (segn<<8); - #else + #else //other ... else { min_bus = ++max; } - #endif + #endif #else min_bus = ++max; #endif max_bus = 0xfc | (segn<<8); - dev->link[link].secondary = min_bus; - dev->link[link].subordinate = max_bus; + link->secondary = min_bus; + link->subordinate = max_bus; + /* Read the existing primary/secondary/subordinate bus * number configuration. */ - busses = pci_read_config32(devx, dev->link[link].cap + 0x14); + busses = pci_read_config32(devx, link->cap + 0x14); /* Configure the bus numbers for this bridge: the configuration * transactions will not be propagates by the bridge if it is * not correctly configured */ busses &= 0xffff00ff; - busses |= ((u32)(dev->link[link].secondary) << 8); - pci_write_config32(devx, dev->link[link].cap + 0x14, busses); + busses |= ((u32)(link->secondary) << 8); + pci_write_config32(devx, link->cap + 0x14, busses); /* set the config map space */ - set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes); + set_config_map_reg(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, sysconf.segbit, sysconf.nodes); /* Now we can scan all of the subordinate busses i.e. the * chain on the hypertranport link @@ -253,22 +260,21 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, else max_devfn = (0x1f<<3) | 7; - max = hypertransport_scan_chain(&dev->link[link], 0, max_devfn, max, ht_unitid_base, offset_unitid); - + max = hypertransport_scan_chain(link, 0, max_devfn, max, ht_unitid_base, offset_unitid); /* We know the number of busses behind this bridge. Set the * subordinate bus number to it's real value */ if(ht_c_index>3) { // clear the extend reg - clear_config_map_reg(nodeid, link, ht_c_index, (max+1)>>sysconf.segbit, (dev->link[link].subordinate)>>sysconf.segbit, sysconf.nodes); + clear_config_map_reg(nodeid, link_num, ht_c_index, (max+1)>>sysconf.segbit, (link->subordinate)>>sysconf.segbit, sysconf.nodes); } - dev->link[link].subordinate = max; - set_config_map_reg(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, sysconf.segbit, sysconf.nodes); + link->subordinate = max; + set_config_map_reg(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, sysconf.segbit, sysconf.nodes); sysconf.ht_c_num++; { - // config config_reg, and ht_unitid_base to update hcdn_reg; + // use ht_unitid_base to update hcdn_reg u32 temp = 0; for(i=0;i<4;i++) { temp |= (ht_unitid_base[i] & 0xff) << (i*8); @@ -277,69 +283,67 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, sysconf.hcdn_reg[ht_c_index] = temp; } - - store_ht_c_conf_bus(nodeid, link, ht_c_index, dev->link[link].secondary, dev->link[link].subordinate, &sysconf); - - + store_ht_c_conf_bus(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, &sysconf); return max; } -static u32 amdfam10_scan_chains(device_t dev, u32 max) +static unsigned amdfam10_scan_chains(device_t dev, unsigned max) { - u32 nodeid; - u32 link; - u32 sblink = sysconf.sblk; - u32 offset_unitid = 0; + unsigned nodeid; + struct bus *link; + unsigned sblink = sysconf.sblk; + unsigned offset_unitid = 0; nodeid = amdfam10_nodeid(dev); - // Put sb chain in bus 0 -#if SB_HT_CHAIN_ON_BUS0 > 0 +#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0 if(nodeid==0) { - #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20)) + #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20)) offset_unitid = 1; #endif - 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 + for (link = dev->link_list; link; link = link->next) + if (link->link_num == sblink) + max = amdfam10_scan_chain(dev, nodeid, link, sblink, sblink, max, offset_unitid ); // do sb ht chain at first, in case s2885 put sb chain (8131/8111) on link2, but put 8151 on link0 } #endif - -#if PCI_BUS_SEGN_BITS +#if CONFIG_PCI_BUS_SEGN_BITS max = check_segn(dev, max, sysconf.nodes, &sysconf); #endif - - for(link = 0; link < dev->links; link++) { -#if SB_HT_CHAIN_ON_BUS0 > 0 - if( (nodeid == 0) && (sblink == link) ) continue; //already done + for(link = dev->link_list; link; link = link->next) { +#if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0 + if( (nodeid == 0) && (sblink == link->link_num) ) continue; //already done #endif offset_unitid = 0; - #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20)) - #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1 - if((nodeid == 0) && (sblink == link)) + #if ((CONFIG_HT_CHAIN_UNITID_BASE != 1) || (CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20)) + #if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1 + if((nodeid == 0) && (sblink == link->link_num)) #endif offset_unitid = 1; #endif - max = amdfam10_scan_chain(dev, nodeid, link, sblink, max, offset_unitid); + max = amdfam10_scan_chain(dev, nodeid, link, link->link_num, sblink, max, offset_unitid); } return max; } -static int reg_useable(u32 reg,device_t goal_dev, u32 goal_nodeid, - u32 goal_link) +static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid, + unsigned goal_link) { struct resource *res; - u32 nodeid, link; + unsigned nodeid, link = 0; int result; res = 0; - for(nodeid = 0; !res && (nodeid < NODE_NUMS); nodeid++) { + for(nodeid = 0; !res && (nodeid < fx_devs); nodeid++) { device_t dev; dev = __f0_dev[nodeid]; + if (!dev) + continue; for(link = 0; !res && (link < 8); link++) { - res = probe_resource(dev, 0x1000 + reg + (link<<16)); // 8 links, 0x1000 man f1, + res = probe_resource(dev, IOINDEX(0x1000 + reg, link)); } } result = 2; @@ -354,7 +358,7 @@ static int reg_useable(u32 reg,device_t goal_dev, u32 goal_nodeid, return result; } -static struct resource *amdfam10_find_iopair(device_t dev, u32 nodeid, u32 link) +static struct resource *amdfam10_find_iopair(device_t dev, unsigned nodeid, unsigned link) { struct resource *resource; u32 free_reg, reg; @@ -383,7 +387,7 @@ static struct resource *amdfam10_find_iopair(device_t dev, u32 nodeid, u32 link) reg = 0x110+ (index<<24) + (4<<20); // index could be 0, 255 } - resource = new_resource(dev, 0x1000 + reg + (link<<16)); + resource = new_resource(dev, IOINDEX(0x1000 + reg, link)); return resource; } @@ -419,7 +423,7 @@ static struct resource *amdfam10_find_mempair(device_t dev, u32 nodeid, u32 link reg = 0x110+ (index<<24) + (6<<20); // index could be 0, 63 } - resource = new_resource(dev, 0x1000 + reg + (link<<16)); + resource = new_resource(dev, IOINDEX(0x1000 + reg, link)); return resource; } @@ -429,10 +433,10 @@ static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link) struct resource *resource; /* Initialize the io space constraints on the current bus */ - resource = amdfam10_find_iopair(dev, nodeid, link); + resource = amdfam10_find_iopair(dev, nodeid, link); if (resource) { u32 align; -#if EXT_CONF_SUPPORT == 1 +#if CONFIG_EXT_CONF_SUPPORT == 1 if((resource->index & 0x1fff) == 0x1110) { // ext align = 8; } @@ -444,25 +448,21 @@ static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link) resource->align = align; resource->gran = align; resource->limit = 0xffffUL; - resource->flags = IORESOURCE_IO; - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_IO, IORESOURCE_IO); + resource->flags = IORESOURCE_IO | IORESOURCE_BRIDGE; } /* Initialize the prefetchable memory constraints on the current bus */ resource = amdfam10_find_mempair(dev, nodeid, link); if (resource) { - resource->base = 0; - resource->size = 0; + resource->base = 0; + resource->size = 0; resource->align = log2(HT_MEM_HOST_ALIGN); - resource->gran = log2(HT_MEM_HOST_ALIGN); + resource->gran = log2(HT_MEM_HOST_ALIGN); resource->limit = 0xffffffffffULL; resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM | IORESOURCE_PREFETCH); + resource->flags |= IORESOURCE_BRIDGE; -#if EXT_CONF_SUPPORT == 1 +#if CONFIG_EXT_CONF_SUPPORT == 1 if((resource->index & 0x1fff) == 0x1110) { // ext normalize_resource(resource); } @@ -473,44 +473,37 @@ static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link) /* Initialize the memory constraints on the current bus */ resource = amdfam10_find_mempair(dev, nodeid, link); if (resource) { - resource->base = 0; - resource->size = 0; + resource->base = 0; + resource->size = 0; resource->align = log2(HT_MEM_HOST_ALIGN); - resource->gran = log2(HT_MEM_HOST_ALIGN); + resource->gran = log2(HT_MEM_HOST_ALIGN); resource->limit = 0xffffffffffULL; - resource->flags = IORESOURCE_MEM; - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM); - -#if EXT_CONF_SUPPORT == 1 + resource->flags = IORESOURCE_MEM | IORESOURCE_BRIDGE; +#if CONFIG_EXT_CONF_SUPPORT == 1 if((resource->index & 0x1fff) == 0x1110) { // ext normalize_resource(resource); } #endif - } } - static void amdfam10_read_resources(device_t dev) { - u32 nodeid, link; - + u32 nodeid; + struct bus *link; nodeid = amdfam10_nodeid(dev); - for(link = 0; link < dev->links; link++) { - if (dev->link[link].children) { - amdfam10_link_read_bases(dev, nodeid, link); + for(link = dev->link_list; link; link = link->next) { + if (link->children) { + amdfam10_link_read_bases(dev, nodeid, link->link_num); } } } - static void amdfam10_set_resource(device_t dev, struct resource *resource, u32 nodeid) { resource_t rbase, rend; - unsigned reg, link; + unsigned reg, link_num; char buf[50]; /* Make certain the resource has actually been set */ @@ -539,51 +532,43 @@ static void amdfam10_set_resource(device_t dev, struct resource *resource, /* Get the register and link */ reg = resource->index & 0xfff; // 4k - link = ( resource->index>> 16)& 0x7; // 8 links + link_num = IOINDEX_LINK(resource->index); if (resource->flags & IORESOURCE_IO) { - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_IO, IORESOURCE_IO); - set_io_addr_reg(dev, nodeid, link, reg, rbase>>8, rend>>8); - store_conf_io_addr(nodeid, link, reg, (resource->index >> 24), rbase>>8, rend>>8); + set_io_addr_reg(dev, nodeid, link_num, reg, rbase>>8, rend>>8); + store_conf_io_addr(nodeid, link_num, reg, (resource->index >> 24), rbase>>8, rend>>8); } else if (resource->flags & IORESOURCE_MEM) { - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - resource->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)); - set_mmio_addr_reg(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8] - store_conf_mmio_addr(nodeid, link, reg, (resource->index >>24), rbase>>8, rend>>8); + set_mmio_addr_reg(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8, sysconf.nodes) ;// [39:8] + store_conf_mmio_addr(nodeid, link_num, reg, (resource->index >>24), rbase>>8, rend>>8); } resource->flags |= IORESOURCE_STORED; - sprintf(buf, " ", - nodeid, link); + sprintf(buf, " ", + nodeid, link_num); report_resource_stored(dev, resource, buf); } /** - * * I tried to reuse the resource allocation code in amdfam10_set_resource() - * but it is too diffcult to deal with the resource allocation magic. + * but it is too difficult to deal with the resource allocation magic. */ -#if CONFIG_CONSOLE_VGA_MULTI == 1 -extern device_t vga_pri; // the primary vga device, defined in device.c -#endif static void amdfam10_create_vga_resource(device_t dev, unsigned nodeid) { - unsigned link; + struct bus *link; /* find out which link the VGA card is connected, * we only deal with the 'first' vga card */ - for (link = 0; link < dev->links; link++) { - if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) { -#if CONFIG_CONSOLE_VGA_MULTI == 1 - printk_debug("VGA: vga_pri bus num = %d dev->link[link] bus range [%d,%d]\n", vga_pri->bus->secondary, - dev->link[link].secondary,dev->link[link].subordinate); + for (link = dev->link_list; link; link = link->next) { + if (link->bridge_ctrl & PCI_BRIDGE_CTL_VGA) { +#if CONFIG_MULTIPLE_VGA_ADAPTERS == 1 + extern device_t vga_pri; // the primary vga device, defined in device.c + printk(BIOS_DEBUG, "VGA: vga_pri bus num = %d bus range [%d,%d]\n", vga_pri->bus->secondary, + link->secondary,link->subordinate); /* We need to make sure the vga_pri is under the link */ - if((vga_pri->bus->secondary >= dev->link[link].secondary ) && - (vga_pri->bus->secondary <= dev->link[link].subordinate ) + if((vga_pri->bus->secondary >= link->secondary ) && + (vga_pri->bus->secondary <= link->subordinate ) ) #endif break; @@ -591,17 +576,18 @@ static void amdfam10_create_vga_resource(device_t dev, unsigned nodeid) } /* no VGA card installed */ - if (link == dev->links) + if (link == NULL) return; - printk_debug("VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link); - set_vga_enable_reg(nodeid, link); + printk(BIOS_DEBUG, "VGA: %s (aka node %d) link %d has VGA device\n", dev_path(dev), nodeid, link->link_num); + set_vga_enable_reg(nodeid, link->link_num); } static void amdfam10_set_resources(device_t dev) { - u32 nodeid, link; - int i; + unsigned nodeid; + struct bus *bus; + struct resource *res; /* Find the nodeid */ nodeid = amdfam10_nodeid(dev); @@ -609,26 +595,17 @@ static void amdfam10_set_resources(device_t dev) amdfam10_create_vga_resource(dev, nodeid); /* Set each resource we have found */ - for(i = 0; i < dev->resources; i++) { - amdfam10_set_resource(dev, &dev->resource[i], nodeid); + for(res = dev->resource_list; res; res = res->next) { + amdfam10_set_resource(dev, res, nodeid); } - for(link = 0; link < dev->links; link++) { - struct bus *bus; - bus = &dev->link[link]; + for(bus = dev->link_list; bus; bus = bus->next) { if (bus->children) { assign_resources(bus); } } } - -static void amdfam10_enable_resources(device_t dev) -{ - pci_dev_enable_resources(dev); - enable_childrens_resources(dev); -} - static void mcf0_control_init(struct device *dev) { } @@ -636,7 +613,7 @@ static void mcf0_control_init(struct device *dev) static struct device_operations northbridge_operations = { .read_resources = amdfam10_read_resources, .set_resources = amdfam10_set_resources, - .enable_resources = amdfam10_enable_resources, + .enable_resources = pci_dev_enable_resources, .init = mcf0_control_init, .scan_bus = amdfam10_scan_chains, .enable = 0, @@ -644,26 +621,20 @@ static struct device_operations northbridge_operations = { }; -static struct pci_driver mcf0_driver __pci_driver = { +static const struct pci_driver mcf0_driver __pci_driver = { .ops = &northbridge_operations, .vendor = PCI_VENDOR_ID_AMD, .device = 0x1200, }; -#if CONFIG_CHIP_NAME == 1 - struct chip_operations northbridge_amd_amdfam10_ops = { CHIP_NAME("AMD FAM10 Northbridge") .enable_dev = 0, }; -#endif - -static void pci_domain_read_resources(device_t dev) +static void amdfam10_domain_read_resources(device_t dev) { - struct resource *resource; unsigned reg; - unsigned link; /* Find the already assigned resource pairs */ get_fx_devs(); @@ -673,21 +644,21 @@ static void pci_domain_read_resources(device_t dev) limit = f1_read_config32(reg + 0x04); /* Is this register allocated? */ if ((base & 3) != 0) { - unsigned nodeid, link; - device_t dev; + unsigned nodeid, reg_link; + device_t reg_dev; if(reg<0xc0) { // mmio nodeid = (limit & 0xf) + (base&0x30); } else { // io nodeid = (limit & 0xf) + ((base>>4)&0x30); } - link = (limit >> 4) & 7; - dev = __f0_dev[nodeid]; - if (dev) { - /* Reserve the resource */ - struct resource *resource; - resource = new_resource(dev, 0x1000 + reg + (link<<16)); - if (resource) { - resource->flags = 1; + reg_link = (limit >> 4) & 7; + reg_dev = __f0_dev[nodeid]; + if (reg_dev) { + /* Reserve the resource */ + struct resource *res; + res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link)); + if (res) { + res->flags = 1; } } } @@ -696,72 +667,38 @@ static void pci_domain_read_resources(device_t dev) I don't believe that much preset value */ #if CONFIG_PCI_64BIT_PREF_MEM == 0 - /* Initialize the system wide io space constraints */ - resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0)); - resource->base = 0x400; - resource->limit = 0xffffUL; - resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; - - /* Initialize the system wide memory resources constraints */ - resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0)); - resource->limit = 0xfcffffffffULL; - resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + pci_domain_read_resources(dev); #else - for(link=0; linklinks; link++) { + struct bus *link; + struct resource *resource; + for(link=dev->link_list; link; link = link->next) { /* Initialize the system wide io space constraints */ - resource = new_resource(dev, 0|(link<<2)); + resource = new_resource(dev, 0|(link->link_num<<2)); resource->base = 0x400; resource->limit = 0xffffUL; resource->flags = IORESOURCE_IO; - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_IO, IORESOURCE_IO); /* Initialize the system wide prefetchable memory resources constraints */ - resource = new_resource(dev, 1|(link<<2)); + resource = new_resource(dev, 1|(link->link_num<<2)); resource->limit = 0xfcffffffffULL; resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM | IORESOURCE_PREFETCH); /* Initialize the system wide memory resources constraints */ - resource = new_resource(dev, 2|(link<<2)); + resource = new_resource(dev, 2|(link->link_num<<2)); resource->limit = 0xfcffffffffULL; resource->flags = IORESOURCE_MEM; - compute_allocate_resource(&dev->link[link], resource, - IORESOURCE_MEM | IORESOURCE_PREFETCH, - IORESOURCE_MEM); } #endif +#if CONFIG_MMCONF_SUPPORT + struct resource *res = new_resource(dev, 0xc0010058); + res->base = CONFIG_MMCONF_BASE_ADDRESS; + res->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256; + res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +#endif } -static void ram_resource(device_t dev, unsigned long index, - resource_t basek, resource_t sizek) -{ - struct resource *resource; - - if (!sizek) { - return; - } - resource = new_resource(dev, index); - resource->base = basek << 10; - resource->size = sizek << 10; - resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ - IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; -} - -static void tolm_test(void *gp, struct device *dev, struct resource *new) -{ - struct resource **best_p = gp; - struct resource *best; - best = *best_p; - if (!best || (best->base > new->base)) { - best = new; - } - *best_p = best; -} - -static u32 find_pci_tolm(struct bus *bus, u32 tolm) +static u32 my_find_pci_tolm(struct bus *bus, u32 tolm) { struct resource *min; min = 0; @@ -772,11 +709,7 @@ static u32 find_pci_tolm(struct bus *bus, u32 tolm) return tolm; } -#if CONFIG_PCI_64BIT_PREF_MEM == 1 -#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH) -#endif - -#if HW_MEM_HOLE_SIZEK != 0 +#if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info { unsigned hole_startk; @@ -788,7 +721,7 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void) struct hw_mem_hole_info mem_hole; int i; - mem_hole.hole_startk = HW_MEM_HOLE_SIZEK; + mem_hole.hole_startk = CONFIG_HW_MEM_HOLE_SIZEK; mem_hole.node_id = -1; for (i = 0; i < sysconf.nodes; i++) { @@ -829,11 +762,12 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void) return mem_hole; } - +// WHY this check? CONFIG_AMDMCT is enabled on all Fam10 boards. +// Does it make sense not to? #if CONFIG_AMDMCT == 0 -static void disable_hoist_memory(unsigned long hole_startk, int i) +static void disable_hoist_memory(unsigned long hole_startk, int node_id) { - int ii; + int i; device_t dev; struct dram_base_mask_t d; u32 sel_m; @@ -842,9 +776,9 @@ static void disable_hoist_memory(unsigned long hole_startk, int i) u32 hole_sizek; u32 one_DCT; - struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM + struct sys_info *sysinfox = (struct sys_info *)((CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM struct mem_info *meminfo; - meminfo = &sysinfox->meminfo[i]; + meminfo = &sysinfox->meminfo[node_id]; one_DCT = get_one_DCT(meminfo); @@ -857,54 +791,52 @@ static void disable_hoist_memory(unsigned long hole_startk, int i) hole_sizek = (4*1024*1024) - hole_startk; - for(ii=NODE_NUMS-1;ii>i;ii--) { + for(i=NODE_NUMS-1;i>node_id;i--) { - d = get_dram_base_mask(ii); + d = get_dram_base_mask(i); if(!(d.mask & 1)) continue; d.base -= (hole_sizek>>9); d.mask -= (hole_sizek>>9); - set_dram_base_mask(ii, d, sysconf.nodes); + set_dram_base_mask(i, d, sysconf.nodes); - if(get_DctSelHiEn(ii) & 1) { - sel_m = get_DctSelBaseAddr(ii); + if(get_DctSelHiEn(i) & 1) { + sel_m = get_DctSelBaseAddr(i); sel_m -= hole_startk>>10; - set_DctSelBaseAddr(ii, sel_m); + set_DctSelBaseAddr(i, sel_m); } } - d = get_dram_base_mask(i); - dev = __f1_dev[i]; - hoist = pci_read_config32(dev, 0xf0); - sel_hi_en = get_DctSelHiEn(i); + d = get_dram_base_mask(node_id); + dev = __f1_dev[node_id]; + sel_hi_en = get_DctSelHiEn(node_id); if(sel_hi_en & 1) { - sel_m = get_DctSelBaseAddr(i); + sel_m = get_DctSelBaseAddr(node_id); } - + hoist = pci_read_config32(dev, 0xf0); if(hoist & 1) { pci_write_config32(dev, 0xf0, 0); d.mask -= (hole_sizek>>9); - set_dram_base_mask(i, d, sysconf.nodes); + set_dram_base_mask(node_id, d, sysconf.nodes); if(one_DCT || (sel_m >= (hole_startk>>10))) { if(sel_hi_en & 1) { sel_m -= hole_startk>>10; - set_DctSelBaseAddr(i, sel_m); + set_DctSelBaseAddr(node_id, sel_m); } } if(sel_hi_en & 1) { - set_DctSelBaseOffset(i, 0); + set_DctSelBaseOffset(node_id, 0); } - } - else { + } else { d.base -= (hole_sizek>>9); d.mask -= (hole_sizek>>9); - set_dram_base_mask(i, d, sysconf.nodes); + set_dram_base_mask(node_id, d, sysconf.nodes); if(sel_hi_en & 1) { sel_m -= hole_startk>>10; - set_DctSelBaseAddr(i, sel_m); + set_DctSelBaseAddr(node_id, sel_m); } } @@ -913,33 +845,53 @@ static void disable_hoist_memory(unsigned long hole_startk, int i) #endif -static void pci_domain_set_resources(device_t dev) +#if CONFIG_WRITE_HIGH_TABLES==1 +#include +#endif + +#if CONFIG_GFXUMA == 1 +extern uint64_t uma_memory_base, uma_memory_size; + +static void add_uma_resource(struct device *dev, int index) +{ + struct resource *resource; + + printk(BIOS_DEBUG, "Adding UMA memory area\n"); + resource = new_resource(dev, index); + resource->base = (resource_t) uma_memory_base; + resource->size = (resource_t) uma_memory_size; + resource->flags = IORESOURCE_MEM | IORESOURCE_RESERVE | + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} +#endif + +static void amdfam10_domain_set_resources(device_t dev) { #if CONFIG_PCI_64BIT_PREF_MEM == 1 struct resource *io, *mem1, *mem2; - struct resource *resource, *last; + struct resource *res; #endif unsigned long mmio_basek; u32 pci_tolm; int i, idx; - u32 link; -#if HW_MEM_HOLE_SIZEK != 0 + struct bus *link; +#if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info mem_hole; u32 reset_memhole = 1; #endif #if CONFIG_PCI_64BIT_PREF_MEM == 1 - for(link=0; linklinks; link++) { + for(link = dev->link_list; link; link = link->next) { /* Now reallocate the pci resources memory with the * highest addresses I can manage. */ - mem1 = find_resource(dev, 1|(link<<2)); - mem2 = find_resource(dev, 2|(link<<2)); + mem1 = find_resource(dev, 1|(link->link_num<<2)); + mem2 = find_resource(dev, 2|(link->link_num<<2)); - printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n", + printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n", mem1->base, mem1->limit, mem1->size, mem1->align); - printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n", + printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n", mem2->base, mem2->limit, mem2->size, mem2->align); /* See if both resources have roughly the same limits */ @@ -965,42 +917,37 @@ static void pci_domain_set_resources(device_t dev) mem1->base = resource_max(mem1); } - printk_debug("base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n", + printk(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n", mem1->base, mem1->limit, mem1->size, mem1->align); - printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n", + printk(BIOS_DEBUG, "base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx align: %d\n", mem2->base, mem2->limit, mem2->size, mem2->align); } - last = &dev->resource[dev->resources]; - for(resource = &dev->resource[0]; resource < last; resource++) + for(res = &dev->resource_list; res; res = res->next) { - resource->flags |= IORESOURCE_ASSIGNED; - resource->flags &= ~IORESOURCE_STORED; - link = (resource>>2) & 3; - compute_allocate_resource(&dev->link[link], resource, - BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK); - - resource->flags |= IORESOURCE_STORED; - report_resource_stored(dev, resource, ""); - + res->flags |= IORESOURCE_ASSIGNED; + res->flags |= IORESOURCE_STORED; + report_resource_stored(dev, res, ""); } #endif pci_tolm = 0xffffffffUL; - for(link=0;linklinks; link++) { - pci_tolm = find_pci_tolm(&dev->link[link], pci_tolm); + for(link = dev->link_list; link; link = link->next) { + pci_tolm = my_find_pci_tolm(link, pci_tolm); } -#warning "FIXME handle interleaved nodes" + // FIXME handle interleaved nodes. If you fix this here, please fix + // amdk8, too. mmio_basek = pci_tolm >> 10; /* Round mmio_basek to something the processor can support */ mmio_basek &= ~((1 << 6) -1); -#warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole" - /* Round the mmio hold to 64M */ + // FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M + // MMIO hole. If you fix this here, please fix amdk8, too. + /* Round the mmio hole to 64M */ mmio_basek &= ~((64*1024) - 1); -#if HW_MEM_HOLE_SIZEK != 0 +#if CONFIG_HW_MEM_HOLE_SIZEK != 0 /* if the hw mem hole is already set in raminit stage, here we will compare * mmio_basek and hole_basek. if mmio_basek is bigger that hole_basek and will * use hole_basek as mmio_basek and we don't need to reset hole. @@ -1020,7 +967,7 @@ static void pci_domain_set_resources(device_t dev) if(reset_memhole) { if(mem_hole.node_id!=-1) { - /* We need to select HW_MEM_HOLE_SIZEK for raminit, it can not + /* We need to select CONFIG_HW_MEM_HOLE_SIZEK for raminit, it can not make hole_startk to some basek too! We need to reset our Mem Hole, because We want more big HOLE than we already set @@ -1030,7 +977,7 @@ static void pci_domain_set_resources(device_t dev) disable_hoist_memory(mem_hole.hole_startk, mem_hole.node_id); } - #if HW_MEM_HOLE_SIZE_AUTO_INC == 1 + #if CONFIG_HW_MEM_HOLE_SIZE_AUTO_INC == 1 // We need to double check if the mmio_basek is valid for hole // setting, if it is equal to basek, we need to decrease it some resource_t basek_pri; @@ -1075,7 +1022,7 @@ static void pci_domain_set_resources(device_t dev) } -// printk_debug("node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk); +// printk(BIOS_DEBUG, "node %d : mmio_basek=%08x, basek=%08x, limitk=%08x\n", i, mmio_basek, basek, limitk); /* split the region to accomodate pci memory space */ if ( (basek < 4*1024*1024 ) && (limitk > mmio_basek) ) { @@ -1086,11 +1033,24 @@ static void pci_domain_set_resources(device_t dev) ram_resource(dev, (idx | i), basek, pre_sizek); idx += 0x10; sizek -= pre_sizek; +#if CONFIG_WRITE_HIGH_TABLES==1 + if (high_tables_base==0) { + /* Leave some space for ACPI, PIRQ and MP tables */ +#if CONFIG_GFXUMA == 1 + high_tables_base = uma_memory_base - HIGH_MEMORY_SIZE; +#else + high_tables_base = (mmio_basek * 1024) - HIGH_MEMORY_SIZE; +#endif + high_tables_size = HIGH_MEMORY_SIZE; + printk(BIOS_DEBUG, " split: %dK table at =%08llx\n", + HIGH_MEMORY_SIZE / 1024, high_tables_base); + } +#endif } #if CONFIG_AMDMCT == 0 - #if HW_MEM_HOLE_SIZEK != 0 + #if CONFIG_HW_MEM_HOLE_SIZEK != 0 if(reset_memhole) { - struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM + struct sys_info *sysinfox = (struct sys_info *)((CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); // in RAM struct mem_info *meminfo; meminfo = &sysinfox->meminfo[i]; sizek += hoist_memory(mmio_basek,i, get_one_DCT(meminfo), sysconf.nodes); @@ -1108,28 +1068,50 @@ static void pci_domain_set_resources(device_t dev) sizek -= (4*1024*1024 - mmio_basek); } } + +#if CONFIG_GFXUMA == 1 + /* Deduct uma memory before reporting because + * this is what the mtrr code expects */ + sizek -= uma_memory_size / 1024; +#endif ram_resource(dev, (idx | i), basek, sizek); idx += 0x10; +#if CONFIG_WRITE_HIGH_TABLES==1 + printk(BIOS_DEBUG, "%d: mmio_basek=%08lx, basek=%08llx, limitk=%08llx\n", + i, mmio_basek, basek, limitk); + if (high_tables_base==0) { + /* Leave some space for ACPI, PIRQ and MP tables */ +#if CONFIG_GFXUMA == 1 + high_tables_base = uma_memory_base - HIGH_MEMORY_SIZE; +#else + high_tables_base = (limitk * 1024) - HIGH_MEMORY_SIZE; +#endif + high_tables_size = HIGH_MEMORY_SIZE; + } +#endif } - for(link = 0; link < dev->links; link++) { - struct bus *bus; - bus = &dev->link[link]; - if (bus->children) { - assign_resources(bus); +#if CONFIG_GFXUMA == 1 + add_uma_resource(dev, 7); +#endif + + for(link = dev->link_list; link; link = link->next) { + if (link->children) { + assign_resources(link); } } } -static u32 pci_domain_scan_bus(device_t dev, u32 max) +static u32 amdfam10_domain_scan_bus(device_t dev, u32 max) { u32 reg; int i; + struct bus *link; /* Unmap all of the HT chains */ for(reg = 0xe0; reg <= 0xec; reg += 4) { f1_write_config32(reg, 0); } -#if EXT_CONF_SUPPORT == 1 +#if CONFIG_EXT_CONF_SUPPORT == 1 // all nodes for(i = 0; i< sysconf.nodes; i++) { int index; @@ -1142,27 +1124,27 @@ static u32 pci_domain_scan_bus(device_t dev, u32 max) #endif - for(i=0;ilinks;i++) { - max = pci_scan_bus(&dev->link[i], PCI_DEVFN(CDB, 0), 0xff, max); + for(link = dev->link_list; link; link = link->next) { + max = pci_scan_bus(link, PCI_DEVFN(CONFIG_CDB, 0), 0xff, max); } /* Tune the hypertransport transaction for best performance. * Including enabling relaxed ordering if it is safe. */ get_fx_devs(); - for(i = 0; i < FX_DEVS; i++) { + for(i = 0; i < fx_devs; i++) { device_t f0_dev; f0_dev = __f0_dev[i]; if (f0_dev && f0_dev->enabled) { u32 httc; httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL); httc &= ~HTTC_RSP_PASS_PW; - if (!dev->link[0].disable_relaxed_ordering) { + if (!dev->link_list->disable_relaxed_ordering) { httc |= HTTC_RSP_PASS_PW; } - printk_spew("%s passpw: %s\n", + printk(BIOS_SPEW, "%s passpw: %s\n", dev_path(dev), - (!dev->link[0].disable_relaxed_ordering)? + (!dev->link_list->disable_relaxed_ordering)? "enabled":"disabled"); pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc); } @@ -1171,12 +1153,12 @@ static u32 pci_domain_scan_bus(device_t dev, u32 max) } static struct device_operations pci_domain_ops = { - .read_resources = pci_domain_read_resources, - .set_resources = pci_domain_set_resources, - .enable_resources = enable_childrens_resources, - .init = 0, - .scan_bus = pci_domain_scan_bus, -#if MMCONF_SUPPORT_DEFAULT + .read_resources = amdfam10_domain_read_resources, + .set_resources = amdfam10_domain_set_resources, + .enable_resources = NULL, + .init = NULL, + .scan_bus = amdfam10_domain_scan_bus, +#if CONFIG_MMCONF_SUPPORT_DEFAULT .ops_pci_bus = &pci_ops_mmconf, #else .ops_pci_bus = &pci_cf8_conf1, @@ -1207,31 +1189,67 @@ static void sysconf_init(device_t dev) // first node sysconf.bsp_apicid = lapicid(); sysconf.apicid_offset = sysconf.bsp_apicid; -#if (ENABLE_APIC_EXT_ID == 1) +#if (CONFIG_ENABLE_APIC_EXT_ID == 1) if (pci_read_config32(dev, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST)) { sysconf.enabled_apic_ext_id = 1; } - #if (APIC_ID_OFFSET>0) + #if (CONFIG_APIC_ID_OFFSET>0) if(sysconf.enabled_apic_ext_id) { if(sysconf.bsp_apicid == 0) { /* bsp apic id is not changed */ - sysconf.apicid_offset = APIC_ID_OFFSET; + sysconf.apicid_offset = CONFIG_APIC_ID_OFFSET; } else { sysconf.lift_bsp_apicid = 1; } - } #endif #endif +} + +static void add_more_links(device_t dev, unsigned total_links) +{ + struct bus *link, *last = NULL; + int link_num; + + for (link = dev->link_list; link; link = link->next) + last = link; + + if (last) { + int links = total_links - last->link_num; + link_num = last->link_num; + if (links > 0) { + link = malloc(links*sizeof(*link)); + if (!link) + die("Couldn't allocate more links!\n"); + memset(link, 0, links*sizeof(*link)); + last->next = link; + } + } + else { + link_num = -1; + link = malloc(total_links*sizeof(*link)); + memset(link, 0, total_links*sizeof(*link)); + dev->link_list = link; + } + for (link_num = link_num + 1; link_num < total_links; link_num++) { + link->link_num = link_num; + link->dev = dev; + link->next = link + 1; + last = link; + link = link->next; + } + last->next = NULL; } static u32 cpu_bus_scan(device_t dev, u32 max) { struct bus *cpu_bus; device_t dev_mc; +#if CONFIG_CBB device_t pci_domain; +#endif int i,j; int nodes; unsigned nb_cfg_54; @@ -1250,47 +1268,42 @@ static u32 cpu_bus_scan(device_t dev, u32 max) disable_siblings = !CONFIG_LOGICAL_CPUS; #if CONFIG_LOGICAL_CPUS == 1 - get_option(&disable_siblings, "quad_core"); + get_option(&disable_siblings, "multi_core"); #endif - // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it - // still be 0) - // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp??? - // and differ d0 and e0 single core - + // How can I get the nb_cfg_54 of every node's nb_cfg_54 in bsp??? nb_cfg_54 = read_nb_cfg_54(); -#if CBB - dev_mc = dev_find_slot(0, PCI_DEVFN(CDB, 0)); //0x00 +#if CONFIG_CBB + dev_mc = dev_find_slot(0, PCI_DEVFN(CONFIG_CDB, 0)); //0x00 if(dev_mc && dev_mc->bus) { - printk_debug("%s found", dev_path(dev_mc)); + printk(BIOS_DEBUG, "%s found", dev_path(dev_mc)); pci_domain = dev_mc->bus->dev; if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) { - printk_debug("\n%s move to ",dev_path(dev_mc)); - dev_mc->bus->secondary = CBB; // move to 0xff - printk_debug("%s",dev_path(dev_mc)); + printk(BIOS_DEBUG, "\n%s move to ",dev_path(dev_mc)); + dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff + printk(BIOS_DEBUG, "%s",dev_path(dev_mc)); } else { - printk_debug(" but it is not under pci_domain directly "); + printk(BIOS_DEBUG, " but it is not under pci_domain directly "); } - printk_debug("\n"); - + printk(BIOS_DEBUG, "\n"); } - dev_mc = dev_find_slot(CBB, PCI_DEVFN(CDB, 0)); + dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0)); if(!dev_mc) { dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0)); if (dev_mc && dev_mc->bus) { - printk_debug("%s found\n", dev_path(dev_mc)); + printk(BIOS_DEBUG, "%s found\n", dev_path(dev_mc)); pci_domain = dev_mc->bus->dev; if(pci_domain && (pci_domain->path.type == DEVICE_PATH_PCI_DOMAIN)) { - if((pci_domain->links==1) && (pci_domain->link[0].children == dev_mc)) { - printk_debug("%s move to ",dev_path(dev_mc)); - dev_mc->bus->secondary = CBB; // move to 0xff - printk_debug("%s\n",dev_path(dev_mc)); + if((pci_domain->link_list) && (pci_domain->link_list->children == dev_mc)) { + printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc)); + dev_mc->bus->secondary = CONFIG_CBB; // move to 0xff + printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc)); while(dev_mc){ - printk_debug("%s move to ",dev_path(dev_mc)); + printk(BIOS_DEBUG, "%s move to ",dev_path(dev_mc)); dev_mc->path.pci.devfn -= PCI_DEVFN(0x18,0); - printk_debug("%s\n",dev_path(dev_mc)); + printk(BIOS_DEBUG, "%s\n",dev_path(dev_mc)); dev_mc = dev_mc->sibling; } } @@ -1300,9 +1313,9 @@ static u32 cpu_bus_scan(device_t dev, u32 max) #endif - dev_mc = dev_find_slot(CBB, PCI_DEVFN(CDB, 0)); + dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0)); if (!dev_mc) { - printk_err("%02x:%02x.0 not found", CBB, CDB); + printk(BIOS_ERR, "%02x:%02x.0 not found", CONFIG_CBB, CONFIG_CDB); die(""); } @@ -1310,77 +1323,72 @@ static u32 cpu_bus_scan(device_t dev, u32 max) nodes = sysconf.nodes; -#if CBB && (NODE_NUMS > 32) +#if CONFIG_CBB && (NODE_NUMS > 32) if(nodes>32) { // need to put node 32 to node 63 to bus 0xfe - if(pci_domain->links==1) { - pci_domain->links++; // from 1 to 2 - pci_domain->link[1].link = 1; - pci_domain->link[1].dev = pci_domain; - pci_domain->link[1].children = 0; - printk_debug("%s links increase to %d\n", dev_path(pci_domain), pci_domain->links); + if(pci_domain->link_list && !pci_domain->link_list->next) { + struct bus *new_link = new_link(pci_domain); + pci_domain->link_list->next = new_link; + new_link->link_num = 1; + new_link->dev = pci_domain; + new_link->children = 0; + printk(BIOS_DEBUG, "%s links now 2\n", dev_path(pci_domain)); } - pci_domain->link[1].secondary = CBB - 1; + pci_domain->link_list->next->secondary = CONFIG_CBB - 1; } #endif /* Find which cpus are present */ - cpu_bus = &dev->link[0]; + cpu_bus = dev->link_list; for(i = 0; i < nodes; i++) { - device_t dev, cpu; + device_t cdb_dev, cpu; struct device_path cpu_path; unsigned busn, devn; struct bus *pbus; - busn = CBB; - devn = CDB+i; + busn = CONFIG_CBB; + devn = CONFIG_CDB+i; pbus = dev_mc->bus; -#if CBB && (NODE_NUMS > 32) +#if CONFIG_CBB && (NODE_NUMS > 32) if(i>=32) { busn--; devn-=32; - pbus = &(pci_domain->link[1]); + pbus = pci_domain->link_list->next); } #endif /* Find the cpu's pci device */ - dev = dev_find_slot(busn, PCI_DEVFN(devn, 0)); - if (!dev) { + cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0)); + if (!cdb_dev) { /* If I am probing things in a weird order * ensure all of the cpu's pci devices are found. */ - int j; - for(j = 0; j <= 5; j++) { //FBDIMM? - dev = pci_probe_dev(NULL, pbus, - PCI_DEVFN(devn, j)); + int fn; + for(fn = 0; fn <= 5; fn++) { //FBDIMM? + cdb_dev = pci_probe_dev(NULL, pbus, + PCI_DEVFN(devn, fn)); } - dev = dev_find_slot(busn, PCI_DEVFN(devn,0)); + cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0)); } - if(dev) { + if (cdb_dev) { /* Ok, We need to set the links for that device. * otherwise the device under it will not be scanned */ - int j; int linknum; -#if HT3_SUPPORT==1 +#if CONFIG_HT3_SUPPORT==1 linknum = 8; #else linknum = 4; #endif - if(dev->links < linknum) { - for(j=dev->links; jlink[j].link = j; - dev->link[j].dev = dev; - } - dev->links = linknum; - printk_debug("%s links increase to %d\n", dev_path(dev), dev->links); - } + add_more_links(cdb_dev, linknum); } cores_found = 0; // one core - dev = dev_find_slot(busn, PCI_DEVFN(devn, 3)); - if (dev && dev->enabled) { - j = pci_read_config32(dev, 0xe8); + cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 3)); + if (cdb_dev && cdb_dev->enabled) { + j = pci_read_config32(cdb_dev, 0xe8); cores_found = (j >> 12) & 3; // dev is func 3 - printk_debug(" %s siblings=%d\n", dev_path(dev), cores_found); + if (siblings > 3) + cores_found |= (j >> 13) & 4; + printk(BIOS_DEBUG, " %s siblings=%d\n", dev_path(cdb_dev), cores_found); } u32 jj; @@ -1401,7 +1409,7 @@ static u32 cpu_bus_scan(device_t dev, u32 max) cpu = find_dev_path(cpu_bus, &cpu_path); /* Enable the cpu if I have the processor */ - if (dev && dev->enabled) { + if (cdb_dev && cdb_dev->enabled) { if (!cpu) { cpu = alloc_dev(cpu_bus, &cpu_path); } @@ -1411,7 +1419,7 @@ static u32 cpu_bus_scan(device_t dev, u32 max) } /* Disable the cpu if I don't have the processor */ - if (cpu && (!dev || !dev->enabled)) { + if (cpu && (!cdb_dev || !cdb_dev->enabled)) { cpu->enabled = 0; } @@ -1419,18 +1427,18 @@ static u32 cpu_bus_scan(device_t dev, u32 max) if (cpu) { cpu->path.apic.node_id = i; cpu->path.apic.core_id = j; - #if (ENABLE_APIC_EXT_ID == 1) && (APIC_ID_OFFSET>0) - if(sysconf.enabled_apic_ext_id) { + #if (CONFIG_ENABLE_APIC_EXT_ID == 1) && (CONFIG_APIC_ID_OFFSET>0) + if(sysconf.enabled_apic_ext_id) { if(sysconf.lift_bsp_apicid) { cpu->path.apic.apic_id += sysconf.apicid_offset; } else { if (cpu->path.apic.apic_id != 0) cpu->path.apic.apic_id += sysconf.apicid_offset; - } + } } #endif - printk_debug("CPU: %s %s\n", + printk(BIOS_DEBUG, "CPU: %s %s\n", dev_path(cpu), cpu->enabled?"enabled":"disabled"); } @@ -1439,27 +1447,40 @@ static u32 cpu_bus_scan(device_t dev, u32 max) return max; } - static void cpu_bus_init(device_t dev) { - initialize_cpus(&dev->link[0]); + initialize_cpus(dev->link_list); +#if CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 || CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 + sb_After_Pci_Init(); + sb_Mid_Post_Init(); +#endif } - static void cpu_bus_noop(device_t dev) { } +static void cpu_bus_read_resources(device_t dev) +{ +} + +static void cpu_bus_set_resources(device_t dev) +{ + struct resource *resource = find_resource(dev, 0xc0010058); + if (resource) { + report_resource_stored(dev, resource, " "); + } + pci_dev_set_resources(dev); +} static struct device_operations cpu_bus_ops = { - .read_resources = cpu_bus_noop, - .set_resources = cpu_bus_noop, + .read_resources = cpu_bus_read_resources, + .set_resources = cpu_bus_set_resources, .enable_resources = cpu_bus_noop, .init = cpu_bus_init, .scan_bus = cpu_bus_scan, }; - static void root_complex_enable_dev(struct device *dev) { /* Set the operations if it is a special bus type */