aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2014-02-04 00:09:15 -0500
committerAnton Blanchard <anton@samba.org>2014-04-22 20:05:21 -0400
commitc71b7eff426fa7d8fd33e0964a7f79a3b41faff9 (patch)
tree19035b32883d0b554d3b318a80f11f1acc29a485
parent814e4cd98f777c7fa3b42e0468030cd341fb8b6b (diff)
powerpc: Add ABIv2 support to ppc_function_entry
Skip over the well known global entry point code for ABIv2. Signed-off-by: Anton Blanchard <anton@samba.org>
-rw-r--r--arch/powerpc/include/asm/code-patching.h40
1 files changed, 36 insertions, 4 deletions
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 97e02f985df8..37991e154ef8 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -42,15 +42,47 @@ void __patch_exception(int exc, unsigned long addr);
42} while (0) 42} while (0)
43#endif 43#endif
44 44
45#define OP_RT_RA_MASK 0xffff0000UL
46#define LIS_R2 0x3c020000UL
47#define ADDIS_R2_R12 0x3c4c0000UL
48#define ADDI_R2_R2 0x38420000UL
49
45static inline unsigned long ppc_function_entry(void *func) 50static inline unsigned long ppc_function_entry(void *func)
46{ 51{
47#ifdef CONFIG_PPC64 52#if defined(CONFIG_PPC64)
53#if defined(_CALL_ELF) && _CALL_ELF == 2
54 u32 *insn = func;
55
56 /*
57 * A PPC64 ABIv2 function may have a local and a global entry
58 * point. We need to use the local entry point when patching
59 * functions, so identify and step over the global entry point
60 * sequence.
61 *
62 * The global entry point sequence is always of the form:
63 *
64 * addis r2,r12,XXXX
65 * addi r2,r2,XXXX
66 *
67 * A linker optimisation may convert the addis to lis:
68 *
69 * lis r2,XXXX
70 * addi r2,r2,XXXX
71 */
72 if ((((*insn & OP_RT_RA_MASK) == ADDIS_R2_R12) ||
73 ((*insn & OP_RT_RA_MASK) == LIS_R2)) &&
74 ((*(insn+1) & OP_RT_RA_MASK) == ADDI_R2_R2))
75 return (unsigned long)(insn + 2);
76 else
77 return (unsigned long)func;
78#else
48 /* 79 /*
49 * On PPC64 the function pointer actually points to the function's 80 * On PPC64 ABIv1 the function pointer actually points to the
50 * descriptor. The first entry in the descriptor is the address 81 * function's descriptor. The first entry in the descriptor is the
51 * of the function text. 82 * address of the function text.
52 */ 83 */
53 return ((func_descr_t *)func)->entry; 84 return ((func_descr_t *)func)->entry;
85#endif
54#else 86#else
55 return (unsigned long)func; 87 return (unsigned long)func;
56#endif 88#endif