|
@@ -328,17 +328,6 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-static int __initdata early_ioremap_debug;
|
|
|
-
|
|
|
-static int __init early_ioremap_debug_setup(char *str)
|
|
|
-{
|
|
|
- early_ioremap_debug = 1;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-early_param("early_ioremap_debug", early_ioremap_debug_setup);
|
|
|
-
|
|
|
-static __initdata int after_paging_init;
|
|
|
static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
|
|
|
|
|
|
static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
|
|
@@ -362,18 +351,11 @@ bool __init is_early_ioremap_ptep(pte_t *ptep)
|
|
|
return ptep >= &bm_pte[0] && ptep < &bm_pte[PAGE_SIZE/sizeof(pte_t)];
|
|
|
}
|
|
|
|
|
|
-static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;
|
|
|
-
|
|
|
void __init early_ioremap_init(void)
|
|
|
{
|
|
|
pmd_t *pmd;
|
|
|
- int i;
|
|
|
|
|
|
- if (early_ioremap_debug)
|
|
|
- printk(KERN_INFO "early_ioremap_init()\n");
|
|
|
-
|
|
|
- for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
|
|
|
- slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
|
|
|
+ early_ioremap_setup();
|
|
|
|
|
|
pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
|
|
|
memset(bm_pte, 0, sizeof(bm_pte));
|
|
@@ -402,13 +384,8 @@ void __init early_ioremap_init(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void __init early_ioremap_reset(void)
|
|
|
-{
|
|
|
- after_paging_init = 1;
|
|
|
-}
|
|
|
-
|
|
|
-static void __init __early_set_fixmap(enum fixed_addresses idx,
|
|
|
- phys_addr_t phys, pgprot_t flags)
|
|
|
+void __init __early_set_fixmap(enum fixed_addresses idx,
|
|
|
+ phys_addr_t phys, pgprot_t flags)
|
|
|
{
|
|
|
unsigned long addr = __fix_to_virt(idx);
|
|
|
pte_t *pte;
|
|
@@ -425,202 +402,3 @@ static void __init __early_set_fixmap(enum fixed_addresses idx,
|
|
|
pte_clear(&init_mm, addr, pte);
|
|
|
__flush_tlb_one(addr);
|
|
|
}
|
|
|
-
|
|
|
-static inline void __init early_set_fixmap(enum fixed_addresses idx,
|
|
|
- phys_addr_t phys, pgprot_t prot)
|
|
|
-{
|
|
|
- if (after_paging_init)
|
|
|
- __set_fixmap(idx, phys, prot);
|
|
|
- else
|
|
|
- __early_set_fixmap(idx, phys, prot);
|
|
|
-}
|
|
|
-
|
|
|
-static inline void __init early_clear_fixmap(enum fixed_addresses idx)
|
|
|
-{
|
|
|
- if (after_paging_init)
|
|
|
- clear_fixmap(idx);
|
|
|
- else
|
|
|
- __early_set_fixmap(idx, 0, __pgprot(0));
|
|
|
-}
|
|
|
-
|
|
|
-static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata;
|
|
|
-static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
|
|
|
-
|
|
|
-void __init fixup_early_ioremap(void)
|
|
|
-{
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
|
|
|
- if (prev_map[i]) {
|
|
|
- WARN_ON(1);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- early_ioremap_init();
|
|
|
-}
|
|
|
-
|
|
|
-static int __init check_early_ioremap_leak(void)
|
|
|
-{
|
|
|
- int count = 0;
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
|
|
|
- if (prev_map[i])
|
|
|
- count++;
|
|
|
-
|
|
|
- if (!count)
|
|
|
- return 0;
|
|
|
- WARN(1, KERN_WARNING
|
|
|
- "Debug warning: early ioremap leak of %d areas detected.\n",
|
|
|
- count);
|
|
|
- printk(KERN_WARNING
|
|
|
- "please boot with early_ioremap_debug and report the dmesg.\n");
|
|
|
-
|
|
|
- return 1;
|
|
|
-}
|
|
|
-late_initcall(check_early_ioremap_leak);
|
|
|
-
|
|
|
-static void __init __iomem *
|
|
|
-__early_ioremap(resource_size_t phys_addr, unsigned long size, pgprot_t prot)
|
|
|
-{
|
|
|
- unsigned long offset;
|
|
|
- resource_size_t last_addr;
|
|
|
- unsigned int nrpages;
|
|
|
- enum fixed_addresses idx;
|
|
|
- int i, slot;
|
|
|
-
|
|
|
- WARN_ON(system_state != SYSTEM_BOOTING);
|
|
|
-
|
|
|
- slot = -1;
|
|
|
- for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
|
|
|
- if (!prev_map[i]) {
|
|
|
- slot = i;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (slot < 0) {
|
|
|
- printk(KERN_INFO "%s(%08llx, %08lx) not found slot\n",
|
|
|
- __func__, (u64)phys_addr, size);
|
|
|
- WARN_ON(1);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- if (early_ioremap_debug) {
|
|
|
- printk(KERN_INFO "%s(%08llx, %08lx) [%d] => ",
|
|
|
- __func__, (u64)phys_addr, size, slot);
|
|
|
- dump_stack();
|
|
|
- }
|
|
|
-
|
|
|
- /* Don't allow wraparound or zero size */
|
|
|
- last_addr = phys_addr + size - 1;
|
|
|
- if (!size || last_addr < phys_addr) {
|
|
|
- WARN_ON(1);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- prev_size[slot] = size;
|
|
|
- /*
|
|
|
- * Mappings have to be page-aligned
|
|
|
- */
|
|
|
- offset = phys_addr & ~PAGE_MASK;
|
|
|
- phys_addr &= PAGE_MASK;
|
|
|
- size = PAGE_ALIGN(last_addr + 1) - phys_addr;
|
|
|
-
|
|
|
- /*
|
|
|
- * Mappings have to fit in the FIX_BTMAP area.
|
|
|
- */
|
|
|
- nrpages = size >> PAGE_SHIFT;
|
|
|
- if (nrpages > NR_FIX_BTMAPS) {
|
|
|
- WARN_ON(1);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Ok, go for it..
|
|
|
- */
|
|
|
- idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
|
|
|
- while (nrpages > 0) {
|
|
|
- early_set_fixmap(idx, phys_addr, prot);
|
|
|
- phys_addr += PAGE_SIZE;
|
|
|
- --idx;
|
|
|
- --nrpages;
|
|
|
- }
|
|
|
- if (early_ioremap_debug)
|
|
|
- printk(KERN_CONT "%08lx + %08lx\n", offset, slot_virt[slot]);
|
|
|
-
|
|
|
- prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]);
|
|
|
- return prev_map[slot];
|
|
|
-}
|
|
|
-
|
|
|
-/* Remap an IO device */
|
|
|
-void __init __iomem *
|
|
|
-early_ioremap(resource_size_t phys_addr, unsigned long size)
|
|
|
-{
|
|
|
- return __early_ioremap(phys_addr, size, PAGE_KERNEL_IO);
|
|
|
-}
|
|
|
-
|
|
|
-/* Remap memory */
|
|
|
-void __init *early_memremap(resource_size_t phys_addr, unsigned long size)
|
|
|
-{
|
|
|
- return (__force void *)__early_ioremap(phys_addr, size, PAGE_KERNEL);
|
|
|
-}
|
|
|
-
|
|
|
-void __init early_iounmap(void __iomem *addr, unsigned long size)
|
|
|
-{
|
|
|
- unsigned long virt_addr;
|
|
|
- unsigned long offset;
|
|
|
- unsigned int nrpages;
|
|
|
- enum fixed_addresses idx;
|
|
|
- int i, slot;
|
|
|
-
|
|
|
- slot = -1;
|
|
|
- for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
|
|
|
- if (prev_map[i] == addr) {
|
|
|
- slot = i;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (slot < 0) {
|
|
|
- printk(KERN_INFO "early_iounmap(%p, %08lx) not found slot\n",
|
|
|
- addr, size);
|
|
|
- WARN_ON(1);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (prev_size[slot] != size) {
|
|
|
- printk(KERN_INFO "early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n",
|
|
|
- addr, size, slot, prev_size[slot]);
|
|
|
- WARN_ON(1);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (early_ioremap_debug) {
|
|
|
- printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr,
|
|
|
- size, slot);
|
|
|
- dump_stack();
|
|
|
- }
|
|
|
-
|
|
|
- virt_addr = (unsigned long)addr;
|
|
|
- if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN)) {
|
|
|
- WARN_ON(1);
|
|
|
- return;
|
|
|
- }
|
|
|
- offset = virt_addr & ~PAGE_MASK;
|
|
|
- nrpages = PAGE_ALIGN(offset + size) >> PAGE_SHIFT;
|
|
|
-
|
|
|
- idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
|
|
|
- while (nrpages > 0) {
|
|
|
- early_clear_fixmap(idx);
|
|
|
- --idx;
|
|
|
- --nrpages;
|
|
|
- }
|
|
|
- prev_map[slot] = NULL;
|
|
|
-}
|
|
|
-
|
|
|
-void __init early_memunmap(void *addr, unsigned long size)
|
|
|
-{
|
|
|
- early_iounmap((__force void __iomem *)addr, size);
|
|
|
-}
|