aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHuang, Ying <ying.huang@intel.com>2008-01-30 07:33:44 -0500
committerIngo Molnar <mingo@elte.hu>2008-01-30 07:33:44 -0500
commit0947b2f31ca1ea1211d3cde2dbd8fcec579ef395 (patch)
tree557cfdb5610e98609eaa02453ed23a8994fd1f2d /arch
parent4138cc3418f5eaa7524ff8e927102863f1ba0ea5 (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')
-rw-r--r--arch/x86/kernel/setup_32.c1
-rw-r--r--arch/x86/mm/init_32.c2
-rw-r--r--arch/x86/mm/ioremap_32.c87
3 files changed, 88 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}
209EXPORT_SYMBOL(iounmap); 209EXPORT_SYMBOL(iounmap);
210 210
211static __initdata int after_paging_init;
212static __initdata unsigned long bm_pte[1024]
213 __attribute__((aligned(PAGE_SIZE)));
214
215static inline unsigned long * __init bt_ioremap_pgd(unsigned long addr)
216{
217 return (unsigned long *)swapper_pg_dir + ((addr >> 22) & 1023);
218}
219
220static inline unsigned long * __init bt_ioremap_pte(unsigned long addr)
221{
222 return bm_pte + ((addr >> PAGE_SHIFT) & 1023);
223}
224
225void __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
235void __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
244void __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
260static 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
277static 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
286static 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
211void __init *bt_ioremap(unsigned long phys_addr, unsigned long size) 294void __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 }