diff options
Diffstat (limited to 'arch/powerpc/lib/code-patching.c')
-rw-r--r-- | arch/powerpc/lib/code-patching.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 7afae88ed1d4..638dde313cbc 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c | |||
@@ -11,23 +11,27 @@ | |||
11 | #include <asm/code-patching.h> | 11 | #include <asm/code-patching.h> |
12 | 12 | ||
13 | 13 | ||
14 | void create_instruction(unsigned long addr, unsigned int instr) | 14 | void patch_instruction(unsigned int *addr, unsigned int instr) |
15 | { | 15 | { |
16 | unsigned int *p; | 16 | *addr = instr; |
17 | p = (unsigned int *)addr; | 17 | asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr)); |
18 | *p = instr; | ||
19 | asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (p)); | ||
20 | } | 18 | } |
21 | 19 | ||
22 | void create_branch(unsigned long addr, unsigned long target, int flags) | 20 | void patch_branch(unsigned int *addr, unsigned long target, int flags) |
21 | { | ||
22 | patch_instruction(addr, create_branch(addr, target, flags)); | ||
23 | } | ||
24 | |||
25 | unsigned int create_branch(const unsigned int *addr, | ||
26 | unsigned long target, int flags) | ||
23 | { | 27 | { |
24 | unsigned int instruction; | 28 | unsigned int instruction; |
25 | 29 | ||
26 | if (! (flags & BRANCH_ABSOLUTE)) | 30 | if (! (flags & BRANCH_ABSOLUTE)) |
27 | target = target - addr; | 31 | target = target - (unsigned long)addr; |
28 | 32 | ||
29 | /* Mask out the flags and target, so they don't step on each other. */ | 33 | /* Mask out the flags and target, so they don't step on each other. */ |
30 | instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC); | 34 | instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC); |
31 | 35 | ||
32 | create_instruction(addr, instruction); | 36 | return instruction; |
33 | } | 37 | } |