staticint sub_reg(u32 *reg, u32 *sub)
{ int i, borrow = 0;
for (i = MAX_ADDR_CELLS - 1; i >= 0; i--) { int prev_borrow = borrow;
borrow = reg[i] < sub[i] + prev_borrow;
reg[i] -= sub[i] + prev_borrow;
}
return !borrow;
}
staticint add_reg(u32 *reg, u32 *add, int naddr)
{ int i, carry = 0;
for (i = MAX_ADDR_CELLS - 1; i >= MAX_ADDR_CELLS - naddr; i--) {
u64 tmp = (u64)be32_to_cpu(reg[i]) + be32_to_cpu(add[i]) + carry;
carry = tmp >> 32;
reg[i] = cpu_to_be32((u32)tmp);
}
return !carry;
}
/* It is assumed that if the first byte of reg fits in a * range, then the whole reg block fits.
*/ staticint compare_reg(u32 *reg, u32 *range, u32 *rangesize)
{ int i;
u32 end;
for (i = 0; i < MAX_ADDR_CELLS; i++) { if (be32_to_cpu(reg[i]) < be32_to_cpu(range[i])) return 0; if (be32_to_cpu(reg[i]) > be32_to_cpu(range[i])) break;
}
for (i = 0; i < MAX_ADDR_CELLS; i++) {
end = be32_to_cpu(range[i]) + be32_to_cpu(rangesize[i]);
if (be32_to_cpu(reg[i]) < end) break; if (be32_to_cpu(reg[i]) > end) return 0;
}
return reg[i] != end;
}
/* reg must be MAX_ADDR_CELLS */ staticint find_range(u32 *reg, u32 *ranges, int nregaddr, int naddr, int nsize, int buflen)
{ int nrange = nregaddr + naddr + nsize; int i;
for (i = 0; i + nrange <= buflen; i += nrange) {
u32 range_addr[MAX_ADDR_CELLS];
u32 range_size[MAX_ADDR_CELLS];
copy_val(range_addr, ranges + i, nregaddr);
copy_val(range_size, ranges + i + nregaddr + naddr, nsize);
if (compare_reg(reg, range_addr, range_size)) return i;
}
return -1;
}
/* Currently only generic buses without special encodings are supported. * In particular, PCI is not supported. Also, only the beginning of the * reg block is tracked; size is ignored except in ranges.
*/ static u32 prop_buf[MAX_PROP_LEN / 4];
staticint dt_xlate(void *node, int res, int reglen, unsignedlong *addr, unsignedlong *size)
{
u32 last_addr[MAX_ADDR_CELLS];
u32 this_addr[MAX_ADDR_CELLS]; void *parent;
u64 ret_addr, ret_size;
u32 naddr, nsize, prev_naddr, prev_nsize; int buflen, offset;
parent = get_parent(node); if (!parent) return 0;
dt_get_reg_format(parent, &naddr, &nsize); if (nsize > 2) return 0;
int dt_is_compatible(void *node, constchar *compat)
{ char *buf = (char *)prop_buf; int len, pos;
len = getprop(node, "compatible", buf, MAX_PROP_LEN); if (len < 0) return 0;
for (pos = 0; pos < len; pos++) { if (!strcmp(buf + pos, compat)) return 1;
pos += strnlen(&buf[pos], len - pos);
}
return 0;
}
int dt_get_virtual_reg(void *node, void **addr, int nres)
{ unsignedlong xaddr; int n, i;
n = getprop(node, "virtual-reg", addr, nres * 4); if (n > 0) { for (i = 0; i < n/4; i ++)
((u32 *)addr)[i] = be32_to_cpu(((u32 *)addr)[i]); return n / 4;
}
for (n = 0; n < nres; n++) { if (!dt_xlate_reg(node, n, &xaddr, NULL)) break;
addr[n] = (void *)xaddr;
}
return n;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.