static int of_translate_one(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus, __be32 *addr, int na, int ns, int pna, const char *rprop) { const __be32 *ranges; unsigned int rlen; int rone; u64 offset = OF_BAD_ADDR; /* * Normally, an absence of a "ranges" property means we are * crossing a non-translatable boundary, and thus the addresses * below the current cannot be converted to CPU physical ones. * Unfortunately, while this is very clear in the spec, it's not * what Apple understood, and they do have things like /uni-n or * /ht nodes with no "ranges" property and a lot of perfectly * useable mapped devices below them. Thus we treat the absence of * "ranges" as equivalent to an empty "ranges" property which means * a 1:1 translation at that level. It's up to the caller not to try * to translate addresses that aren't supposed to be translated in * the first place. --BenH. * * As far as we know, this damage only exists on Apple machines, so * This code is only enabled on powerpc. --gcl */ ranges = of_get_property(parent, rprop, &rlen); if (ranges == NULL && !of_empty_ranges_quirk(parent)) { pr_debug("no ranges; cannot translate\n"); return 1; } if (ranges == NULL || rlen == 0) { offset = of_read_number(addr, na); memset(addr, 0, pna * 4); pr_debug("empty ranges; 1:1 translation\n"); goto finish; } pr_debug("walking ranges...\n"); /* Now walk through the ranges */ rlen /= 4; rone = na + pna + ns; for (; rlen >= rone; rlen -= rone, ranges += rone) { offset = bus->map(addr, ranges, na, ns, pna); if (offset != OF_BAD_ADDR) break; } if (offset == OF_BAD_ADDR) { pr_debug("not found !\n"); return 1; } memcpy(addr, ranges + na, 4 * pna); finish: of_dump_addr("parent translation for:", addr, pna); pr_debug("with offset: %llx\n", (unsigned long long)offset); /* Translate it into parent bus space */ return pbus->translate(addr, offset, pna); }
static int of_translate_one(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus, u32 *addr, int na, int ns, int pna) { const u32 *ranges; unsigned int rlen; int rone; u64 offset = OF_BAD_ADDR; /* Normally, an absence of a "ranges" property means we are * crossing a non-translatable boundary, and thus the addresses * below the current not cannot be converted to CPU physical ones. * Unfortunately, while this is very clear in the spec, it's not * what Apple understood, and they do have things like /uni-n or * /ht nodes with no "ranges" property and a lot of perfectly * useable mapped devices below them. Thus we treat the absence of * "ranges" as equivalent to an empty "ranges" property which means * a 1:1 translation at that level. It's up to the caller not to try * to translate addresses that aren't supposed to be translated in * the first place. --BenH. */ ranges = of_get_property(parent, "ranges", &rlen); if (ranges == NULL || rlen == 0) { offset = of_read_number(addr, na); memset(addr, 0, pna * 4); DBG("OF: no ranges, 1:1 translation\n"); goto finish; } DBG("OF: walking ranges...\n"); /* Now walk through the ranges */ rlen /= 4; rone = na + pna + ns; for (; rlen >= rone; rlen -= rone, ranges += rone) { offset = bus->map(addr, ranges, na, ns, pna); if (offset != OF_BAD_ADDR) break; } if (offset == OF_BAD_ADDR) { DBG("OF: not found !\n"); return 1; } memcpy(addr, ranges + na, 4 * pna); finish: of_dump_addr("OF: parent translation for:", addr, pna); DBG("OF: with offset: "PRu64"\n", offset); /* Translate it into parent bus space */ return pbus->translate(addr, offset, pna); }
static int of_translate_one(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus, u32 *addr, int na, int ns, int pna, const char *rprop) { const __be32 *ranges; unsigned int rlen; int rone; u64 offset = OF_BAD_ADDR; ranges = of_get_property(parent, rprop, &rlen); #if !defined(CONFIG_PPC) if (ranges == NULL) { pr_err("OF: no ranges; cannot translate\n"); return 1; } #endif if (ranges == NULL || rlen == 0) { offset = of_read_number(addr, na); memset(addr, 0, pna * 4); pr_debug("OF: empty ranges; 1:1 translation\n"); goto finish; } pr_debug("OF: walking ranges...\n"); rlen /= 4; rone = na + pna + ns; for (; rlen >= rone; rlen -= rone, ranges += rone) { offset = bus->map(addr, ranges, na, ns, pna); if (offset != OF_BAD_ADDR) break; } if (offset == OF_BAD_ADDR) { pr_debug("OF: not found !\n"); return 1; } memcpy(addr, ranges + na, 4 * pna); finish: of_dump_addr("OF: parent translation for:", addr, pna); pr_debug("OF: with offset: %llx\n", (unsigned long long)offset); return pbus->translate(addr, offset, pna); }
static int __init fdt_translate_one(const void *blob, int parent, const struct of_bus *bus, const struct of_bus *pbus, __be32 *addr, int na, int ns, int pna, const char *rprop) { const __be32 *ranges; int rlen; int rone; u64 offset = OF_BAD_ADDR; ranges = fdt_getprop(blob, parent, rprop, &rlen); if (!ranges) return 1; if (rlen == 0) { offset = of_read_number(addr, na); memset(addr, 0, pna * 4); pr_debug("FDT: empty ranges, 1:1 translation\n"); goto finish; } pr_debug("FDT: walking ranges...\n"); /* Now walk through the ranges */ rlen /= 4; rone = na + pna + ns; for (; rlen >= rone; rlen -= rone, ranges += rone) { offset = bus->map(addr, ranges, na, ns, pna); if (offset != OF_BAD_ADDR) break; } if (offset == OF_BAD_ADDR) { pr_debug("FDT: not found !\n"); return 1; } memcpy(addr, ranges + na, 4 * pna); finish: of_dump_addr("FDT: parent translation for:", addr, pna); pr_debug("FDT: with offset: %llx\n", offset); /* Translate it into parent bus space */ return pbus->translate(addr, offset, pna); }
/* * Translate an address from the device-tree into a CPU physical address, * this walks up the tree and applies the various bus mappings on the * way. * * Note: We consider that crossing any level with #size-cells == 0 to mean * that translation is impossible (that is we are not dealing with a value * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things */ static u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, const char *rprop) { struct device_node *parent = NULL; struct of_bus *bus, *pbus; __be32 addr[OF_MAX_ADDR_CELLS]; int na, ns, pna, pns; u64 result = OF_BAD_ADDR; pr_debug("** translation for device %pOF **\n", dev); /* Increase refcount at current level */ of_node_get(dev); /* Get parent & match bus type */ parent = of_get_parent(dev); if (parent == NULL) goto bail; bus = of_match_bus(parent); /* Count address cells & copy address locally */ bus->count_cells(dev, &na, &ns); if (!OF_CHECK_COUNTS(na, ns)) { pr_debug("Bad cell count for %pOF\n", dev); goto bail; } memcpy(addr, in_addr, na * 4); pr_debug("bus is %s (na=%d, ns=%d) on %pOF\n", bus->name, na, ns, parent); of_dump_addr("translating address:", addr, na); /* Translate */ for (;;) { /* Switch to parent bus */ of_node_put(dev); dev = parent; parent = of_get_parent(dev); /* If root, we have finished */ if (parent == NULL) { pr_debug("reached root node\n"); result = of_read_number(addr, na); break; } /* Get new parent bus and counts */ pbus = of_match_bus(parent); pbus->count_cells(dev, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { pr_err("Bad cell count for %pOF\n", dev); break; } pr_debug("parent bus is %s (na=%d, ns=%d) on %pOF\n", pbus->name, pna, pns, parent); /* Apply bus translation */ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) break; /* Complete the move up one level */ na = pna; ns = pns; bus = pbus; of_dump_addr("one level translation:", addr, na); } bail: of_node_put(parent); of_node_put(dev); return result; }
/* * Translate an address from the device-tree into a CPU physical address, * this walks up the tree and applies the various bus mappings on the * way. * * Note: We consider that crossing any level with #size-cells == 0 to mean * that translation is impossible (that is we are not dealing with a value * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things */ u64 of_translate_address(struct device_node *dev, const u32 *in_addr) { struct device_node *parent = NULL; struct of_bus *bus, *pbus; u32 addr[OF_MAX_ADDR_CELLS]; int na, ns, pna, pns; u64 result = OF_BAD_ADDR; DBG("OF: ** translation for device %s **\n", dev->full_name); /* Increase refcount at current level */ of_node_get(dev); /* Get parent & match bus type */ parent = of_get_parent(dev); if (parent == NULL) goto bail; bus = of_match_bus(parent); /* Cound address cells & copy address locally */ bus->count_cells(dev, &na, &ns); if (!OF_CHECK_COUNTS(na, ns)) { printk(KERN_ERR "prom_parse: Bad cell count for %s\n", dev->full_name); goto bail; } memcpy(addr, in_addr, na * 4); DBG("OF: bus is %s (na=%d, ns=%d) on %s\n", bus->name, na, ns, parent->full_name); of_dump_addr("OF: translating address:", addr, na); /* Translate */ for (;;) { /* Switch to parent bus */ of_node_put(dev); dev = parent; parent = of_get_parent(dev); /* If root, we have finished */ if (parent == NULL) { DBG("OF: reached root node\n"); result = of_read_number(addr, na); break; } /* Get new parent bus and counts */ pbus = of_match_bus(parent); pbus->count_cells(dev, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { printk(KERN_ERR "prom_parse: Bad cell count for %s\n", dev->full_name); break; } DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n", pbus->name, pna, pns, parent->full_name); /* Apply bus translation */ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) break; /* Complete the move up one level */ na = pna; ns = pns; bus = pbus; of_dump_addr("OF: one level translation:", addr, na); } bail: of_node_put(parent); of_node_put(dev); return result; }
/* * Translate an address from the device-tree into a CPU physical address, * this walks up the tree and applies the various bus mappings on the * way. * * Note: We consider that crossing any level with #size-cells == 0 to mean * that translation is impossible (that is we are not dealing with a value * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things * * Whenever the translation fails, the *host pointer will be set to the * device that had registered logical PIO mapping, and the return code is * relative to that node. */ static u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, const char *rprop, struct device_node **host) { struct device_node *parent = NULL; struct of_bus *bus, *pbus; __be32 addr[OF_MAX_ADDR_CELLS]; int na, ns, pna, pns; u64 result = OF_BAD_ADDR; pr_debug("** translation for device %pOF **\n", dev); /* Increase refcount at current level */ of_node_get(dev); *host = NULL; /* Get parent & match bus type */ parent = of_get_parent(dev); if (parent == NULL) goto bail; bus = of_match_bus(parent); /* Count address cells & copy address locally */ bus->count_cells(dev, &na, &ns); if (!OF_CHECK_COUNTS(na, ns)) { pr_debug("Bad cell count for %pOF\n", dev); goto bail; } memcpy(addr, in_addr, na * 4); pr_debug("bus is %s (na=%d, ns=%d) on %pOF\n", bus->name, na, ns, parent); of_dump_addr("translating address:", addr, na); /* Translate */ for (;;) { struct logic_pio_hwaddr *iorange; /* Switch to parent bus */ of_node_put(dev); dev = parent; parent = of_get_parent(dev); /* If root, we have finished */ if (parent == NULL) { pr_debug("reached root node\n"); result = of_read_number(addr, na); break; } /* * For indirectIO device which has no ranges property, get * the address from reg directly. */ iorange = find_io_range_by_fwnode(&dev->fwnode); if (iorange && (iorange->flags != LOGIC_PIO_CPU_MMIO)) { result = of_read_number(addr + 1, na - 1); pr_debug("indirectIO matched(%pOF) 0x%llx\n", dev, result); *host = of_node_get(dev); break; } /* Get new parent bus and counts */ pbus = of_match_bus(parent); pbus->count_cells(dev, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { pr_err("Bad cell count for %pOF\n", dev); break; } pr_debug("parent bus is %s (na=%d, ns=%d) on %pOF\n", pbus->name, pna, pns, parent); /* Apply bus translation */ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) break; /* Complete the move up one level */ na = pna; ns = pns; bus = pbus; of_dump_addr("one level translation:", addr, na); } bail: of_node_put(parent); of_node_put(dev); return result; }
/* * Translate an address from the device-tree into a CPU physical address, * this walks up the tree and applies the various bus mappings on the * way. * * Note: We consider that crossing any level with #size-cells == 0 to mean * that translation is impossible (that is we are not dealing with a value * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things */ u64 __init fdt_translate_address(const void *blob, int node_offset) { int parent, len; const struct of_bus *bus, *pbus; const __be32 *reg; __be32 addr[OF_MAX_ADDR_CELLS]; int na, ns, pna, pns; u64 result = OF_BAD_ADDR; pr_debug("FDT: ** translation for device %s **\n", fdt_get_name(blob, node_offset, NULL)); reg = fdt_getprop(blob, node_offset, "reg", &len); if (!reg) { pr_err("FDT: warning: device tree node '%s' has no address.\n", fdt_get_name(blob, node_offset, NULL)); goto bail; } /* Get parent & match bus type */ parent = fdt_parent_offset(blob, node_offset); if (parent < 0) goto bail; bus = &of_busses[0]; /* Cound address cells & copy address locally */ bus->count_cells(blob, parent, &na, &ns); if (!OF_CHECK_COUNTS(na, ns)) { pr_err("FDT: Bad cell count for %s\n", fdt_get_name(blob, node_offset, NULL)); goto bail; } memcpy(addr, reg, na * 4); pr_debug("FDT: bus (na=%d, ns=%d) on %s\n", na, ns, fdt_get_name(blob, parent, NULL)); of_dump_addr("OF: translating address:", addr, na); /* Translate */ for (;;) { /* Switch to parent bus */ node_offset = parent; parent = fdt_parent_offset(blob, node_offset); /* If root, we have finished */ if (parent < 0) { pr_debug("FDT: reached root node\n"); result = of_read_number(addr, na); break; } /* Get new parent bus and counts */ pbus = &of_busses[0]; pbus->count_cells(blob, parent, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { pr_err("FDT: Bad cell count for %s\n", fdt_get_name(blob, node_offset, NULL)); break; } pr_debug("FDT: parent bus (na=%d, ns=%d) on %s\n", pna, pns, fdt_get_name(blob, parent, NULL)); /* Apply bus translation */ if (fdt_translate_one(blob, node_offset, bus, pbus, addr, na, ns, pna, "ranges")) break; /* Complete the move up one level */ na = pna; ns = pns; bus = pbus; of_dump_addr("FDT: one level translation:", addr, na); } bail: return result; }
u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, const char *rprop) { struct device_node *parent = NULL; struct of_bus *bus, *pbus; u32 addr[OF_MAX_ADDR_CELLS]; int na, ns, pna, pns; u64 result = OF_BAD_ADDR; pr_debug("OF: ** translation for device %s **\n", dev->full_name); of_node_get(dev); parent = of_get_parent(dev); if (parent == NULL) goto bail; bus = of_match_bus(parent); bus->count_cells(dev, &na, &ns); if (!OF_CHECK_COUNTS(na, ns)) { printk(KERN_ERR "prom_parse: Bad cell count for %s\n", dev->full_name); goto bail; } memcpy(addr, in_addr, na * 4); pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", bus->name, na, ns, parent->full_name); of_dump_addr("OF: translating address:", addr, na); for (;;) { of_node_put(dev); dev = parent; parent = of_get_parent(dev); if (parent == NULL) { pr_debug("OF: reached root node\n"); result = of_read_number(addr, na); break; } pbus = of_match_bus(parent); pbus->count_cells(dev, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { printk(KERN_ERR "prom_parse: Bad cell count for %s\n", dev->full_name); break; } pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", pbus->name, pna, pns, parent->full_name); if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) break; na = pna; ns = pns; bus = pbus; of_dump_addr("OF: one level translation:", addr, na); } bail: of_node_put(parent); of_node_put(dev); return result; }