summaryrefslogtreecommitdiff
path: root/arch/powerpc/include/asm/ppc_asm.h
diff options
context:
space:
mode:
authorKevin Hao <haokexin@gmail.com>2013-12-24 15:12:05 +0800
committerScott Wood <scottwood@freescale.com>2014-01-09 17:52:15 -0600
commit1c49abec677c7ff495837dbaafad8e12f09c29fc (patch)
tree9a1bef7d4684457e5ff5ba6869e17264a2cf0bc3 /arch/powerpc/include/asm/ppc_asm.h
parent99739611e816716d912ae89a4354237fc39745a6 (diff)
powerpc: introduce macro LOAD_REG_ADDR_PIC
This is used to get the address of a variable when the kernel is not running at the linked or relocated address. Signed-off-by: Kevin Hao <haokexin@gmail.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc/include/asm/ppc_asm.h')
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index f595b98079ee..1279c59624ed 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -295,6 +295,11 @@ n:
* you want to access various offsets within it). On ppc32 this is
* identical to LOAD_REG_IMMEDIATE.
*
+ * LOAD_REG_ADDR_PIC(rn, name)
+ * Loads the address of label 'name' into register 'run'. Use this when
+ * the kernel doesn't run at the linked or relocated address. Please
+ * note that this macro will clobber the lr register.
+ *
* LOAD_REG_ADDRBASE(rn, name)
* ADDROFF(name)
* LOAD_REG_ADDRBASE loads part of the address of label 'name' into
@@ -305,6 +310,14 @@ n:
* LOAD_REG_ADDRBASE(rX, name)
* ld rY,ADDROFF(name)(rX)
*/
+
+/* Be careful, this will clobber the lr register. */
+#define LOAD_REG_ADDR_PIC(reg, name) \
+ bl 0f; \
+0: mflr reg; \
+ addis reg,reg,(name - 0b)@ha; \
+ addi reg,reg,(name - 0b)@l;
+
#ifdef __powerpc64__
#define LOAD_REG_IMMEDIATE(reg,expr) \
lis reg,(expr)@highest; \