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 | |
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>
-rw-r--r-- | arch/x86/kernel/setup_32.c | 1 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/ioremap_32.c | 87 | ||||
-rw-r--r-- | include/asm-x86/io_32.h | 3 |
4 files changed, 91 insertions, 2 deletions
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 83ba3ca5f431..35db426de300 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -697,6 +697,7 @@ void __init setup_arch(char **cmdline_p) | |||
697 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 697 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
698 | pre_setup_arch_hook(); | 698 | pre_setup_arch_hook(); |
699 | early_cpu_init(); | 699 | early_cpu_init(); |
700 | bt_ioremap_init(); | ||
700 | 701 | ||
701 | #ifdef CONFIG_EFI | 702 | #ifdef CONFIG_EFI |
702 | if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, | 703 | if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 206e3f6800b9..f4e1894367a6 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -429,9 +429,11 @@ static void __init pagetable_init (void) | |||
429 | * Fixed mappings, only the page table structure has to be | 429 | * Fixed mappings, only the page table structure has to be |
430 | * created - mappings will be set by set_fixmap(): | 430 | * created - mappings will be set by set_fixmap(): |
431 | */ | 431 | */ |
432 | bt_ioremap_clear(); | ||
432 | vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; | 433 | vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; |
433 | end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK; | 434 | end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK; |
434 | page_table_range_init(vaddr, end, pgd_base); | 435 | page_table_range_init(vaddr, end, pgd_base); |
436 | bt_ioremap_reset(); | ||
435 | 437 | ||
436 | permanent_kmaps_init(pgd_base); | 438 | permanent_kmaps_init(pgd_base); |
437 | 439 | ||
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 | } |
diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h index db3978846379..f7b733d9ace9 100644 --- a/include/asm-x86/io_32.h +++ b/include/asm-x86/io_32.h | |||
@@ -139,6 +139,9 @@ extern void iounmap(volatile void __iomem *addr); | |||
139 | * mappings, before the real ioremap() is functional. | 139 | * mappings, before the real ioremap() is functional. |
140 | * A boot-time mapping is currently limited to at most 16 pages. | 140 | * A boot-time mapping is currently limited to at most 16 pages. |
141 | */ | 141 | */ |
142 | extern void bt_ioremap_init(void); | ||
143 | extern void bt_ioremap_clear(void); | ||
144 | extern void bt_ioremap_reset(void); | ||
142 | extern void *bt_ioremap(unsigned long offset, unsigned long size); | 145 | extern void *bt_ioremap(unsigned long offset, unsigned long size); |
143 | extern void bt_iounmap(void *addr, unsigned long size); | 146 | extern void bt_iounmap(void *addr, unsigned long size); |
144 | extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); | 147 | extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys); |