diff options
author | Huang, Ying <ying.huang@intel.com> | 2008-01-30 07:33:44 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:33:44 -0500 |
commit | 0947b2f31ca1ea1211d3cde2dbd8fcec579ef395 (patch) | |
tree | 557cfdb5610e98609eaa02453ed23a8994fd1f2d /arch/x86/mm/ioremap_32.c | |
parent | 4138cc3418f5eaa7524ff8e927102863f1ba0ea5 (diff) |
i386 boot: replace boot_ioremap with enhanced bt_ioremap - enhance bt_ioremap
This patch makes it possible for bt_ioremap() to be used before
paging_init(), via providing an early implementation of set_fixmap()
that can be used before paging_init().
This way boot_ioremap() can be replaced by bt_ioremap().
Signed-off-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/mm/ioremap_32.c')
-rw-r--r-- | arch/x86/mm/ioremap_32.c | 87 |
1 files changed, 85 insertions, 2 deletions
diff --git a/arch/x86/mm/ioremap_32.c b/arch/x86/mm/ioremap_32.c index ef0f6a452ee1..fd1f5b6cfa20 100644 --- a/arch/x86/mm/ioremap_32.c +++ b/arch/x86/mm/ioremap_32.c | |||
@@ -208,6 +208,89 @@ void iounmap(volatile void __iomem *addr) | |||
208 | } | 208 | } |
209 | EXPORT_SYMBOL(iounmap); | 209 | EXPORT_SYMBOL(iounmap); |
210 | 210 | ||
211 | static __initdata int after_paging_init; | ||
212 | static __initdata unsigned long bm_pte[1024] | ||
213 | __attribute__((aligned(PAGE_SIZE))); | ||
214 | |||
215 | static inline unsigned long * __init bt_ioremap_pgd(unsigned long addr) | ||
216 | { | ||
217 | return (unsigned long *)swapper_pg_dir + ((addr >> 22) & 1023); | ||
218 | } | ||
219 | |||
220 | static inline unsigned long * __init bt_ioremap_pte(unsigned long addr) | ||
221 | { | ||
222 | return bm_pte + ((addr >> PAGE_SHIFT) & 1023); | ||
223 | } | ||
224 | |||
225 | void __init bt_ioremap_init(void) | ||
226 | { | ||
227 | unsigned long *pgd; | ||
228 | |||
229 | pgd = bt_ioremap_pgd(fix_to_virt(FIX_BTMAP_BEGIN)); | ||
230 | *pgd = __pa(bm_pte) | _PAGE_TABLE; | ||
231 | memset(bm_pte, 0, sizeof(bm_pte)); | ||
232 | BUG_ON(pgd != bt_ioremap_pgd(fix_to_virt(FIX_BTMAP_END))); | ||
233 | } | ||
234 | |||
235 | void __init bt_ioremap_clear(void) | ||
236 | { | ||
237 | unsigned long *pgd; | ||
238 | |||
239 | pgd = bt_ioremap_pgd(fix_to_virt(FIX_BTMAP_BEGIN)); | ||
240 | *pgd = 0; | ||
241 | __flush_tlb_all(); | ||
242 | } | ||
243 | |||
244 | void __init bt_ioremap_reset(void) | ||
245 | { | ||
246 | enum fixed_addresses idx; | ||
247 | unsigned long *pte, phys, addr; | ||
248 | |||
249 | after_paging_init = 1; | ||
250 | for (idx = FIX_BTMAP_BEGIN; idx <= FIX_BTMAP_END; idx--) { | ||
251 | addr = fix_to_virt(idx); | ||
252 | pte = bt_ioremap_pte(addr); | ||
253 | if (!*pte & _PAGE_PRESENT) { | ||
254 | phys = *pte & PAGE_MASK; | ||
255 | set_fixmap(idx, phys); | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | static void __init __bt_set_fixmap(enum fixed_addresses idx, | ||
261 | unsigned long phys, pgprot_t flags) | ||
262 | { | ||
263 | unsigned long *pte, addr = __fix_to_virt(idx); | ||
264 | |||
265 | if (idx >= __end_of_fixed_addresses) { | ||
266 | BUG(); | ||
267 | return; | ||
268 | } | ||
269 | pte = bt_ioremap_pte(addr); | ||
270 | if (pgprot_val(flags)) | ||
271 | *pte = (phys & PAGE_MASK) | pgprot_val(flags); | ||
272 | else | ||
273 | *pte = 0; | ||
274 | __flush_tlb_one(addr); | ||
275 | } | ||
276 | |||
277 | static inline void __init bt_set_fixmap(enum fixed_addresses idx, | ||
278 | unsigned long phys) | ||
279 | { | ||
280 | if (after_paging_init) | ||
281 | set_fixmap(idx, phys); | ||
282 | else | ||
283 | __bt_set_fixmap(idx, phys, PAGE_KERNEL); | ||
284 | } | ||
285 | |||
286 | static inline void __init bt_clear_fixmap(enum fixed_addresses idx) | ||
287 | { | ||
288 | if (after_paging_init) | ||
289 | clear_fixmap(idx); | ||
290 | else | ||
291 | __bt_set_fixmap(idx, 0, __pgprot(0)); | ||
292 | } | ||
293 | |||
211 | void __init *bt_ioremap(unsigned long phys_addr, unsigned long size) | 294 | void __init *bt_ioremap(unsigned long phys_addr, unsigned long size) |
212 | { | 295 | { |
213 | unsigned long offset, last_addr; | 296 | unsigned long offset, last_addr; |
@@ -244,7 +327,7 @@ void __init *bt_ioremap(unsigned long phys_addr, unsigned long size) | |||
244 | */ | 327 | */ |
245 | idx = FIX_BTMAP_BEGIN; | 328 | idx = FIX_BTMAP_BEGIN; |
246 | while (nrpages > 0) { | 329 | while (nrpages > 0) { |
247 | set_fixmap(idx, phys_addr); | 330 | bt_set_fixmap(idx, phys_addr); |
248 | phys_addr += PAGE_SIZE; | 331 | phys_addr += PAGE_SIZE; |
249 | --idx; | 332 | --idx; |
250 | --nrpages; | 333 | --nrpages; |
@@ -267,7 +350,7 @@ void __init bt_iounmap(void *addr, unsigned long size) | |||
267 | 350 | ||
268 | idx = FIX_BTMAP_BEGIN; | 351 | idx = FIX_BTMAP_BEGIN; |
269 | while (nrpages > 0) { | 352 | while (nrpages > 0) { |
270 | clear_fixmap(idx); | 353 | bt_clear_fixmap(idx); |
271 | --idx; | 354 | --idx; |
272 | --nrpages; | 355 | --nrpages; |
273 | } | 356 | } |