10 #include <linux/kernel.h>
16 #include <asm/uaccess.h>
26 asm (
"dcbst 0, %0; sync; icbi 0,%0; sync; isync" : :
"r" (
addr));
43 offset = offset - (
unsigned long)addr;
50 instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC);
63 offset = offset - (
unsigned long)addr;
70 instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC);
75 static unsigned int branch_opcode(
unsigned int instr)
77 return (instr >> 26) & 0x3F;
80 static int instr_is_branch_iform(
unsigned int instr)
82 return branch_opcode(instr) == 18;
85 static int instr_is_branch_bform(
unsigned int instr)
87 return branch_opcode(instr) == 16;
95 return instr_is_branch_iform(instr) || instr_is_branch_bform(instr);
98 static unsigned long branch_iform_target(
const unsigned int *instr)
102 imm = *instr & 0x3FFFFFC;
109 imm += (
unsigned long)instr;
111 return (
unsigned long)imm;
114 static unsigned long branch_bform_target(
const unsigned int *instr)
118 imm = *instr & 0xFFFC;
124 if ((*instr & BRANCH_ABSOLUTE) == 0)
125 imm += (
unsigned long)instr;
127 return (
unsigned long)imm;
132 if (instr_is_branch_iform(*instr))
133 return branch_iform_target(instr);
134 else if (instr_is_branch_bform(*instr))
135 return branch_bform_target(instr);
142 if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr))
154 if (instr_is_branch_iform(*src))
156 else if (instr_is_branch_bform(*src))
163 #ifdef CONFIG_CODE_PATCHING_SELFTEST
165 static void __init test_trampoline(
void)
171 if (!(x)) printk("code-patching: test failed at line %d\n", __LINE__);
173 static void __init test_branch_iform(
void)
178 addr = (
unsigned long)&instr;
181 check(instr_is_branch_iform(0x48000000));
183 check(instr_is_branch_iform(0x4bffffff));
185 check(!instr_is_branch_iform(0xcbffffff));
187 check(!instr_is_branch_iform(0x7bffffff));
190 check(instr_is_branch_iform(0x48000001));
192 check(instr_is_branch_iform(0x4bfffffd));
194 check(instr_is_branch_iform(0x4bff00fd));
196 check(!instr_is_branch_iform(0x7bfffffd));
245 check(instr == 0x48000000);
248 static void __init test_create_function_call(
void)
254 iptr = (
unsigned int *)ppc_function_entry(test_trampoline);
255 dest = ppc_function_entry(test_create_function_call);
260 static void __init test_branch_bform(
void)
266 addr = (
unsigned long)iptr;
269 check(instr_is_branch_bform(0x40000000));
271 check(instr_is_branch_bform(0x43ffffff));
273 check(!instr_is_branch_bform(0xc3ffffff));
275 check(!instr_is_branch_bform(0x7bffffff));
327 check(instr == 0x43FF0000);
330 static void __init test_translate_branch(
void)
343 addr = (
unsigned long)p;
352 addr = (
unsigned long)p;
358 check(*q == 0x4a000000);
362 addr = (
unsigned long)p;
368 check(*q == 0x49fffffc);
372 addr = 0x1000000 + (
unsigned long)buf;
381 addr = 0x2000000 + (
unsigned long)buf;
393 addr = (
unsigned long)p;
402 addr = (
unsigned long)p;
408 check(*q == 0x43ff8000);
412 addr = (
unsigned long)p;
418 check(*q == 0x43ff7ffc);
422 addr = 0x3000 + (
unsigned long)buf;
431 addr = 0x4000 + (
unsigned long)buf;
442 static int __init test_code_patching(
void)
448 test_create_function_call();
449 test_translate_branch();