638dde313cbc1cf953b18b2fcbf25f9820bcf132
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / lib / code-patching.c
1 /*
2  *  Copyright 2008 Michael Ellerman, IBM Corporation.
3  *
4  *  This program is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU General Public License
6  *  as published by the Free Software Foundation; either version
7  *  2 of the License, or (at your option) any later version.
8  */
9
10 #include <linux/kernel.h>
11 #include <asm/code-patching.h>
12
13
14 void patch_instruction(unsigned int *addr, unsigned int instr)
15 {
16         *addr = instr;
17         asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr));
18 }
19
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)
27 {
28         unsigned int instruction;
29
30         if (! (flags & BRANCH_ABSOLUTE))
31                 target = target - (unsigned long)addr;
32
33         /* Mask out the flags and target, so they don't step on each other. */
34         instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC);
35
36         return instruction;
37 }