[POWERPC] Add dt_xlate_addr() to bootwrapper
dt_xlate_reg() looks up the 'reg' property in the specified node to get the address and size to translate. Add dt_xlate_addr() which is passed in the address and size to translate. Signed-off-by: Mark A. Greer <mgreer@mvista.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
committed by
Paul Mackerras
parent
d818d7ec8b
commit
8895ea483e
@@ -207,12 +207,13 @@ static int find_range(u32 *reg, u32 *ranges, int nregaddr,
|
|||||||
* In particular, PCI is not supported. Also, only the beginning of the
|
* In particular, PCI is not supported. Also, only the beginning of the
|
||||||
* reg block is tracked; size is ignored except in ranges.
|
* reg block is tracked; size is ignored except in ranges.
|
||||||
*/
|
*/
|
||||||
int dt_xlate_reg(void *node, int res, unsigned long *addr,
|
static u32 dt_xlate_buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
|
||||||
|
|
||||||
|
static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
|
||||||
unsigned long *size)
|
unsigned long *size)
|
||||||
{
|
{
|
||||||
u32 last_addr[MAX_ADDR_CELLS];
|
u32 last_addr[MAX_ADDR_CELLS];
|
||||||
u32 this_addr[MAX_ADDR_CELLS];
|
u32 this_addr[MAX_ADDR_CELLS];
|
||||||
u32 buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
|
|
||||||
void *parent;
|
void *parent;
|
||||||
u64 ret_addr, ret_size;
|
u64 ret_addr, ret_size;
|
||||||
u32 naddr, nsize, prev_naddr;
|
u32 naddr, nsize, prev_naddr;
|
||||||
@@ -227,19 +228,18 @@ int dt_xlate_reg(void *node, int res, unsigned long *addr,
|
|||||||
if (nsize > 2)
|
if (nsize > 2)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
buflen = getprop(node, "reg", buf, sizeof(buf)) / 4;
|
|
||||||
offset = (naddr + nsize) * res;
|
offset = (naddr + nsize) * res;
|
||||||
|
|
||||||
if (buflen < offset + naddr + nsize ||
|
if (reglen < offset + naddr + nsize ||
|
||||||
sizeof(buf) < offset + naddr + nsize)
|
sizeof(dt_xlate_buf) < offset + naddr + nsize)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
copy_val(last_addr, buf + offset, naddr);
|
copy_val(last_addr, dt_xlate_buf + offset, naddr);
|
||||||
|
|
||||||
ret_size = buf[offset + naddr];
|
ret_size = dt_xlate_buf[offset + naddr];
|
||||||
if (nsize == 2) {
|
if (nsize == 2) {
|
||||||
ret_size <<= 32;
|
ret_size <<= 32;
|
||||||
ret_size |= buf[offset + naddr + 1];
|
ret_size |= dt_xlate_buf[offset + naddr + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((node = get_parent(node))) {
|
while ((node = get_parent(node))) {
|
||||||
@@ -247,24 +247,25 @@ int dt_xlate_reg(void *node, int res, unsigned long *addr,
|
|||||||
|
|
||||||
get_reg_format(node, &naddr, &nsize);
|
get_reg_format(node, &naddr, &nsize);
|
||||||
|
|
||||||
buflen = getprop(node, "ranges", buf, sizeof(buf));
|
buflen = getprop(node, "ranges", dt_xlate_buf,
|
||||||
|
sizeof(dt_xlate_buf));
|
||||||
if (buflen < 0)
|
if (buflen < 0)
|
||||||
continue;
|
continue;
|
||||||
if (buflen > sizeof(buf))
|
if (buflen > sizeof(dt_xlate_buf))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
offset = find_range(last_addr, buf, prev_naddr,
|
offset = find_range(last_addr, dt_xlate_buf, prev_naddr,
|
||||||
naddr, nsize, buflen / 4);
|
naddr, nsize, buflen / 4);
|
||||||
|
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
copy_val(this_addr, buf + offset, prev_naddr);
|
copy_val(this_addr, dt_xlate_buf + offset, prev_naddr);
|
||||||
|
|
||||||
if (!sub_reg(last_addr, this_addr))
|
if (!sub_reg(last_addr, this_addr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
copy_val(this_addr, buf + offset + prev_naddr, naddr);
|
copy_val(this_addr, dt_xlate_buf + offset + prev_naddr, naddr);
|
||||||
|
|
||||||
if (!add_reg(last_addr, this_addr, naddr))
|
if (!add_reg(last_addr, this_addr, naddr))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -286,3 +287,21 @@ int dt_xlate_reg(void *node, int res, unsigned long *addr,
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size)
|
||||||
|
{
|
||||||
|
int reglen;
|
||||||
|
|
||||||
|
reglen = getprop(node, "reg", dt_xlate_buf, sizeof(dt_xlate_buf)) / 4;
|
||||||
|
return dt_xlate(node, res, reglen, addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (buflen > sizeof(dt_xlate_buf))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy(dt_xlate_buf, buf, buflen);
|
||||||
|
return dt_xlate(node, 0, buflen / 4, xlated_addr, NULL);
|
||||||
|
}
|
||||||
|
@@ -82,8 +82,8 @@ int ns16550_console_init(void *devp, struct serial_console_data *scdp);
|
|||||||
void *simple_alloc_init(char *base, unsigned long heap_size,
|
void *simple_alloc_init(char *base, unsigned long heap_size,
|
||||||
unsigned long granularity, unsigned long max_allocs);
|
unsigned long granularity, unsigned long max_allocs);
|
||||||
extern void flush_cache(void *, unsigned long);
|
extern void flush_cache(void *, unsigned long);
|
||||||
int dt_xlate_reg(void *node, int res, unsigned long *addr,
|
int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
|
||||||
unsigned long *size);
|
int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
|
||||||
|
|
||||||
static inline void *finddevice(const char *name)
|
static inline void *finddevice(const char *name)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user