diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-09-04 05:47:48 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-10-04 15:23:36 -0400 |
commit | f00ec48fadf5e37e7889f14cff900aa70d18b644 (patch) | |
tree | 421cbce97167a78532aa825624f380caade3c0d2 /arch/arm/mm/tlb-v7.S | |
parent | 067173526c3bbc2eaeefcf6b7b2a9d998b9e8042 (diff) |
ARM: Allow SMP kernels to boot on UP systems
UP systems do not implement all the instructions that SMP systems have,
so in order to boot a SMP kernel on a UP system, we need to rewrite
parts of the kernel.
Do this using an 'alternatives' scheme, where the kernel code and data
is modified prior to initialization to replace the SMP instructions,
thereby rendering the problematical code ineffectual. We use the linker
to generate a list of 32-bit word locations and their replacement values,
and run through these replacements when we detect a UP system.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mm/tlb-v7.S')
-rw-r--r-- | arch/arm/mm/tlb-v7.S | 33 |
1 files changed, 12 insertions, 21 deletions
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index f3f288a9546d..53cd5b454673 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
16 | #include <asm/assembler.h> | ||
16 | #include <asm/asm-offsets.h> | 17 | #include <asm/asm-offsets.h> |
17 | #include <asm/page.h> | 18 | #include <asm/page.h> |
18 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
@@ -41,20 +42,15 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
41 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA | 42 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA |
42 | mov r1, r1, lsl #PAGE_SHIFT | 43 | mov r1, r1, lsl #PAGE_SHIFT |
43 | 1: | 44 | 1: |
44 | #ifdef CONFIG_SMP | 45 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
45 | mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable) | 46 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
46 | #else | 47 | |
47 | mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate U MVA | ||
48 | #endif | ||
49 | add r0, r0, #PAGE_SZ | 48 | add r0, r0, #PAGE_SZ |
50 | cmp r0, r1 | 49 | cmp r0, r1 |
51 | blo 1b | 50 | blo 1b |
52 | mov ip, #0 | 51 | mov ip, #0 |
53 | #ifdef CONFIG_SMP | 52 | ALT_SMP(mcr p15, 0, ip, c7, c1, 6) @ flush BTAC/BTB Inner Shareable |
54 | mcr p15, 0, ip, c7, c1, 6 @ flush BTAC/BTB Inner Shareable | 53 | ALT_UP(mcr p15, 0, ip, c7, c5, 6) @ flush BTAC/BTB |
55 | #else | ||
56 | mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB | ||
57 | #endif | ||
58 | dsb | 54 | dsb |
59 | mov pc, lr | 55 | mov pc, lr |
60 | ENDPROC(v7wbi_flush_user_tlb_range) | 56 | ENDPROC(v7wbi_flush_user_tlb_range) |
@@ -74,20 +70,14 @@ ENTRY(v7wbi_flush_kern_tlb_range) | |||
74 | mov r0, r0, lsl #PAGE_SHIFT | 70 | mov r0, r0, lsl #PAGE_SHIFT |
75 | mov r1, r1, lsl #PAGE_SHIFT | 71 | mov r1, r1, lsl #PAGE_SHIFT |
76 | 1: | 72 | 1: |
77 | #ifdef CONFIG_SMP | 73 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
78 | mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable) | 74 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
79 | #else | ||
80 | mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate U MVA | ||
81 | #endif | ||
82 | add r0, r0, #PAGE_SZ | 75 | add r0, r0, #PAGE_SZ |
83 | cmp r0, r1 | 76 | cmp r0, r1 |
84 | blo 1b | 77 | blo 1b |
85 | mov r2, #0 | 78 | mov r2, #0 |
86 | #ifdef CONFIG_SMP | 79 | ALT_SMP(mcr p15, 0, r2, c7, c1, 6) @ flush BTAC/BTB Inner Shareable |
87 | mcr p15, 0, r2, c7, c1, 6 @ flush BTAC/BTB Inner Shareable | 80 | ALT_UP(mcr p15, 0, r2, c7, c5, 6) @ flush BTAC/BTB |
88 | #else | ||
89 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | ||
90 | #endif | ||
91 | dsb | 81 | dsb |
92 | isb | 82 | isb |
93 | mov pc, lr | 83 | mov pc, lr |
@@ -99,5 +89,6 @@ ENDPROC(v7wbi_flush_kern_tlb_range) | |||
99 | ENTRY(v7wbi_tlb_fns) | 89 | ENTRY(v7wbi_tlb_fns) |
100 | .long v7wbi_flush_user_tlb_range | 90 | .long v7wbi_flush_user_tlb_range |
101 | .long v7wbi_flush_kern_tlb_range | 91 | .long v7wbi_flush_kern_tlb_range |
102 | .long v7wbi_tlb_flags | 92 | ALT_SMP(.long v7wbi_tlb_flags_smp) |
93 | ALT_UP(.long v7wbi_tlb_flags_up) | ||
103 | .size v7wbi_tlb_fns, . - v7wbi_tlb_fns | 94 | .size v7wbi_tlb_fns, . - v7wbi_tlb_fns |