static struct resource *amdfam12_find_mempair(device_t dev, u32 nodeid, u32 link) { struct resource *resource; u32 free_reg, reg; resource = 0; free_reg = 0; for(reg = 0x80; reg <= 0xb8; reg += 0x8) { int result; result = reg_useable(reg, dev, nodeid, link); if (result == 1) { /* I have been allocated this one */ break; } else if (result > 1) { /* I have a free register pair */ free_reg = reg; } } if (reg > 0xb8) { reg = free_reg; } //Ext conf space if(!reg) { //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 u32 index = get_mmio_addr_index(nodeid, link); reg = 0x110+ (index<<24) + (6<<20); // index could be 0, 63 } resource = new_resource(dev, IOINDEX(0x1000 + reg, link)); return resource; }
static struct resource *amdfam14_find_iopair(device_t dev, unsigned nodeid, unsigned link) { struct resource *resource; u32 result, reg; resource = 0; reg = 0; result = reg_useable(0xc0, dev, nodeid, link); if (result >= 1) { /* I have been allocated this one */ reg = 0xc0; } /* Ext conf space */ if (!reg) { /* 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 */ u32 index = get_io_addr_index(nodeid, link); reg = 0x110 + (index << 24) + (4 << 20); // index could be 0, 255 } resource = new_resource(dev, IOINDEX(0x1000 + reg, link)); return resource; }
static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid, unsigned goal_link) { struct resource *res; unsigned nodeid, link = 0; int result; printk(BIOS_DEBUG, "\nFam12h - northbridge.c - %s - Start.\n",__func__); res = 0; 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, IOINDEX(0x1000 + reg, link)); } } result = 2; if (res) { result = 0; if ( (goal_link == (link - 1)) && (goal_nodeid == (nodeid - 1)) && (res->flags <= 1)) { result = 1; } } printk(BIOS_DEBUG, "Fam12h - northbridge.c - %s - End.\n",__func__); return result; }
static int reg_useable(unsigned reg, device_t goal_dev, unsigned goal_nodeid, unsigned goal_link) { struct resource *res; unsigned nodeid, link = 0; int result; res = 0; 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, IOINDEX(0x1000 + reg, link)); } } result = 2; if (res) { result = 0; if ((goal_link == (link - 1)) && (goal_nodeid == (nodeid - 1)) && (res->flags <= 1)) { result = 1; } } return result; }