diff options
Diffstat (limited to 'arch/powerpc/include')
-rw-r--r-- | arch/powerpc/include/asm/paca.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/ppc-opcode.h | 8 | ||||
-rw-r--r-- | arch/powerpc/include/asm/ppc_asm.h | 19 | ||||
-rw-r--r-- | arch/powerpc/include/asm/sections.h | 5 |
4 files changed, 34 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 0ab3511a47d7..da0377f46597 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -88,7 +88,9 @@ struct paca_struct { u16 lock_token; /* Constant 0x8000, used in locks */ #endif +#ifndef CONFIG_PPC_KERNEL_PCREL u64 kernel_toc; /* Kernel TOC address */ +#endif u64 kernelbase; /* Base address of kernel */ u64 kernel_msr; /* MSR while running in kernel */ void *emergency_sp; /* pointer to emergency stack */ diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 21e33e46f4b8..ca5a0da7df4e 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -120,11 +120,18 @@ * 16-bit immediate helper macros: HA() is for use with sign-extending instrs * (e.g. LD, ADDI). If the bottom 16 bits is "-ve", add another bit into the * top half to negate the effect (i.e. 0xffff + 1 = 0x(1)0000). + * + * XXX: should these mask out possible sign bits? */ #define IMM_H(i) ((uintptr_t)(i)>>16) #define IMM_HA(i) (((uintptr_t)(i)>>16) + \ (((uintptr_t)(i) & 0x8000) >> 15)) +/* + * 18-bit immediate helper for prefix 18-bit upper immediate si0 field. + */ +#define IMM_H18(i) (((uintptr_t)(i)>>16) & 0x3ffff) + /* opcode and xopcode for instructions */ #define OP_PREFIX 1 @@ -306,6 +313,7 @@ #define PPC_PREFIX_8LS 0x04000000 /* Prefixed instructions */ +#define PPC_INST_PADDI 0x38000000 #define PPC_INST_PLD 0xe4000000 #define PPC_INST_PSTD 0xf4000000 diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index f08b7990a69d..4dfabf4ef966 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -183,7 +183,11 @@ /* * Used to name C functions called from asm */ +#if defined(CONFIG_PPC_KERNEL_PCREL) && !defined(MODULE) +#define CFUNC(name) name@notoc +#else #define CFUNC(name) name +#endif /* * We use __powerpc64__ here because we want the compat VDSO to use the 32-bit @@ -212,6 +216,9 @@ .globl name; \ name: +#if defined(CONFIG_PPC_KERNEL_PCREL) && !defined(MODULE) +#define _GLOBAL_TOC _GLOBAL +#else #define _GLOBAL_TOC(name) \ .align 2 ; \ .type name,@function; \ @@ -220,6 +227,7 @@ name: \ 0: addis r2,r12,(.TOC.-0b)@ha; \ addi r2,r2,(.TOC.-0b)@l; \ .localentry name,.-name +#endif #define DOTSYM(a) a @@ -351,8 +359,13 @@ n: #ifdef __powerpc64__ +#ifdef CONFIG_PPC_KERNEL_PCREL +#define __LOAD_PACA_TOC(reg) \ + li reg,-1 +#else #define __LOAD_PACA_TOC(reg) \ ld reg,PACATOC(r13) +#endif #define LOAD_PACA_TOC() \ __LOAD_PACA_TOC(r2) @@ -366,9 +379,15 @@ n: ori reg, reg, (expr)@l; \ rldimi reg, tmp, 32, 0 +#if defined(CONFIG_PPC_KERNEL_PCREL) && !defined(MODULE) +#define LOAD_REG_ADDR(reg,name) \ + pla reg,name@pcrel + +#else #define LOAD_REG_ADDR(reg,name) \ addis reg,r2,name@toc@ha; \ addi reg,reg,name@toc@l +#endif #ifdef CONFIG_PPC_BOOK3E_64 /* diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index 9c00c9c0ca8f..4e1f548c8d37 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h @@ -46,10 +46,15 @@ extern char end_virt_trampolines[]; */ static inline unsigned long kernel_toc_addr(void) { +#ifdef CONFIG_PPC_KERNEL_PCREL + BUILD_BUG(); + return -1UL; +#else unsigned long toc_ptr; asm volatile("mr %0, 2" : "=r" (toc_ptr)); return toc_ptr; +#endif } static inline int overlaps_interrupt_vector_text(unsigned long start, |