aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/head_32.S
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-02-18 04:13:51 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-18 04:13:51 -0500
commitd01447b3197c2c470a14666be2c640407bbbfec7 (patch)
tree06d1b83868e4d3971b781b45607b124718ee2ec0 /arch/sh/kernel/head_32.S
parent2e450643d70b62e0192577681b227d7d5d2efa45 (diff)
sh: Merge legacy and dynamic PMB modes.
This implements a bit of rework for the PMB code, which permits us to kill off the legacy PMB mode completely. Rather than trusting the boot loader to do the right thing, we do a quick verification of the PMB contents to determine whether to have the kernel setup the initial mappings or whether it needs to mangle them later on instead. If we're booting from legacy mappings, the kernel will now take control of them and make them match the kernel's initial mapping configuration. This is accomplished by breaking the initialization phase out in to multiple steps: synchronization, merging, and resizing. With the recent rework, the synchronization code establishes page links for compound mappings already, so we build on top of this for promoting mappings and reclaiming unused slots. At the same time, the changes introduced for the uncached helpers also permit us to dynamically resize the uncached mapping without any particular headaches. The smallest page size is more than sufficient for mapping all of kernel text, and as we're careful not to jump to any far off locations in the setup code the mapping can safely be resized regardless of whether we are executing from it or not. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/head_32.S')
-rw-r--r--arch/sh/kernel/head_32.S42
1 files changed, 38 insertions, 4 deletions
diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 79ff39517f8e..fe0b743881b0 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -85,7 +85,7 @@ ENTRY(_stext)
85 ldc r0, r7_bank ! ... and initial thread_info 85 ldc r0, r7_bank ! ... and initial thread_info
86#endif 86#endif
87 87
88#if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) 88#ifdef CONFIG_PMB
89/* 89/*
90 * Reconfigure the initial PMB mappings setup by the hardware. 90 * Reconfigure the initial PMB mappings setup by the hardware.
91 * 91 *
@@ -139,7 +139,6 @@ ENTRY(_stext)
139 mov.l r0, @r1 139 mov.l r0, @r1
140 140
141 mov.l .LMEMORY_SIZE, r5 141 mov.l .LMEMORY_SIZE, r5
142 mov r5, r7
143 142
144 mov #PMB_E_SHIFT, r0 143 mov #PMB_E_SHIFT, r0
145 mov #0x1, r4 144 mov #0x1, r4
@@ -150,6 +149,40 @@ ENTRY(_stext)
150 mov.l .LFIRST_ADDR_ENTRY, r2 149 mov.l .LFIRST_ADDR_ENTRY, r2
151 mov.l .LPMB_ADDR, r3 150 mov.l .LPMB_ADDR, r3
152 151
152 /*
153 * First we need to walk the PMB and figure out if there are any
154 * existing mappings that match the initial mappings VPN/PPN.
155 * If these have already been established by the bootloader, we
156 * don't bother setting up new entries here, and let the late PMB
157 * initialization take care of things instead.
158 *
159 * Note that we may need to coalesce and merge entries in order
160 * to reclaim more available PMB slots, which is much more than
161 * we want to do at this early stage.
162 */
163 mov #0, r10
164 mov #NR_PMB_ENTRIES, r9
165
166 mov r1, r7 /* temporary PMB_DATA iter */
167
168.Lvalidate_existing_mappings:
169
170 mov.l @r7, r8
171 and r0, r8
172 cmp/eq r0, r8 /* Check for valid __MEMORY_START mappings */
173 bt .Lpmb_done
174
175 add #1, r10 /* Increment the loop counter */
176 cmp/eq r9, r10
177 bf/s .Lvalidate_existing_mappings
178 add r4, r7 /* Increment to the next PMB_DATA entry */
179
180 /*
181 * If we've fallen through, continue with setting up the initial
182 * mappings.
183 */
184
185 mov r5, r7 /* cached_to_uncached */
153 mov #0, r10 186 mov #0, r10
154 187
155#ifdef CONFIG_UNCACHED_MAPPING 188#ifdef CONFIG_UNCACHED_MAPPING
@@ -252,7 +285,8 @@ ENTRY(_stext)
252 mov.l 6f, r0 285 mov.l 6f, r0
253 icbi @r0 286 icbi @r0
254 287
255#endif /* !CONFIG_PMB_LEGACY */ 288.Lpmb_done:
289#endif /* CONFIG_PMB */
256 290
257#ifndef CONFIG_SH_NO_BSS_INIT 291#ifndef CONFIG_SH_NO_BSS_INIT
258 /* 292 /*
@@ -304,7 +338,7 @@ ENTRY(stack_start)
3046: .long sh_cpu_init 3386: .long sh_cpu_init
3057: .long init_thread_union 3397: .long init_thread_union
306 340
307#if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) 341#ifdef CONFIG_PMB
308.LPMB_ADDR: .long PMB_ADDR 342.LPMB_ADDR: .long PMB_ADDR
309.LPMB_DATA: .long PMB_DATA 343.LPMB_DATA: .long PMB_DATA
310.LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V 344.LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V