Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0947b2f3 authored by Huang, Ying's avatar Huang, Ying Committed by Ingo Molnar
Browse files

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: default avatarHuang Ying <ying.huang@intel.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 4138cc34
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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);

+85 −2
Original line number Diff line number Diff line
@@ -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;
	}
+3 −0
Original line number Diff line number Diff line
@@ -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);