Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0947b2f31ca1ea1211d3cde2dbd8fcec579ef395
Commit:     0947b2f31ca1ea1211d3cde2dbd8fcec579ef395
Parent:     4138cc3418f5eaa7524ff8e927102863f1ba0ea5
Author:     Huang, Ying <[EMAIL PROTECTED]>
AuthorDate: Wed Jan 30 13:33:44 2008 +0100
Committer:  Ingo Molnar <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 13:33:44 2008 +0100

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
---
 arch/x86/kernel/setup_32.c |    1 +
 arch/x86/mm/init_32.c      |    2 +
 arch/x86/mm/ioremap_32.c   |   87 +++++++++++++++++++++++++++++++++++++++++++-
 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 83ba3ca..35db426 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)
        memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
        pre_setup_arch_hook();
        early_cpu_init();
+       bt_ioremap_init();
 
 #ifdef CONFIG_EFI
        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 206e3f6..f4e1894 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)
         * Fixed mappings, only the page table structure has to be
         * created - mappings will be set by set_fixmap():
         */
+       bt_ioremap_clear();
        vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
        end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
        page_table_range_init(vaddr, end, pgd_base);
+       bt_ioremap_reset();
 
        permanent_kmaps_init(pgd_base);
 
diff --git a/arch/x86/mm/ioremap_32.c b/arch/x86/mm/ioremap_32.c
index ef0f6a4..fd1f5b6 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)
 }
 EXPORT_SYMBOL(iounmap);
 
+static __initdata int after_paging_init;
+static __initdata unsigned long bm_pte[1024]
+                               __attribute__((aligned(PAGE_SIZE)));
+
+static inline unsigned long * __init bt_ioremap_pgd(unsigned long addr)
+{
+       return (unsigned long *)swapper_pg_dir + ((addr >> 22) & 1023);
+}
+
+static inline unsigned long * __init bt_ioremap_pte(unsigned long addr)
+{
+       return bm_pte + ((addr >> PAGE_SHIFT) & 1023);
+}
+
+void __init bt_ioremap_init(void)
+{
+       unsigned long *pgd;
+
+       pgd = bt_ioremap_pgd(fix_to_virt(FIX_BTMAP_BEGIN));
+       *pgd = __pa(bm_pte) | _PAGE_TABLE;
+       memset(bm_pte, 0, sizeof(bm_pte));
+       BUG_ON(pgd != bt_ioremap_pgd(fix_to_virt(FIX_BTMAP_END)));
+}
+
+void __init bt_ioremap_clear(void)
+{
+       unsigned long *pgd;
+
+       pgd = bt_ioremap_pgd(fix_to_virt(FIX_BTMAP_BEGIN));
+       *pgd = 0;
+       __flush_tlb_all();
+}
+
+void __init bt_ioremap_reset(void)
+{
+       enum fixed_addresses idx;
+       unsigned long *pte, phys, addr;
+
+       after_paging_init = 1;
+       for (idx = FIX_BTMAP_BEGIN; idx <= FIX_BTMAP_END; idx--) {
+               addr = fix_to_virt(idx);
+               pte = bt_ioremap_pte(addr);
+               if (!*pte & _PAGE_PRESENT) {
+                       phys = *pte & PAGE_MASK;
+                       set_fixmap(idx, phys);
+               }
+       }
+}
+
+static void __init __bt_set_fixmap(enum fixed_addresses idx,
+                                  unsigned long phys, pgprot_t flags)
+{
+       unsigned long *pte, addr = __fix_to_virt(idx);
+
+       if (idx >= __end_of_fixed_addresses) {
+               BUG();
+               return;
+       }
+       pte = bt_ioremap_pte(addr);
+       if (pgprot_val(flags))
+               *pte = (phys & PAGE_MASK) | pgprot_val(flags);
+       else
+               *pte = 0;
+       __flush_tlb_one(addr);
+}
+
+static inline void __init bt_set_fixmap(enum fixed_addresses idx,
+                                       unsigned long phys)
+{
+       if (after_paging_init)
+               set_fixmap(idx, phys);
+       else
+               __bt_set_fixmap(idx, phys, PAGE_KERNEL);
+}
+
+static inline void __init bt_clear_fixmap(enum fixed_addresses idx)
+{
+       if (after_paging_init)
+               clear_fixmap(idx);
+       else
+               __bt_set_fixmap(idx, 0, __pgprot(0));
+}
+
 void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
 {
        unsigned long offset, last_addr;
@@ -244,7 +327,7 @@ void __init *bt_ioremap(unsigned long phys_addr, unsigned 
long size)
         */
        idx = FIX_BTMAP_BEGIN;
        while (nrpages > 0) {
-               set_fixmap(idx, phys_addr);
+               bt_set_fixmap(idx, phys_addr);
                phys_addr += PAGE_SIZE;
                --idx;
                --nrpages;
@@ -267,7 +350,7 @@ void __init bt_iounmap(void *addr, unsigned long size)
 
        idx = FIX_BTMAP_BEGIN;
        while (nrpages > 0) {
-               clear_fixmap(idx);
+               bt_clear_fixmap(idx);
                --idx;
                --nrpages;
        }
diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h
index db39788..f7b733d 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);
  * mappings, before the real ioremap() is functional.
  * A boot-time mapping is currently limited to at most 16 pages.
  */
+extern void bt_ioremap_init(void);
+extern void bt_ioremap_clear(void);
+extern void bt_ioremap_reset(void);
 extern void *bt_ioremap(unsigned long offset, unsigned long size);
 extern void bt_iounmap(void *addr, unsigned long size);
 extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to