Patchwork PPC: Skip over OF_DT_NOP when unflattening the device tree

login
register
mail settings
Submitter Jason Gunthorpe
Date March 9, 2010, 7:30 p.m.
Message ID <20100309193021.GD30462@obsidianresearch.com>
Download mbox | patch
Permalink /patch/47185/
State Accepted
Delegated to: Grant Likely
Headers show

Comments

Jason Gunthorpe - March 9, 2010, 7:30 p.m.
NOPs within the property section are skipped, but NOPs between
OF_DT_END_NODE and OF_DT_BEGIN_NODE were not. My firmware NOPs out
entire nodes depending on various environment parameters.

of_scan_flat_dt already handles NOP more generally..

Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
---
 arch/powerpc/kernel/prom.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)
Benjamin Herrenschmidt - March 19, 2010, 5:50 a.m.
On Tue, 2010-03-09 at 12:30 -0700, Jason Gunthorpe wrote:
> NOPs within the property section are skipped, but NOPs between
> OF_DT_END_NODE and OF_DT_BEGIN_NODE were not. My firmware NOPs out
> entire nodes depending on various environment parameters.
> 
> of_scan_flat_dt already handles NOP more generally..

Good catch, though that code has now moved over to drivers/of
and is a bit different. Grant is going to fix it up though.

Cheers,
Ben.

> Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
> ---
>  arch/powerpc/kernel/prom.c |    7 +++++--
>  1 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 4ec3008..92137b2 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -408,8 +408,11 @@ static unsigned long __init unflatten_dt_node(unsigned long mem,
>  		if (!np->type)
>  			np->type = "<NULL>";
>  	}
> -	while (tag == OF_DT_BEGIN_NODE) {
> -		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
> +	while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) {
> +		if (tag == OF_DT_NOP)
> +			*p += 4;
> +		else
> +			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
>  		tag = *((u32 *)(*p));
>  	}
>  	if (tag != OF_DT_END_NODE) {
Jason Gunthorpe - March 19, 2010, 6:06 a.m.
On Fri, Mar 19, 2010 at 04:50:38PM +1100, Benjamin Herrenschmidt wrote:
> On Tue, 2010-03-09 at 12:30 -0700, Jason Gunthorpe wrote:
> > NOPs within the property section are skipped, but NOPs between
> > OF_DT_END_NODE and OF_DT_BEGIN_NODE were not. My firmware NOPs out
> > entire nodes depending on various environment parameters.
> > 
> > of_scan_flat_dt already handles NOP more generally..
> 
> Good catch, though that code has now moved over to drivers/of
> and is a bit different. Grant is going to fix it up though.

Ah, I based the patch off 2.6.33.. 

Grant: let me know if you need some help/testing, nice to run into you
again.

Jason
Grant Likely - March 19, 2010, 6:18 a.m.
On Fri, Mar 19, 2010 at 12:06 AM, Jason Gunthorpe
<jgunthorpe@obsidianresearch.com> wrote:
> On Fri, Mar 19, 2010 at 04:50:38PM +1100, Benjamin Herrenschmidt wrote:
>> On Tue, 2010-03-09 at 12:30 -0700, Jason Gunthorpe wrote:
>> > NOPs within the property section are skipped, but NOPs between
>> > OF_DT_END_NODE and OF_DT_BEGIN_NODE were not. My firmware NOPs out
>> > entire nodes depending on various environment parameters.
>> >
>> > of_scan_flat_dt already handles NOP more generally..
>>
>> Good catch, though that code has now moved over to drivers/of
>> and is a bit different. Grant is going to fix it up though.
>
> Ah, I based the patch off 2.6.33..
>
> Grant: let me know if you need some help/testing, nice to run into you
> again.

Would be nice if you could respin and test your patch against 2.6.34-rc1.  :-)

Otherwise I'll look at it tomorrow.

g.

Patch

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4ec3008..92137b2 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -408,8 +408,11 @@  static unsigned long __init unflatten_dt_node(unsigned long mem,
 		if (!np->type)
 			np->type = "<NULL>";
 	}
-	while (tag == OF_DT_BEGIN_NODE) {
-		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
+	while (tag == OF_DT_BEGIN_NODE || tag == OF_DT_NOP) {
+		if (tag == OF_DT_NOP)
+			*p += 4;
+		else
+			mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
 		tag = *((u32 *)(*p));
 	}
 	if (tag != OF_DT_END_NODE) {