mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 23:14:31 +08:00
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>
This commit is contained in:
parent
4138cc3418
commit
0947b2f31c
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user