Patchwork [U-Boot,3/6] mpc83xx: Add link vs. load address calculation

login
register
mail settings
Submitter Joakim Tjernlund
Date Nov. 23, 2010, 6:48 p.m.
Message ID <1290538131-12383-4-git-send-email-Joakim.Tjernlund@transmode.se>
Download mbox | patch
Permalink /patch/72718/
State Changes Requested
Headers show

Comments

Joakim Tjernlund - Nov. 23, 2010, 6:48 p.m.
link_off calculates the difference between link address and
actila load address. This is a must for true PIC u-boot.
---
 arch/powerpc/cpu/mpc83xx/start.S |   25 +++++++++++++++++++++++++
 include/common.h                 |    5 +++++
 2 files changed, 30 insertions(+), 0 deletions(-)
Scott Wood - Nov. 23, 2010, 7:32 p.m.
On Tue, 23 Nov 2010 19:48:48 +0100
Joakim Tjernlund <Joakim.Tjernlund@transmode.se> wrote:

> diff --git a/include/common.h b/include/common.h
> index 8bca04f..f257ea4 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -94,6 +94,9 @@ typedef volatile unsigned char	vu_char;
>  #ifdef CONFIG_MPC83xx
>  #include <mpc83xx.h>
>  #include <asm/immap_83xx.h>
> +const void * link_off(const void *);
> +#else
> +#define link_off(x) ((const void *)(x))
>  #endif

What is special about 83xx?

If it's just that 83xx is the only one that this type of relocation has
been enabled on so far, define a symbol for that.

-Scott
Joakim Tjernlund - Nov. 23, 2010, 8:08 p.m.
Scott Wood <scottwood@freescale.com> wrote on 2010/11/23 20:32:32:
> On Tue, 23 Nov 2010 19:48:48 +0100
> Joakim Tjernlund <Joakim.Tjernlund@transmode.se> wrote:
>
> > diff --git a/include/common.h b/include/common.h
> > index 8bca04f..f257ea4 100644
> > --- a/include/common.h
> > +++ b/include/common.h
> > @@ -94,6 +94,9 @@ typedef volatile unsigned char   vu_char;
> >  #ifdef CONFIG_MPC83xx
> >  #include <mpc83xx.h>
> >  #include <asm/immap_83xx.h>
> > +const void * link_off(const void *);
> > +#else
> > +#define link_off(x) ((const void *)(x))
> >  #endif
>
> What is special about 83xx?

Nothing, just it is the first one.
>
> If it's just that 83xx is the only one that this type of relocation has
> been enabled on so far, define a symbol for that.

there is a
#define LINK_OFF(x) ((__typeof__(x))link_off(x))
already but I am guessing you mean something else.
Perhaps a dummy link_off for other targets? Don't think
that is any better.
Scott Wood - Nov. 23, 2010, 8:17 p.m.
On Tue, 23 Nov 2010 21:08:37 +0100
Joakim Tjernlund <joakim.tjernlund@transmode.se> wrote:

> Scott Wood <scottwood@freescale.com> wrote on 2010/11/23 20:32:32:
> > On Tue, 23 Nov 2010 19:48:48 +0100
> > Joakim Tjernlund <Joakim.Tjernlund@transmode.se> wrote:
> >
> > > diff --git a/include/common.h b/include/common.h
> > > index 8bca04f..f257ea4 100644
> > > --- a/include/common.h
> > > +++ b/include/common.h
> > > @@ -94,6 +94,9 @@ typedef volatile unsigned char   vu_char;
> > >  #ifdef CONFIG_MPC83xx
> > >  #include <mpc83xx.h>
> > >  #include <asm/immap_83xx.h>
> > > +const void * link_off(const void *);
> > > +#else
> > > +#define link_off(x) ((const void *)(x))
> > >  #endif
> >
> > What is special about 83xx?
> 
> Nothing, just it is the first one.
> >
> > If it's just that 83xx is the only one that this type of relocation has
> > been enabled on so far, define a symbol for that.
> 
> there is a
> #define LINK_OFF(x) ((__typeof__(x))link_off(x))
> already but I am guessing you mean something else.
> Perhaps a dummy link_off for other targets? Don't think
> that is any better.

I mean instead of this:

#ifdef CONFIG_MPC83xx
...unrelated stuff...
const void *link_off(const void *ptr);
#else
#define link_off(x) ((const void *)(x));
#endif

do something like this:

#ifdef CONFIG_RELOC_PIC
const void *link_off(const void *ptr);
#else
#define link_off(x) ((const void *)(x));
#endif

...with CONFIG_RELOC_PIC defined in a board config file and also
controlling whether this mechanism is enabled at all.  Boards could
enable it as they verify that they have the proper manual relocations
(or just leave it off, if they don't think it's worth it) -- including
non-83xx targets if they provide link_off() and do whatever else is
required.

-Scott
Joakim Tjernlund - Nov. 23, 2010, 8:22 p.m.
Scott Wood <scottwood@freescale.com> wrote on 2010/11/23 21:17:12:
>
> On Tue, 23 Nov 2010 21:08:37 +0100
> Joakim Tjernlund <joakim.tjernlund@transmode.se> wrote:
>
> > Scott Wood <scottwood@freescale.com> wrote on 2010/11/23 20:32:32:
> > > On Tue, 23 Nov 2010 19:48:48 +0100
> > > Joakim Tjernlund <Joakim.Tjernlund@transmode.se> wrote:
> > >
> > > > diff --git a/include/common.h b/include/common.h
> > > > index 8bca04f..f257ea4 100644
> > > > --- a/include/common.h
> > > > +++ b/include/common.h
> > > > @@ -94,6 +94,9 @@ typedef volatile unsigned char   vu_char;
> > > >  #ifdef CONFIG_MPC83xx
> > > >  #include <mpc83xx.h>
> > > >  #include <asm/immap_83xx.h>
> > > > +const void * link_off(const void *);
> > > > +#else
> > > > +#define link_off(x) ((const void *)(x))
> > > >  #endif
> > >
> > > What is special about 83xx?
> >
> > Nothing, just it is the first one.
> > >
> > > If it's just that 83xx is the only one that this type of relocation has
> > > been enabled on so far, define a symbol for that.
> >
> > there is a
> > #define LINK_OFF(x) ((__typeof__(x))link_off(x))
> > already but I am guessing you mean something else.
> > Perhaps a dummy link_off for other targets? Don't think
> > that is any better.
>
> I mean instead of this:
>
> #ifdef CONFIG_MPC83xx
> ...unrelated stuff...
> const void *link_off(const void *ptr);
> #else
> #define link_off(x) ((const void *)(x));
> #endif
>
> do something like this:
>
> #ifdef CONFIG_RELOC_PIC
> const void *link_off(const void *ptr);
> #else
> #define link_off(x) ((const void *)(x));
> #endif
>
> ...with CONFIG_RELOC_PIC defined in a board config file and also
> controlling whether this mechanism is enabled at all.  Boards could
> enable it as they verify that they have the proper manual relocations
> (or just leave it off, if they don't think it's worth it) -- including
> non-83xx targets if they provide link_off() and do whatever else is
> required.

Ah yes, will be in my cleanup later on.

Patch

diff --git a/arch/powerpc/cpu/mpc83xx/start.S b/arch/powerpc/cpu/mpc83xx/start.S
index 3cac147..ec65f40 100644
--- a/arch/powerpc/cpu/mpc83xx/start.S
+++ b/arch/powerpc/cpu/mpc83xx/start.S
@@ -427,6 +427,31 @@  _end_of_vectors:
 
 	. = 0x3000
 
+	.globl	link_off /* const void * link_off(const void * ptr) */
+	.type	link_off, @function
+	/*
+	 * Calculates the offset between link address and load address
+	 * and subtracs the offset to from its argument(r3)
+	 * This function must be where _GOT2_TABLE_ is defined
+	 */
+link_off:
+	/* GOT hand coded as we cannot clobber r12 */
+	mflr	r4
+	bl	1f
+	.text	2
+0:	.long	.LCTOC1-1f
+	.text
+1:	mflr	r6
+	lwz	r0,0b-1b(r6)
+	add	r6,r0,r6
+	mtlr	r4
+	la	r4,.L__GOT2_TABLE_(r6) /* addi	r4,r6,.L__GOT2_TABLE_ */
+	lwz	r5,.L__GOT2_TABLE_(r6)
+	sub	r4,r5,r4 /* r4 - r5 */
+	sub	r3,r3,r4 /* r4 - r3 */
+	blr
+	.size	link_off, .-link_off
+
 /*
  * This code finishes saving the registers to the exception frame
  * and jumps to the appropriate handler for the exception.
diff --git a/include/common.h b/include/common.h
index 8bca04f..f257ea4 100644
--- a/include/common.h
+++ b/include/common.h
@@ -94,6 +94,9 @@  typedef volatile unsigned char	vu_char;
 #ifdef CONFIG_MPC83xx
 #include <mpc83xx.h>
 #include <asm/immap_83xx.h>
+const void * link_off(const void *);
+#else
+#define link_off(x) ((const void *)(x))
 #endif
 #ifdef	CONFIG_4xx
 #include <ppc4xx.h>
@@ -111,6 +114,8 @@  typedef volatile unsigned char	vu_char;
 #include <asm/arch/hardware.h>
 #endif
 
+#define LINK_OFF(x) ((__typeof__(x))link_off(x))
+
 #include <part.h>
 #include <flash.h>
 #include <image.h>