]>
Commit | Line | Data |
---|---|---|
51c52e86 ME |
1 | /* |
2 | * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) | |
3 | * | |
4 | * Modifications for ppc64: | |
5 | * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com> | |
6 | * | |
7 | * Copyright 2008 Michael Ellerman, IBM Corporation. | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU General Public License | |
11 | * as published by the Free Software Foundation; either version | |
12 | * 2 of the License, or (at your option) any later version. | |
13 | */ | |
14 | ||
15 | #include <linux/kernel.h> | |
16 | #include <asm/cputable.h> | |
17 | #include <asm/code-patching.h> | |
18 | ||
19 | ||
20 | struct fixup_entry { | |
21 | unsigned long mask; | |
22 | unsigned long value; | |
23 | long start_off; | |
24 | long end_off; | |
fac23fe4 ME |
25 | long alt_start_off; |
26 | long alt_end_off; | |
51c52e86 ME |
27 | }; |
28 | ||
29 | static void patch_feature_section(unsigned long value, struct fixup_entry *fcur) | |
30 | { | |
31 | unsigned int *pstart, *pend, *p; | |
32 | ||
33 | if ((value & fcur->mask) == fcur->value) | |
34 | return; | |
35 | ||
36 | pstart = ((unsigned int *)fcur) + (fcur->start_off / 4); | |
37 | pend = ((unsigned int *)fcur) + (fcur->end_off / 4); | |
38 | ||
39 | for (p = pstart; p < pend; p++) { | |
40 | *p = PPC_NOP_INSTR; | |
41 | asm volatile ("dcbst 0, %0" : : "r" (p)); | |
42 | } | |
43 | asm volatile ("sync" : : : "memory"); | |
44 | for (p = pstart; p < pend; p++) | |
45 | asm volatile ("icbi 0,%0" : : "r" (p)); | |
46 | asm volatile ("sync; isync" : : : "memory"); | |
47 | } | |
48 | ||
49 | void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) | |
50 | { | |
51 | struct fixup_entry *fcur, *fend; | |
52 | ||
53 | fcur = fixup_start; | |
54 | fend = fixup_end; | |
55 | ||
56 | for (; fcur < fend; fcur++) | |
57 | patch_feature_section(value, fcur); | |
58 | } |