X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnorthbridge%2Famd%2Famdfam10%2Fnorthbridge.c;h=2d0f3c8836519de18379ebf72285feadc863f825;hb=e16bee4a7c7723b45d72de29aea496a23fa32028;hp=3d968a9dedbfbfa249abbe994e7315bd0809909a;hpb=29ceae2c370fcd5a7c159771050611f03de006ba;p=coreboot.git diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index 3d968a9de..2d0f3c883 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -47,6 +47,11 @@ #endif #include +#if CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 +#include +#elif CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 +#include +#endif struct amdfam10_sysconf_t sysconf; @@ -55,6 +60,7 @@ 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) { @@ -68,37 +74,37 @@ device_t get_node_pci(u32 nodeid, u32 fn) #else 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(BIOS_ERR, "Cannot find %02x:%02x.1", CONFIG_CBB, CONFIG_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,7 +113,6 @@ static void f1_write_config32(u32 reg, u32 value) } } - static u32 amdfam10_nodeid(device_t dev) { #if NODE_NUMS == 64 @@ -124,7 +129,7 @@ static u32 amdfam10_nodeid(device_t dev) #endif } -#include "amdfam10_conf.c" +#include "conf.c" static void set_vga_enable_reg(u32 nodeid, u32 linkn) { @@ -137,11 +142,12 @@ 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? + printk(BIOS_INFO, "%s: starting...\n", __func__); u32 link_type; int i; @@ -149,7 +155,7 @@ 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; @@ -162,7 +168,7 @@ static u32 amdfam10_scan_chain(device_t dev, u32 nodeid, u32 link, u32 sblink, 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); @@ -171,15 +177,17 @@ 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); + printk(BIOS_INFO, "%s: link_type: 0x%08x\n", __func__, link_type); } 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); + printk(BIOS_INFO, "%s: link_type: 0x%08x\n", __func__, link_type); } while(!(link_type & InitComplete)); if (!(link_type & NonCoherent)) { return max; @@ -187,7 +195,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); + printk(BIOS_INFO, "%s: before get_ht_c_index\n", __func__); + ht_c_index = get_ht_c_index(nodeid, link_num, &sysconf); + printk(BIOS_INFO, "%s: after get_ht_c_index\n", __func__); #if CONFIG_EXT_CONF_SUPPORT == 0 if(ht_c_index>=4) return max; @@ -197,11 +207,10 @@ 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 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 CONFIG_SB_HT_CHAIN_ON_BUS0 > 1 // second chain will be on 0x40, third 0x80, forth 0xc0 @@ -211,36 +220,39 @@ 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); + printk(BIOS_INFO, "%s: before set_config_map_reg\n", __func__); + set_config_map_reg(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, sysconf.segbit, sysconf.nodes); + printk(BIOS_INFO, "%s: after set_config_map_reg\n", __func__); /* Now we can scan all of the subordinate busses i.e. the * chain on the hypertranport link @@ -255,22 +267,28 @@ 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); - + printk(BIOS_INFO, "%s: before hypertransport_scan_chain\n", __func__); + /* HERE. ZOMG */ + max = hypertransport_scan_chain(link, 0, max_devfn, max, ht_unitid_base, offset_unitid); + printk(BIOS_INFO, "%s: after hypertransport_scan_chain\n", __func__); /* 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); + printk(BIOS_INFO, "%s: before clear_config_map_reg\n", __func__); + clear_config_map_reg(nodeid, link_num, ht_c_index, (max+1)>>sysconf.segbit, (link->subordinate)>>sysconf.segbit, sysconf.nodes); + printk(BIOS_INFO, "%s: after clear_config_map_reg\n", __func__); } - 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; + printk(BIOS_INFO, "%s: before set_config_map_reg\n", __func__); + set_config_map_reg(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, sysconf.segbit, sysconf.nodes); + printk(BIOS_INFO, "%s: after set_config_map_reg\n", __func__); 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); @@ -279,22 +297,23 @@ 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); - - + printk(BIOS_INFO, "%s: before store_ht_c_conf_bus\n", __func__); + store_ht_c_conf_bus(nodeid, link_num, ht_c_index, link->secondary, link->subordinate, &sysconf); + printk(BIOS_INFO, "%s: after store_ht_c_conf_bus\n", __func__); + printk(BIOS_INFO, "%s: done.\n", __func__); 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); + printk(BIOS_INFO, "%s: starting...\n", __func__); + nodeid = amdfam10_nodeid(dev); // Put sb chain in bus 0 #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0 @@ -302,42 +321,46 @@ static u32 amdfam10_scan_chains(device_t dev, u32 max) #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) { + printk(BIOS_INFO, "%s: link: %p\n", __func__, link); + 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 CONFIG_PCI_BUS_SEGN_BITS max = check_segn(dev, max, sysconf.nodes, &sysconf); #endif - - for(link = 0; link < dev->links; link++) { + for(link = dev->link_list; link; link = link->next) { + printk(BIOS_INFO, "%s: link2: %p\n", __func__, link); #if CONFIG_SB_HT_CHAIN_ON_BUS0 > 0 - if( (nodeid == 0) && (sblink == link) ) continue; //already done + if( (nodeid == 0) && (sblink == link->link_num) ) continue; //already done #endif offset_unitid = 0; #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)) + 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); } + printk(BIOS_INFO, "%s: done.\n", __func__); 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 = 0; + 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) @@ -358,7 +381,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; @@ -433,7 +456,7 @@ 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 CONFIG_EXT_CONF_SUPPORT == 1 @@ -454,12 +477,13 @@ static void amdfam10_link_read_bases(device_t dev, u32 nodeid, u32 link) /* 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 | IORESOURCE_BRIDGE; + resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; + resource->flags |= IORESOURCE_BRIDGE; #if CONFIG_EXT_CONF_SUPPORT == 1 if((resource->index & 0x1fff) == 0x1110) { // ext @@ -472,41 +496,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 | 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 */ @@ -535,46 +555,43 @@ static void amdfam10_set_resource(device_t dev, struct resource *resource, /* Get the register and link */ reg = resource->index & 0xfff; // 4k - link = IOINDEX_LINK(resource->index); + link_num = IOINDEX_LINK(resource->index); if (resource->flags & 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) { - 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(BIOS_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; @@ -582,17 +599,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(BIOS_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); @@ -600,26 +618,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) { } @@ -627,7 +636,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, @@ -665,14 +674,14 @@ static void amdfam10_domain_read_resources(device_t dev) } else { // io nodeid = (limit & 0xf) + ((base>>4)&0x30); } - reg_link = (limit >> 4) & 7; + reg_link = (limit >> 4) & 7; reg_dev = __f0_dev[nodeid]; if (reg_dev) { /* Reserve the resource */ - struct resource *reg_resource; - reg_resource = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link)); - if (reg_resource) { - reg_resource->flags = 1; + struct resource *res; + res = new_resource(reg_dev, IOINDEX(0x1000 + reg, reg_link)); + if (res) { + res->flags = 1; } } } @@ -683,55 +692,36 @@ static void amdfam10_domain_read_resources(device_t dev) #if CONFIG_PCI_64BIT_PREF_MEM == 0 pci_domain_read_resources(dev); #else - unsigned link; + struct bus *link; struct resource *resource; - for(link=0; linklinks; link++) { + 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; /* 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; /* 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; } #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; @@ -798,9 +788,9 @@ static struct hw_mem_hole_info get_hw_mem_hole_info(void) // 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; @@ -811,7 +801,7 @@ static void disable_hoist_memory(unsigned long hole_startk, int i) u32 one_DCT; 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); @@ -824,54 +814,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); } } @@ -881,20 +869,35 @@ static void disable_hoist_memory(unsigned long hole_startk, int i) #endif #if CONFIG_WRITE_HIGH_TABLES==1 -#define HIGH_TABLES_SIZE 64 // maximum size of high tables in KB -extern uint64_t high_tables_base, high_tables_size; +#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 pci_domain_set_resources(device_t dev) +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; + struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info mem_hole; u32 reset_memhole = 1; @@ -902,12 +905,12 @@ static void pci_domain_set_resources(device_t dev) #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(BIOS_DEBUG, "base1: 0x%08Lx limit1: 0x%08Lx size: 0x%08Lx align: %d\n", mem1->base, mem1->limit, mem1->size, mem1->align); @@ -943,21 +946,17 @@ static void pci_domain_set_resources(device_t dev) 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; - 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); } // FIXME handle interleaved nodes. If you fix this here, please fix @@ -968,7 +967,7 @@ static void pci_domain_set_resources(device_t dev) // 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 hold to 64M */ + /* Round the mmio hole to 64M */ mmio_basek &= ~((64*1024) - 1); #if CONFIG_HW_MEM_HOLE_SIZEK != 0 @@ -1058,12 +1057,16 @@ static void pci_domain_set_resources(device_t dev) idx += 0x10; sizek -= pre_sizek; #if CONFIG_WRITE_HIGH_TABLES==1 - if (i==0 && high_tables_base==0) { + if (high_tables_base==0) { /* Leave some space for ACPI, PIRQ and MP tables */ - high_tables_base = (mmio_basek - HIGH_TABLES_SIZE) * 1024; - high_tables_size = HIGH_TABLES_SIZE * 1024; - printk(BIOS_DEBUG, "(split)%xK table at =%08llx\n", HIGH_TABLES_SIZE, - high_tables_base); +#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 } @@ -1088,24 +1091,36 @@ 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 (i==0 && high_tables_base==0) { + if (high_tables_base==0) { /* Leave some space for ACPI, PIRQ and MP tables */ - high_tables_base = (limitk - HIGH_TABLES_SIZE) * 1024; - high_tables_size = HIGH_TABLES_SIZE * 1024; +#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); } } } @@ -1114,6 +1129,7 @@ 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); @@ -1131,27 +1147,27 @@ static u32 amdfam10_domain_scan_bus(device_t dev, u32 max) #endif - for(i=0;ilinks;i++) { - max = pci_scan_bus(&dev->link[i], PCI_DEVFN(CONFIG_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(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); } @@ -1161,9 +1177,9 @@ static u32 amdfam10_domain_scan_bus(device_t dev, u32 max) static struct device_operations pci_domain_ops = { .read_resources = amdfam10_domain_read_resources, - .set_resources = pci_domain_set_resources, - .enable_resources = enable_childrens_resources, - .init = 0, + .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, @@ -1209,11 +1225,45 @@ static void sysconf_init(device_t dev) // first node } 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) @@ -1231,6 +1281,7 @@ static u32 cpu_bus_scan(device_t dev, u32 max) int disable_siblings; unsigned ApicIdCoreIdSize; + printk(BIOS_INFO, "%s: starting...\n", __func__); nb_cfg_54 = 0; ApicIdCoreIdSize = (cpuid_ecx(0x80000008)>>12 & 0xf); if(ApicIdCoreIdSize) { @@ -1244,11 +1295,7 @@ static u32 cpu_bus_scan(device_t dev, u32 max) 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 CONFIG_CBB @@ -1265,7 +1312,6 @@ static u32 cpu_bus_scan(device_t dev, u32 max) printk(BIOS_DEBUG, " but it is not under pci_domain directly "); } printk(BIOS_DEBUG, "\n"); - } dev_mc = dev_find_slot(CONFIG_CBB, PCI_DEVFN(CONFIG_CDB, 0)); if(!dev_mc) { @@ -1274,7 +1320,7 @@ static u32 cpu_bus_scan(device_t dev, u32 max) 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)) { + 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)); @@ -1303,18 +1349,19 @@ static u32 cpu_bus_scan(device_t dev, u32 max) #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(BIOS_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 = CONFIG_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 cdb_dev, cpu; struct device_path cpu_path; @@ -1328,7 +1375,7 @@ static u32 cpu_bus_scan(device_t dev, u32 max) if(i>=32) { busn--; devn-=32; - pbus = &(pci_domain->link[1]); + pbus = pci_domain->link_list->next); } #endif @@ -1343,27 +1390,19 @@ static u32 cpu_bus_scan(device_t dev, u32 max) cdb_dev = pci_probe_dev(NULL, pbus, PCI_DEVFN(devn, fn)); } - cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn,0)); + cdb_dev = dev_find_slot(busn, PCI_DEVFN(devn, 0)); } - if(cdb_dev) { + if (cdb_dev) { /* Ok, We need to set the links for that device. * otherwise the device under it will not be scanned */ - int link; int linknum; #if CONFIG_HT3_SUPPORT==1 linknum = 8; #else linknum = 4; #endif - if(cdb_dev->links < linknum) { - for(link=cdb_dev->links; linklink[link].link = link; - cdb_dev->link[link].dev = cdb_dev; - } - cdb_dev->links = linknum; - printk(BIOS_DEBUG, "%s links increase to %d\n", dev_path(cdb_dev), cdb_dev->links); - } + add_more_links(cdb_dev, linknum); } cores_found = 0; // one core @@ -1413,14 +1452,14 @@ static u32 cpu_bus_scan(device_t dev, u32 max) cpu->path.apic.node_id = i; cpu->path.apic.core_id = j; #if (CONFIG_ENABLE_APIC_EXT_ID == 1) && (CONFIG_APIC_ID_OFFSET>0) - if(sysconf.enabled_apic_ext_id) { + 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(BIOS_DEBUG, "CPU: %s %s\n", @@ -1429,30 +1468,44 @@ static u32 cpu_bus_scan(device_t dev, u32 max) } //j } + printk(BIOS_INFO, "%s: done.\n", __func__); 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 */