Merge remote-tracking branch 'lsk/v3.10/topic/arm64-misc' into linux-linaro-lsk
Conflicts: arch/arm64/Kconfig
This commit is contained in:
commit
088d7dadf9
18 changed files with 626 additions and 148 deletions
|
|
@ -39,7 +39,7 @@ ffffffbffa000000 ffffffbffaffffff 16MB PCI I/O space
|
|||
|
||||
ffffffbffb000000 ffffffbffbbfffff 12MB [guard]
|
||||
|
||||
ffffffbffbc00000 ffffffbffbdfffff 2MB earlyprintk device
|
||||
ffffffbffbc00000 ffffffbffbdfffff 2MB fixed mappings
|
||||
|
||||
ffffffbffbe00000 ffffffbffbffffff 2MB [guard]
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ fffffdfffa000000 fffffdfffaffffff 16MB PCI I/O space
|
|||
|
||||
fffffdfffb000000 fffffdfffbbfffff 12MB [guard]
|
||||
|
||||
fffffdfffbc00000 fffffdfffbdfffff 2MB earlyprintk device
|
||||
fffffdfffbc00000 fffffdfffbdfffff 2MB fixed mappings
|
||||
|
||||
fffffdfffbe00000 fffffdfffbffffff 2MB [guard]
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ config ARM64
|
|||
select DCACHE_WORD_ACCESS
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
|
||||
select GENERIC_EARLY_IOREMAP
|
||||
select GENERIC_IOMAP
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_IRQ_SHOW
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ generic-y += delay.h
|
|||
generic-y += div64.h
|
||||
generic-y += dma.h
|
||||
generic-y += emergency-restart.h
|
||||
generic-y += early_ioremap.h
|
||||
generic-y += errno.h
|
||||
generic-y += ftrace.h
|
||||
generic-y += hw_irq.h
|
||||
|
|
|
|||
67
arch/arm64/include/asm/fixmap.h
Normal file
67
arch/arm64/include/asm/fixmap.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* fixmap.h: compile-time virtual memory allocation
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1998 Ingo Molnar
|
||||
* Copyright (C) 2013 Mark Salter <msalter@redhat.com>
|
||||
*
|
||||
* Adapted from arch/x86_64 version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ASM_ARM64_FIXMAP_H
|
||||
#define _ASM_ARM64_FIXMAP_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/*
|
||||
* Here we define all the compile-time 'special' virtual
|
||||
* addresses. The point is to have a constant address at
|
||||
* compile time, but to set the physical address only
|
||||
* in the boot process.
|
||||
*
|
||||
* These 'compile-time allocated' memory buffers are
|
||||
* page-sized. Use set_fixmap(idx,phys) to associate
|
||||
* physical memory with fixmap indices.
|
||||
*
|
||||
*/
|
||||
enum fixed_addresses {
|
||||
FIX_EARLYCON_MEM_BASE,
|
||||
__end_of_permanent_fixed_addresses,
|
||||
|
||||
/*
|
||||
* Temporary boot-time mappings, used by early_ioremap(),
|
||||
* before ioremap() is functional.
|
||||
*/
|
||||
#ifdef CONFIG_ARM64_64K_PAGES
|
||||
#define NR_FIX_BTMAPS 4
|
||||
#else
|
||||
#define NR_FIX_BTMAPS 64
|
||||
#endif
|
||||
#define FIX_BTMAPS_SLOTS 7
|
||||
#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
|
||||
|
||||
FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
|
||||
FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
|
||||
__end_of_fixed_addresses
|
||||
};
|
||||
|
||||
#define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
|
||||
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
|
||||
|
||||
#define FIXMAP_PAGE_IO __pgprot(PROT_DEVICE_nGnRE)
|
||||
|
||||
extern void __early_set_fixmap(enum fixed_addresses idx,
|
||||
phys_addr_t phys, pgprot_t flags);
|
||||
|
||||
#define __set_fixmap __early_set_fixmap
|
||||
|
||||
#include <asm-generic/fixmap.h>
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* _ASM_ARM64_FIXMAP_H */
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#include <asm/byteorder.h>
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/early_ioremap.h>
|
||||
|
||||
/*
|
||||
* Generic IO read/write. These perform native-endian accesses.
|
||||
|
|
@ -225,18 +226,11 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
|
|||
extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
|
||||
extern void __iounmap(volatile void __iomem *addr);
|
||||
|
||||
#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY)
|
||||
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
|
||||
#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
|
||||
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
|
||||
#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
|
||||
#define iounmap __iounmap
|
||||
|
||||
#define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF)
|
||||
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PTE_PXN | PTE_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
|
||||
#define ARCH_HAS_IOREMAP_WC
|
||||
#include <asm-generic/iomap.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
#define PAGE_OFFSET (UL(0xffffffffffffffff) << (VA_BITS - 1))
|
||||
#define MODULES_END (PAGE_OFFSET)
|
||||
#define MODULES_VADDR (MODULES_END - SZ_64M)
|
||||
#define EARLYCON_IOBASE (MODULES_VADDR - SZ_4M)
|
||||
#define FIXADDR_TOP (MODULES_VADDR - SZ_2M - PAGE_SIZE)
|
||||
#define TASK_SIZE_64 (UL(1) << VA_BITS)
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
|
|||
|
|
@ -52,61 +52,60 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
|
|||
#endif
|
||||
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
|
||||
|
||||
/*
|
||||
* The pgprot_* and protection_map entries will be fixed up at runtime to
|
||||
* include the cachable and bufferable bits based on memory policy, as well as
|
||||
* any architecture dependent bits like global/ASID and SMP shared mapping
|
||||
* bits.
|
||||
*/
|
||||
#define _PAGE_DEFAULT PTE_TYPE_PAGE | PTE_AF
|
||||
#ifdef CONFIG_SMP
|
||||
#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
|
||||
#define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
|
||||
#else
|
||||
#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF)
|
||||
#define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF)
|
||||
#endif
|
||||
|
||||
extern pgprot_t pgprot_default;
|
||||
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define __pgprot_modify(prot,mask,bits) \
|
||||
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
|
||||
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
|
||||
#define PROT_SECT_NORMAL_EXEC (PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define _MOD_PROT(p, b) __pgprot_modify(p, 0, b)
|
||||
#define _PAGE_DEFAULT (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define PAGE_NONE __pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
|
||||
#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
|
||||
#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
|
||||
#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
|
||||
#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
|
||||
#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY | PTE_WRITE)
|
||||
#define PAGE_KERNEL __pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
|
||||
#define PAGE_KERNEL_EXEC __pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
|
||||
|
||||
#define __PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN)
|
||||
#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
|
||||
#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
|
||||
#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
|
||||
#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
|
||||
#define __PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN)
|
||||
#define PAGE_HYP __pgprot(_PAGE_DEFAULT | PTE_HYP)
|
||||
#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
|
||||
#define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN)
|
||||
|
||||
#define __P000 __PAGE_NONE
|
||||
#define __P001 __PAGE_READONLY
|
||||
#define __P010 __PAGE_COPY
|
||||
#define __P011 __PAGE_COPY
|
||||
#define __P100 __PAGE_EXECONLY
|
||||
#define __P101 __PAGE_READONLY_EXEC
|
||||
#define __P110 __PAGE_COPY_EXEC
|
||||
#define __P111 __PAGE_COPY_EXEC
|
||||
#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
|
||||
#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE)
|
||||
#define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
|
||||
#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
|
||||
#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN)
|
||||
|
||||
#define __S000 __PAGE_NONE
|
||||
#define __S001 __PAGE_READONLY
|
||||
#define __S010 __PAGE_SHARED
|
||||
#define __S011 __PAGE_SHARED
|
||||
#define __S100 __PAGE_EXECONLY
|
||||
#define __S101 __PAGE_READONLY_EXEC
|
||||
#define __S110 __PAGE_SHARED_EXEC
|
||||
#define __S111 __PAGE_SHARED_EXEC
|
||||
#define __P000 PAGE_NONE
|
||||
#define __P001 PAGE_READONLY
|
||||
#define __P010 PAGE_COPY
|
||||
#define __P011 PAGE_COPY
|
||||
#define __P100 PAGE_EXECONLY
|
||||
#define __P101 PAGE_READONLY_EXEC
|
||||
#define __P110 PAGE_COPY_EXEC
|
||||
#define __P111 PAGE_COPY_EXEC
|
||||
|
||||
#define __S000 PAGE_NONE
|
||||
#define __S001 PAGE_READONLY
|
||||
#define __S010 PAGE_SHARED
|
||||
#define __S011 PAGE_SHARED
|
||||
#define __S100 PAGE_EXECONLY
|
||||
#define __S101 PAGE_READONLY_EXEC
|
||||
#define __S110 PAGE_SHARED_EXEC
|
||||
#define __S111 PAGE_SHARED_EXEC
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/*
|
||||
* ZERO_PAGE is a global shared page that is always zero: used
|
||||
* for zero-mapped memory areas etc..
|
||||
|
|
@ -268,6 +267,9 @@ static inline int has_transparent_hugepage(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#define __pgprot_modify(prot,mask,bits) \
|
||||
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
|
||||
|
||||
/*
|
||||
* Mark the prot value as uncacheable and unbufferable.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include <linux/amba/serial.h>
|
||||
#include <linux/serial_reg.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
|
||||
static void __iomem *early_base;
|
||||
static void (*printch)(char ch);
|
||||
|
||||
|
|
@ -141,8 +143,10 @@ static int __init setup_early_printk(char *buf)
|
|||
}
|
||||
/* no options parsing yet */
|
||||
|
||||
if (paddr)
|
||||
early_base = early_io_map(paddr, EARLYCON_IOBASE);
|
||||
if (paddr) {
|
||||
set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr);
|
||||
early_base = (void __iomem *)fix_to_virt(FIX_EARLYCON_MEM_BASE);
|
||||
}
|
||||
|
||||
printch = match->printch;
|
||||
early_console = &early_console_dev;
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ ENDPROC(__calc_phys_offset)
|
|||
* - identity mapping to enable the MMU (low address, TTBR0)
|
||||
* - first few MB of the kernel linear mapping to jump to once the MMU has
|
||||
* been enabled, including the FDT blob (TTBR1)
|
||||
* - UART mapping if CONFIG_EARLY_PRINTK is enabled (TTBR1)
|
||||
* - pgd entry for fixed mappings (TTBR1)
|
||||
*/
|
||||
__create_page_tables:
|
||||
pgtbl x25, x26, x24 // idmap_pg_dir and swapper_pg_dir addresses
|
||||
|
|
@ -460,15 +460,12 @@ __create_page_tables:
|
|||
sub x6, x6, #1 // inclusive range
|
||||
create_block_map x0, x7, x3, x5, x6
|
||||
1:
|
||||
#ifdef CONFIG_EARLY_PRINTK
|
||||
/*
|
||||
* Create the pgd entry for the UART mapping. The full mapping is done
|
||||
* later based earlyprintk kernel parameter.
|
||||
* Create the pgd entry for the fixed mappings.
|
||||
*/
|
||||
ldr x5, =EARLYCON_IOBASE // UART virtual address
|
||||
ldr x5, =FIXADDR_TOP // Fixed mapping virtual address
|
||||
add x0, x26, #2 * PAGE_SIZE // section table address
|
||||
create_pgd_entry x26, x0, x5, x6, x7
|
||||
#endif
|
||||
ret
|
||||
ENDPROC(__create_page_tables)
|
||||
.ltorg
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/elf.h>
|
||||
#include <asm/cputable.h>
|
||||
|
|
@ -412,7 +413,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
*cmdline_p = boot_command_line;
|
||||
|
||||
init_mem_pgprot();
|
||||
early_ioremap_init();
|
||||
|
||||
parse_early_param();
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ static void *__dma_alloc_noncoherent(struct device *dev, size_t size,
|
|||
for (i = 0; i < (size >> PAGE_SHIFT); i++)
|
||||
map[i] = page + i;
|
||||
coherent_ptr = vmap(map, size >> PAGE_SHIFT, VM_MAP,
|
||||
__get_dma_pgprot(attrs, pgprot_default, false));
|
||||
__get_dma_pgprot(attrs, __pgprot(PROT_NORMAL_NC), false));
|
||||
kfree(map);
|
||||
if (!coherent_ptr)
|
||||
goto no_map;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/pgalloc.h>
|
||||
|
||||
static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
|
||||
pgprot_t prot, void *caller)
|
||||
{
|
||||
|
|
@ -82,3 +86,95 @@ void __iounmap(volatile void __iomem *io_addr)
|
|||
vunmap(addr);
|
||||
}
|
||||
EXPORT_SYMBOL(__iounmap);
|
||||
|
||||
void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
|
||||
{
|
||||
/* For normal memory we already have a cacheable mapping. */
|
||||
if (pfn_valid(__phys_to_pfn(phys_addr)))
|
||||
return (void __iomem *)__phys_to_virt(phys_addr);
|
||||
|
||||
return __ioremap_caller(phys_addr, size, __pgprot(PROT_NORMAL),
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap_cache);
|
||||
|
||||
#ifndef CONFIG_ARM64_64K_PAGES
|
||||
static pte_t bm_pte[PTRS_PER_PTE] __page_aligned_bss;
|
||||
#endif
|
||||
|
||||
static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
|
||||
pgd = pgd_offset_k(addr);
|
||||
BUG_ON(pgd_none(*pgd) || pgd_bad(*pgd));
|
||||
|
||||
pud = pud_offset(pgd, addr);
|
||||
BUG_ON(pud_none(*pud) || pud_bad(*pud));
|
||||
|
||||
return pmd_offset(pud, addr);
|
||||
}
|
||||
|
||||
static inline pte_t * __init early_ioremap_pte(unsigned long addr)
|
||||
{
|
||||
pmd_t *pmd = early_ioremap_pmd(addr);
|
||||
|
||||
BUG_ON(pmd_none(*pmd) || pmd_bad(*pmd));
|
||||
|
||||
return pte_offset_kernel(pmd, addr);
|
||||
}
|
||||
|
||||
void __init early_ioremap_init(void)
|
||||
{
|
||||
pmd_t *pmd;
|
||||
|
||||
pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
|
||||
#ifndef CONFIG_ARM64_64K_PAGES
|
||||
/* need to populate pmd for 4k pagesize only */
|
||||
pmd_populate_kernel(&init_mm, pmd, bm_pte);
|
||||
#endif
|
||||
/*
|
||||
* The boot-ioremap range spans multiple pmds, for which
|
||||
* we are not prepared:
|
||||
*/
|
||||
BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
|
||||
!= (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
|
||||
|
||||
if (pmd != early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END))) {
|
||||
WARN_ON(1);
|
||||
pr_warn("pmd %p != %p\n",
|
||||
pmd, early_ioremap_pmd(fix_to_virt(FIX_BTMAP_END)));
|
||||
pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
|
||||
fix_to_virt(FIX_BTMAP_BEGIN));
|
||||
pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n",
|
||||
fix_to_virt(FIX_BTMAP_END));
|
||||
|
||||
pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
|
||||
pr_warn("FIX_BTMAP_BEGIN: %d\n",
|
||||
FIX_BTMAP_BEGIN);
|
||||
}
|
||||
|
||||
early_ioremap_setup();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (idx >= __end_of_fixed_addresses) {
|
||||
BUG();
|
||||
return;
|
||||
}
|
||||
|
||||
pte = early_ioremap_pte(addr);
|
||||
|
||||
if (pgprot_val(flags))
|
||||
set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags));
|
||||
else {
|
||||
pte_clear(&init_mm, addr, pte);
|
||||
flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,11 +43,6 @@
|
|||
struct page *empty_zero_page;
|
||||
EXPORT_SYMBOL(empty_zero_page);
|
||||
|
||||
pgprot_t pgprot_default;
|
||||
EXPORT_SYMBOL(pgprot_default);
|
||||
|
||||
static pmdval_t prot_sect_kernel;
|
||||
|
||||
struct cachepolicy {
|
||||
const char policy[16];
|
||||
u64 mair;
|
||||
|
|
@ -122,33 +117,6 @@ static int __init early_cachepolicy(char *p)
|
|||
}
|
||||
early_param("cachepolicy", early_cachepolicy);
|
||||
|
||||
/*
|
||||
* Adjust the PMD section entries according to the CPU in use.
|
||||
*/
|
||||
void __init init_mem_pgprot(void)
|
||||
{
|
||||
pteval_t default_pgprot;
|
||||
int i;
|
||||
|
||||
default_pgprot = PTE_ATTRINDX(MT_NORMAL);
|
||||
prot_sect_kernel = PMD_TYPE_SECT | PMD_SECT_AF | PMD_ATTRINDX(MT_NORMAL);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Mark memory with the "shared" attribute for SMP systems
|
||||
*/
|
||||
default_pgprot |= PTE_SHARED;
|
||||
prot_sect_kernel |= PMD_SECT_S;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
unsigned long v = pgprot_val(protection_map[i]);
|
||||
protection_map[i] = __pgprot(v | default_pgprot);
|
||||
}
|
||||
|
||||
pgprot_default = __pgprot(PTE_TYPE_PAGE | PTE_AF | default_pgprot);
|
||||
}
|
||||
|
||||
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
unsigned long size, pgprot_t vma_prot)
|
||||
{
|
||||
|
|
@ -205,7 +173,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
|
|||
/* try section mapping first */
|
||||
if (((addr | next | phys) & ~SECTION_MASK) == 0) {
|
||||
pmd_t old_pmd =*pmd;
|
||||
set_pmd(pmd, __pmd(phys | prot_sect_kernel));
|
||||
set_pmd(pmd, __pmd(phys | PROT_SECT_NORMAL_EXEC));
|
||||
/*
|
||||
* Check for previous table entries created during
|
||||
* boot (__create_page_tables) and flush them.
|
||||
|
|
@ -260,47 +228,6 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt,
|
|||
} while (pgd++, addr = next, addr != end);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK
|
||||
/*
|
||||
* Create an early I/O mapping using the pgd/pmd entries already populated
|
||||
* in head.S as this function is called too early to allocated any memory. The
|
||||
* mapping size is 2MB with 4KB pages or 64KB or 64KB pages.
|
||||
*/
|
||||
void __iomem * __init early_io_map(phys_addr_t phys, unsigned long virt)
|
||||
{
|
||||
unsigned long size, mask;
|
||||
bool page64k = IS_ENABLED(CONFIG_ARM64_64K_PAGES);
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
/*
|
||||
* No early pte entries with !ARM64_64K_PAGES configuration, so using
|
||||
* sections (pmd).
|
||||
*/
|
||||
size = page64k ? PAGE_SIZE : SECTION_SIZE;
|
||||
mask = ~(size - 1);
|
||||
|
||||
pgd = pgd_offset_k(virt);
|
||||
pud = pud_offset(pgd, virt);
|
||||
if (pud_none(*pud))
|
||||
return NULL;
|
||||
pmd = pmd_offset(pud, virt);
|
||||
|
||||
if (page64k) {
|
||||
if (pmd_none(*pmd))
|
||||
return NULL;
|
||||
pte = pte_offset_kernel(pmd, virt);
|
||||
set_pte(pte, __pte((phys & mask) | PROT_DEVICE_nGnRE));
|
||||
} else {
|
||||
set_pmd(pmd, __pmd((phys & mask) | PROT_SECT_DEVICE_nGnRE));
|
||||
}
|
||||
|
||||
return (void __iomem *)((virt & mask) + (phys & ~mask));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __init map_mem(void)
|
||||
{
|
||||
struct memblock_region *reg;
|
||||
|
|
@ -455,7 +382,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
|
|||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
set_pmd(pmd, __pmd(__pa(p) | prot_sect_kernel));
|
||||
set_pmd(pmd, __pmd(__pa(p) | PROT_SECT_NORMAL));
|
||||
} else
|
||||
vmemmap_verify((pte_t *)pmd, node, addr, next);
|
||||
} while (addr = next, addr != end);
|
||||
|
|
|
|||
42
include/asm-generic/early_ioremap.h
Normal file
42
include/asm-generic/early_ioremap.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef _ASM_EARLY_IOREMAP_H_
|
||||
#define _ASM_EARLY_IOREMAP_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* early_ioremap() and early_iounmap() are for temporary early boot-time
|
||||
* mappings, before the real ioremap() is functional.
|
||||
*/
|
||||
extern void __iomem *early_ioremap(resource_size_t phys_addr,
|
||||
unsigned long size);
|
||||
extern void *early_memremap(resource_size_t phys_addr,
|
||||
unsigned long size);
|
||||
extern void early_iounmap(void __iomem *addr, unsigned long size);
|
||||
extern void early_memunmap(void *addr, unsigned long size);
|
||||
|
||||
/*
|
||||
* Weak function called by early_ioremap_reset(). It does nothing, but
|
||||
* architectures may provide their own version to do any needed cleanups.
|
||||
*/
|
||||
extern void early_ioremap_shutdown(void);
|
||||
|
||||
#if defined(CONFIG_GENERIC_EARLY_IOREMAP) && defined(CONFIG_MMU)
|
||||
/* Arch-specific initialization */
|
||||
extern void early_ioremap_init(void);
|
||||
|
||||
/* Generic initialization called by architecture code */
|
||||
extern void early_ioremap_setup(void);
|
||||
|
||||
/*
|
||||
* Called as last step in paging_init() so library can act
|
||||
* accordingly for subsequent map/unmap requests.
|
||||
*/
|
||||
extern void early_ioremap_reset(void);
|
||||
|
||||
#else
|
||||
static inline void early_ioremap_init(void) { }
|
||||
static inline void early_ioremap_setup(void) { }
|
||||
static inline void early_ioremap_reset(void) { }
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_EARLY_IOREMAP_H_ */
|
||||
97
include/asm-generic/fixmap.h
Normal file
97
include/asm-generic/fixmap.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* fixmap.h: compile-time virtual memory allocation
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 1998 Ingo Molnar
|
||||
*
|
||||
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
|
||||
* x86_32 and x86_64 integration by Gustavo F. Padovan, February 2009
|
||||
* Break out common bits to asm-generic by Mark Salter, November 2013
|
||||
*/
|
||||
|
||||
#ifndef __ASM_GENERIC_FIXMAP_H
|
||||
#define __ASM_GENERIC_FIXMAP_H
|
||||
|
||||
#include <linux/bug.h>
|
||||
|
||||
#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
|
||||
#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/*
|
||||
* 'index to address' translation. If anyone tries to use the idx
|
||||
* directly without translation, we catch the bug with a NULL-deference
|
||||
* kernel oops. Illegal ranges of incoming indices are caught too.
|
||||
*/
|
||||
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
|
||||
{
|
||||
BUILD_BUG_ON(idx >= __end_of_fixed_addresses);
|
||||
return __fix_to_virt(idx);
|
||||
}
|
||||
|
||||
static inline unsigned long virt_to_fix(const unsigned long vaddr)
|
||||
{
|
||||
BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
|
||||
return __virt_to_fix(vaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide some reasonable defaults for page flags.
|
||||
* Not all architectures use all of these different types and some
|
||||
* architectures use different names.
|
||||
*/
|
||||
#ifndef FIXMAP_PAGE_NORMAL
|
||||
#define FIXMAP_PAGE_NORMAL PAGE_KERNEL
|
||||
#endif
|
||||
#ifndef FIXMAP_PAGE_NOCACHE
|
||||
#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_NOCACHE
|
||||
#endif
|
||||
#ifndef FIXMAP_PAGE_IO
|
||||
#define FIXMAP_PAGE_IO PAGE_KERNEL_IO
|
||||
#endif
|
||||
#ifndef FIXMAP_PAGE_CLEAR
|
||||
#define FIXMAP_PAGE_CLEAR __pgprot(0)
|
||||
#endif
|
||||
|
||||
#ifndef set_fixmap
|
||||
#define set_fixmap(idx, phys) \
|
||||
__set_fixmap(idx, phys, FIXMAP_PAGE_NORMAL)
|
||||
#endif
|
||||
|
||||
#ifndef clear_fixmap
|
||||
#define clear_fixmap(idx) \
|
||||
__set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR)
|
||||
#endif
|
||||
|
||||
/* Return a pointer with offset calculated */
|
||||
#define __set_fixmap_offset(idx, phys, flags) \
|
||||
({ \
|
||||
unsigned long addr; \
|
||||
__set_fixmap(idx, phys, flags); \
|
||||
addr = fix_to_virt(idx) + ((phys) & (PAGE_SIZE - 1)); \
|
||||
addr; \
|
||||
})
|
||||
|
||||
#define set_fixmap_offset(idx, phys) \
|
||||
__set_fixmap_offset(idx, phys, FIXMAP_PAGE_NORMAL)
|
||||
|
||||
/*
|
||||
* Some hardware wants to get fixmapped without caching.
|
||||
*/
|
||||
#define set_fixmap_nocache(idx, phys) \
|
||||
__set_fixmap(idx, phys, FIXMAP_PAGE_NOCACHE)
|
||||
|
||||
#define set_fixmap_offset_nocache(idx, phys) \
|
||||
__set_fixmap_offset(idx, phys, FIXMAP_PAGE_NOCACHE)
|
||||
|
||||
/*
|
||||
* Some fixmaps are for IO
|
||||
*/
|
||||
#define set_fixmap_io(idx, phys) \
|
||||
__set_fixmap(idx, phys, FIXMAP_PAGE_IO)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASM_GENERIC_FIXMAP_H */
|
||||
|
|
@ -478,6 +478,9 @@ config FRONTSWAP
|
|||
|
||||
If unsure, say Y to enable frontswap.
|
||||
|
||||
config GENERIC_EARLY_IOREMAP
|
||||
bool
|
||||
|
||||
config CMA
|
||||
bool "Contiguous Memory Allocator"
|
||||
depends on HAVE_MEMBLOCK
|
||||
|
|
|
|||
|
|
@ -58,3 +58,4 @@ obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
|
|||
obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o
|
||||
obj-$(CONFIG_CLEANCACHE) += cleancache.o
|
||||
obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o
|
||||
obj-$(CONFIG_GENERIC_EARLY_IOREMAP) += early_ioremap.o
|
||||
|
|
|
|||
245
mm/early_ioremap.c
Normal file
245
mm/early_ioremap.c
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Provide common bits of early_ioremap() support for architectures needing
|
||||
* temporary mappings during boot before ioremap() is available.
|
||||
*
|
||||
* This is mostly a direct copy of the x86 early_ioremap implementation.
|
||||
*
|
||||
* (C) Copyright 1995 1996, 2014 Linus Torvalds
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <asm/fixmap.h>
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
static int early_ioremap_debug __initdata;
|
||||
|
||||
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 int after_paging_init __initdata;
|
||||
|
||||
void __init __weak early_ioremap_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void __init early_ioremap_reset(void)
|
||||
{
|
||||
early_ioremap_shutdown();
|
||||
after_paging_init = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generally, ioremap() is available after paging_init() has been called.
|
||||
* Architectures wanting to allow early_ioremap after paging_init() can
|
||||
* define __late_set_fixmap and __late_clear_fixmap to do the right thing.
|
||||
*/
|
||||
#ifndef __late_set_fixmap
|
||||
static inline void __init __late_set_fixmap(enum fixed_addresses idx,
|
||||
phys_addr_t phys, pgprot_t prot)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __late_clear_fixmap
|
||||
static inline void __init __late_clear_fixmap(enum fixed_addresses idx)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata;
|
||||
static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
|
||||
static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata;
|
||||
|
||||
void __init early_ioremap_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
|
||||
if (WARN_ON(prev_map[i]))
|
||||
break;
|
||||
|
||||
for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
|
||||
slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
|
||||
}
|
||||
|
||||
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 (WARN(count, KERN_WARNING
|
||||
"Debug warning: early ioremap leak of %d areas detected.\n"
|
||||
"please boot with early_ioremap_debug and report the dmesg.\n",
|
||||
count))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
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 (WARN(slot < 0, "%s(%08llx, %08lx) not found slot\n",
|
||||
__func__, (u64)phys_addr, size))
|
||||
return NULL;
|
||||
|
||||
/* Don't allow wraparound or zero size */
|
||||
last_addr = phys_addr + size - 1;
|
||||
if (WARN_ON(!size || last_addr < phys_addr))
|
||||
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 (WARN_ON(nrpages > NR_FIX_BTMAPS))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Ok, go for it..
|
||||
*/
|
||||
idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
|
||||
while (nrpages > 0) {
|
||||
if (after_paging_init)
|
||||
__late_set_fixmap(idx, phys_addr, prot);
|
||||
else
|
||||
__early_set_fixmap(idx, phys_addr, prot);
|
||||
phys_addr += PAGE_SIZE;
|
||||
--idx;
|
||||
--nrpages;
|
||||
}
|
||||
WARN(early_ioremap_debug, "%s(%08llx, %08lx) [%d] => %08lx + %08lx\n",
|
||||
__func__, (u64)phys_addr, size, slot, offset, slot_virt[slot]);
|
||||
|
||||
prev_map[slot] = (void __iomem *)(offset + slot_virt[slot]);
|
||||
return prev_map[slot];
|
||||
}
|
||||
|
||||
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 (WARN(slot < 0, "early_iounmap(%p, %08lx) not found slot\n",
|
||||
addr, size))
|
||||
return;
|
||||
|
||||
if (WARN(prev_size[slot] != size,
|
||||
"early_iounmap(%p, %08lx) [%d] size not consistent %08lx\n",
|
||||
addr, size, slot, prev_size[slot]))
|
||||
return;
|
||||
|
||||
WARN(early_ioremap_debug, "early_iounmap(%p, %08lx) [%d]\n",
|
||||
addr, size, slot);
|
||||
|
||||
virt_addr = (unsigned long)addr;
|
||||
if (WARN_ON(virt_addr < fix_to_virt(FIX_BTMAP_BEGIN)))
|
||||
return;
|
||||
|
||||
offset = virt_addr & ~PAGE_MASK;
|
||||
nrpages = PAGE_ALIGN(offset + size) >> PAGE_SHIFT;
|
||||
|
||||
idx = FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*slot;
|
||||
while (nrpages > 0) {
|
||||
if (after_paging_init)
|
||||
__late_clear_fixmap(idx);
|
||||
else
|
||||
__early_set_fixmap(idx, 0, FIXMAP_PAGE_CLEAR);
|
||||
--idx;
|
||||
--nrpages;
|
||||
}
|
||||
prev_map[slot] = NULL;
|
||||
}
|
||||
|
||||
/* Remap an IO device */
|
||||
void __init __iomem *
|
||||
early_ioremap(resource_size_t phys_addr, unsigned long size)
|
||||
{
|
||||
return __early_ioremap(phys_addr, size, FIXMAP_PAGE_IO);
|
||||
}
|
||||
|
||||
/* Remap memory */
|
||||
void __init *
|
||||
early_memremap(resource_size_t phys_addr, unsigned long size)
|
||||
{
|
||||
return (__force void *)__early_ioremap(phys_addr, size,
|
||||
FIXMAP_PAGE_NORMAL);
|
||||
}
|
||||
#else /* CONFIG_MMU */
|
||||
|
||||
void __init __iomem *
|
||||
early_ioremap(resource_size_t phys_addr, unsigned long size)
|
||||
{
|
||||
return (__force void __iomem *)phys_addr;
|
||||
}
|
||||
|
||||
/* Remap memory */
|
||||
void __init *
|
||||
early_memremap(resource_size_t phys_addr, unsigned long size)
|
||||
{
|
||||
return (void *)phys_addr;
|
||||
}
|
||||
|
||||
void __init early_iounmap(void __iomem *addr, unsigned long size)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
|
||||
void __init early_memunmap(void *addr, unsigned long size)
|
||||
{
|
||||
early_iounmap((__force void __iomem *)addr, size);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue