* [PATCH] powerpc: Add dt_xlate_addr() to bootwrapper
@ 2007-04-13 20:23 Mark A. Greer
2007-04-13 22:25 ` Scott Wood
0 siblings, 1 reply; 4+ messages in thread
From: Mark A. Greer @ 2007-04-13 20:23 UTC (permalink / raw)
To: linuxppc-dev
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>
---
Scott, would you please 'Acked-by:' or NACK this? Thanks.
devtree.c | 31 +++++++++++++------------------
ops.h | 23 +++++++++++++++++++++--
2 files changed, 34 insertions(+), 20 deletions(-)
---
diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c
index 23492d7..11b542d 100644
--- a/arch/powerpc/boot/devtree.c
+++ b/arch/powerpc/boot/devtree.c
@@ -110,9 +110,6 @@ void __dt_fixup_mac_addresses(u32 startindex, ...)
va_end(ap);
}
-#define MAX_ADDR_CELLS 4
-#define MAX_RANGES 8
-
static void get_reg_format(void *node, u32 *naddr, u32 *nsize)
{
if (getprop(node, "#address-cells", naddr, 4) != 4)
@@ -123,7 +120,7 @@ static void get_reg_format(void *node, u32 *naddr, u32 *nsize)
static void copy_val(u32 *dest, u32 *src, int naddr)
{
- memset(dest, 0, (MAX_ADDR_CELLS - naddr) * 4);
+ memset(dest, 0, (DT_MAX_ADDR_CELLS - naddr) * 4);
memcpy(dest, src, naddr * 4);
}
@@ -131,7 +128,7 @@ static int sub_reg(u32 *reg, u32 *sub)
{
int i, borrow = 0;
- for (i = 0; i < MAX_ADDR_CELLS; i++) {
+ for (i = 0; i < DT_MAX_ADDR_CELLS; i++) {
int prev_borrow = borrow;
borrow = reg[i] < sub[i] + prev_borrow;
reg[i] -= sub[i] + prev_borrow;
@@ -144,7 +141,7 @@ static int add_reg(u32 *reg, u32 *add)
{
int i, carry = 0;
- for (i = 0; i < MAX_ADDR_CELLS; i++) {
+ for (i = 0; i < DT_MAX_ADDR_CELLS; i++) {
u64 tmp = (u64)reg[i] + add[i] + carry;
carry = tmp >> 32;
reg[i] = (u32)tmp;
@@ -161,14 +158,14 @@ static int compare_reg(u32 *reg, u32 *range, u32 *rangesize)
int i;
u32 end;
- for (i = 0; i < MAX_ADDR_CELLS; i++) {
+ for (i = 0; i < DT_MAX_ADDR_CELLS; i++) {
if (reg[i] < range[i])
return 0;
if (reg[i] > range[i])
break;
}
- for (i = 0; i < MAX_ADDR_CELLS; i++) {
+ for (i = 0; i < DT_MAX_ADDR_CELLS; i++) {
end = range[i] + rangesize[i];
if (reg[i] < end)
@@ -180,7 +177,7 @@ static int compare_reg(u32 *reg, u32 *range, u32 *rangesize)
return reg[i] != end;
}
-/* reg must be MAX_ADDR_CELLS */
+/* reg must be DT_MAX_ADDR_CELLS */
static int find_range(u32 *reg, u32 *ranges, int nregaddr,
int naddr, int nsize, int buflen)
{
@@ -188,8 +185,8 @@ static int find_range(u32 *reg, u32 *ranges, int nregaddr,
int i;
for (i = 0; i + nrange <= buflen; i += nrange) {
- u32 range_addr[MAX_ADDR_CELLS];
- u32 range_size[MAX_ADDR_CELLS];
+ u32 range_addr[DT_MAX_ADDR_CELLS];
+ u32 range_size[DT_MAX_ADDR_CELLS];
copy_val(range_addr, ranges + i, naddr);
copy_val(range_size, ranges + i + nregaddr + naddr, nsize);
@@ -205,16 +202,15 @@ static int find_range(u32 *reg, u32 *ranges, int nregaddr,
* In particular, PCI is not supported. Also, only the beginning of the
* reg block is tracked; size is ignored except in ranges.
*/
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size)
+int dt_xlate(void *node, u32 *buf, int buflen, int res, unsigned long *addr,
+ unsigned long *size)
{
- u32 last_addr[MAX_ADDR_CELLS];
- u32 this_addr[MAX_ADDR_CELLS];
- u32 buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
+ u32 last_addr[DT_MAX_ADDR_CELLS];
+ u32 this_addr[DT_MAX_ADDR_CELLS];
void *parent;
u64 ret_addr, ret_size;
u32 naddr, nsize, prev_naddr;
- int buflen, offset;
+ int offset;
parent = get_parent(node);
if (!parent)
@@ -225,7 +221,6 @@ int dt_xlate_reg(void *node, int res, unsigned long *addr,
if (nsize > 2)
return 0;
- buflen = getprop(node, "reg", buf, sizeof(buf)) / 4;
offset = (naddr + nsize) * res;
if (buflen < offset + naddr + nsize)
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index ee0f9c2..c499ee7 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -82,8 +82,8 @@ int ns16550_console_init(void *devp, struct serial_console_data *scdp);
void *simple_alloc_init(char *base, u32 heap_size, u32 granularity,
u32 max_allocs);
extern void flush_cache(void *, unsigned long);
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size);
+int dt_xlate(void *node, u32 *buf, int buflen, int res, unsigned long *addr,
+ unsigned long *size);
static inline void *finddevice(const char *name)
{
@@ -183,6 +183,25 @@ static inline void exit(void)
}
#define fatal(args...) { printf(args); exit(); }
+#define DT_MAX_ADDR_CELLS 4
+#define DT_MAX_RANGES 8
+
+static inline int dt_xlate_reg(void *node, int res, unsigned long *addr,
+ unsigned long *size)
+{
+ u32 buf[DT_MAX_ADDR_CELLS * DT_MAX_RANGES * 3];
+ int buflen;
+
+ buflen = getprop(node, "reg", buf, sizeof(buf)) / 4;
+ return dt_xlate(node, buf, buflen, res, addr, size);
+}
+
+static inline int dt_xlate_addr(void *node, u32 *buf, int buflen,
+ unsigned long *xlated_addr)
+{
+ return dt_xlate(node, buf, buflen, 0, xlated_addr, NULL);
+}
+
#define BSS_STACK(size) \
static char _bss_stack[size]; \
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] powerpc: Add dt_xlate_addr() to bootwrapper
2007-04-13 20:23 [PATCH] powerpc: Add dt_xlate_addr() to bootwrapper Mark A. Greer
@ 2007-04-13 22:25 ` Scott Wood
2007-04-13 22:36 ` Mark A. Greer
2007-04-25 21:16 ` Mark A. Greer
0 siblings, 2 replies; 4+ messages in thread
From: Scott Wood @ 2007-04-13 22:25 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
On Fri, Apr 13, 2007 at 01:23:43PM -0700, Mark A. Greer wrote:
> +int dt_xlate(void *node, u32 *buf, int buflen, int res, unsigned long *addr,
> + unsigned long *size)
> {
> - u32 last_addr[MAX_ADDR_CELLS];
> - u32 this_addr[MAX_ADDR_CELLS];
> - u32 buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
> + u32 last_addr[DT_MAX_ADDR_CELLS];
> + u32 this_addr[DT_MAX_ADDR_CELLS];
> void *parent;
This causes it to use the caller-provided buffer to read the ranges
property, which may not be large enough in the case of dt_xlate_addr().
Plus, buf being a pointer rather than an array will cause the sizeof(buf)
that gets passed to getprop() to be only sizeof(u32 *).
Instead, I'd declare "rangebuf" as a static array, and accept "regbuf" as
a parameter (with a comment that regbuf can alias rangebuf). Then,
dt_xlate_reg() can use rangebuf as regbuf, dt_xlate_addr()'s caller
doesn't have to worry about its buffer being big enough to hold ranges,
and we don't have to allocate two 384-byte buffers on the stack.
-Scott
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] powerpc: Add dt_xlate_addr() to bootwrapper
2007-04-13 22:25 ` Scott Wood
@ 2007-04-13 22:36 ` Mark A. Greer
2007-04-25 21:16 ` Mark A. Greer
1 sibling, 0 replies; 4+ messages in thread
From: Mark A. Greer @ 2007-04-13 22:36 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
On Fri, Apr 13, 2007 at 05:25:51PM -0500, Scott Wood wrote:
> On Fri, Apr 13, 2007 at 01:23:43PM -0700, Mark A. Greer wrote:
> > +int dt_xlate(void *node, u32 *buf, int buflen, int res, unsigned long *addr,
> > + unsigned long *size)
> > {
> > - u32 last_addr[MAX_ADDR_CELLS];
> > - u32 this_addr[MAX_ADDR_CELLS];
> > - u32 buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
> > + u32 last_addr[DT_MAX_ADDR_CELLS];
> > + u32 this_addr[DT_MAX_ADDR_CELLS];
> > void *parent;
>
> This causes it to use the caller-provided buffer to read the ranges
> property, which may not be large enough in the case of dt_xlate_addr().
> Plus, buf being a pointer rather than an array will cause the sizeof(buf)
> that gets passed to getprop() to be only sizeof(u32 *).
>
> Instead, I'd declare "rangebuf" as a static array, and accept "regbuf" as
> a parameter (with a comment that regbuf can alias rangebuf). Then,
> dt_xlate_reg() can use rangebuf as regbuf, dt_xlate_addr()'s caller
> doesn't have to worry about its buffer being big enough to hold ranges,
> and we don't have to allocate two 384-byte buffers on the stack.
Okay, I'll look closer this time. Thanks for checking.
Mark
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] powerpc: Add dt_xlate_addr() to bootwrapper
2007-04-13 22:25 ` Scott Wood
2007-04-13 22:36 ` Mark A. Greer
@ 2007-04-25 21:16 ` Mark A. Greer
1 sibling, 0 replies; 4+ messages in thread
From: Mark A. Greer @ 2007-04-25 21:16 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
On Fri, Apr 13, 2007 at 05:25:51PM -0500, Scott Wood wrote:
> On Fri, Apr 13, 2007 at 01:23:43PM -0700, Mark A. Greer wrote:
> This causes it to use the caller-provided buffer to read the ranges
> property, which may not be large enough in the case of dt_xlate_addr().
> ...
>
Scott, how about this? If you like it, please give me an "Acked-by:" line
and I'll submit it with some other patches I'm prep'ing.
Thanks,
Mark
---
[PATCH] powerpc: Add dt_xlate_addr() to bootwrapper
From: "Mark A. Greer" <mgreer@mvista.com>
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>
---
devtree.c | 45 ++++++++++++++++++++++++++++++++-------------
ops.h | 4 ++--
2 files changed, 34 insertions(+), 15 deletions(-)
Index: powerpc/arch/powerpc/boot/devtree.c
===================================================================
--- powerpc.orig/arch/powerpc/boot/devtree.c
+++ powerpc/arch/powerpc/boot/devtree.c
@@ -205,16 +205,17 @@ static int find_range(u32 *reg, u32 *ran
* In particular, PCI is not supported. Also, only the beginning of the
* reg block is tracked; size is ignored except in ranges.
*/
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size)
+static u32 dt_xlate_buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
+
+static int dt_xlate(void *node, int res, int buflen, unsigned long *addr,
+ unsigned long *size)
{
u32 last_addr[MAX_ADDR_CELLS];
u32 this_addr[MAX_ADDR_CELLS];
- u32 buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
void *parent;
u64 ret_addr, ret_size;
u32 naddr, nsize, prev_naddr;
- int buflen, offset;
+ int offset;
parent = get_parent(node);
if (!parent)
@@ -225,18 +226,17 @@ int dt_xlate_reg(void *node, int res, un
if (nsize > 2)
return 0;
- buflen = getprop(node, "reg", buf, sizeof(buf)) / 4;
offset = (naddr + nsize) * res;
if (buflen < offset + naddr + nsize)
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) {
ret_size <<= 32;
- ret_size |= buf[offset + naddr + 1];
+ ret_size |= dt_xlate_buf[offset + naddr + 1];
}
while ((node = get_parent(node))) {
@@ -244,24 +244,25 @@ int dt_xlate_reg(void *node, int res, un
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)
continue;
- if (buflen > sizeof(buf))
+ if (buflen > sizeof(dt_xlate_buf))
return 0;
- offset = find_range(last_addr, buf, prev_naddr,
+ offset = find_range(last_addr, dt_xlate_buf, prev_naddr,
naddr, nsize, buflen / 4);
if (offset < 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))
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))
return 0;
@@ -287,3 +288,21 @@ int dt_xlate_reg(void *node, int res, un
return 1;
}
+
+int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size)
+{
+ int buflen;
+
+ buflen = getprop(node, "reg", dt_xlate_buf, sizeof(dt_xlate_buf)) / 4;
+ return dt_xlate(node, res, buflen, 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);
+}
Index: powerpc/arch/powerpc/boot/ops.h
===================================================================
--- powerpc.orig/arch/powerpc/boot/ops.h
+++ powerpc/arch/powerpc/boot/ops.h
@@ -82,8 +82,8 @@ int ns16550_console_init(void *devp, str
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
extern void flush_cache(void *, unsigned long);
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size);
+int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
+int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
static inline void *finddevice(const char *name)
{
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-04-25 21:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-04-13 20:23 [PATCH] powerpc: Add dt_xlate_addr() to bootwrapper Mark A. Greer
2007-04-13 22:25 ` Scott Wood
2007-04-13 22:36 ` Mark A. Greer
2007-04-25 21:16 ` Mark A. Greer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox