code-patching.c (aaddd3eacaeaef3503035750b3f21ac2bfe97cbf) | code-patching.c (e7a57273c6407bb6903fbaddec8c2119bf318617) |
---|---|
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 | 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 |
14void create_instruction(unsigned long addr, unsigned int instr) | 14void patch_instruction(unsigned int *addr, unsigned int instr) |
15{ | 15{ |
16 unsigned int *p; 17 p = (unsigned int *)addr; 18 *p = instr; 19 asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (p)); | 16 *addr = instr; 17 asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr)); |
20} 21 | 18} 19 |
22void create_branch(unsigned long addr, unsigned long target, int flags) | 20void patch_branch(unsigned int *addr, unsigned long target, int flags) |
23{ | 21{ |
22 patch_instruction(addr, create_branch(addr, target, flags)); 23} 24 25unsigned int create_branch(const unsigned int *addr, 26 unsigned long target, int flags) 27{ |
|
24 unsigned int instruction; 25 26 if (! (flags & BRANCH_ABSOLUTE)) | 28 unsigned int instruction; 29 30 if (! (flags & BRANCH_ABSOLUTE)) |
27 target = target - addr; | 31 target = target - (unsigned long)addr; |
28 29 /* Mask out the flags and target, so they don't step on each other. */ 30 instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC); 31 | 32 33 /* Mask out the flags and target, so they don't step on each other. */ 34 instruction = 0x48000000 | (flags & 0x3) | (target & 0x03FFFFFC); 35 |
32 create_instruction(addr, instruction); | 36 return instruction; |
33} | 37} |