From cd4b0c5feaaa524b44889cde8f58d4b121df8fed Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 24 Jun 2016 16:46:22 -0700 Subject: armv8: mmu: Add support of non-identical mapping Introduce virtual and physical addresses in the mapping table. This change have no impact on existing boards because they all use idential mapping. Signed-off-by: York Sun --- arch/arm/cpu/armv8/cache_v8.c | 37 +++++++++++++++++-------------- arch/arm/cpu/armv8/s32v234/cpu.c | 12 ++++++---- arch/arm/cpu/armv8/zynqmp/cpu.c | 21 ++++++++++++------ arch/arm/include/asm/armv8/mmu.h | 3 ++- arch/arm/mach-exynos/mmu-arm64.c | 9 ++++---- arch/arm/mach-meson/board.c | 6 +++-- arch/arm/mach-snapdragon/sysmap-apq8016.c | 6 +++-- arch/arm/mach-sunxi/board.c | 6 +++-- arch/arm/mach-tegra/arm64-mmu.c | 6 +++-- arch/arm/mach-uniphier/arm64/mem_map.c | 6 +++-- 10 files changed, 68 insertions(+), 44 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 8604035..ac909a1 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -44,7 +44,7 @@ u64 get_tcr(int el, u64 *pips, u64 *pva_bits) /* Find the largest address we need to support */ for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) - max_addr = max(max_addr, mem_map[i].base + mem_map[i].size); + max_addr = max(max_addr, mem_map[i].virt + mem_map[i].size); /* Calculate the maximum physical (and thus virtual) address */ if (max_addr > (1ULL << 44)) { @@ -202,7 +202,8 @@ static void split_block(u64 *pte, int level) static void add_map(struct mm_region *map) { u64 *pte; - u64 addr = map->base; + u64 virt = map->virt; + u64 phys = map->phys; u64 size = map->size; u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF; u64 blocksize; @@ -210,37 +211,39 @@ static void add_map(struct mm_region *map) u64 *new_table; while (size) { - pte = find_pte(addr, 0); + pte = find_pte(virt, 0); if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) { - debug("Creating table for addr 0x%llx\n", addr); + debug("Creating table for virt 0x%llx\n", virt); new_table = create_table(); set_pte_table(pte, new_table); } for (level = 1; level < 4; level++) { - pte = find_pte(addr, level); + pte = find_pte(virt, level); if (!pte) panic("pte not found\n"); + blocksize = 1ULL << level2shift(level); - debug("Checking if pte fits for addr=%llx size=%llx " - "blocksize=%llx\n", addr, size, blocksize); - if (size >= blocksize && !(addr & (blocksize - 1))) { + debug("Checking if pte fits for virt=%llx size=%llx blocksize=%llx\n", + virt, size, blocksize); + if (size >= blocksize && !(virt & (blocksize - 1))) { /* Page fits, create block PTE */ - debug("Setting PTE %p to block addr=%llx\n", - pte, addr); - *pte = addr | attrs; - addr += blocksize; + debug("Setting PTE %p to block virt=%llx\n", + pte, virt); + *pte = phys | attrs; + virt += blocksize; + phys += blocksize; size -= blocksize; break; } else if (pte_type(pte) == PTE_TYPE_FAULT) { /* Page doesn't fit, create subpages */ - debug("Creating subtable for addr 0x%llx " - "blksize=%llx\n", addr, blocksize); + debug("Creating subtable for virt 0x%llx blksize=%llx\n", + virt, blocksize); new_table = create_table(); set_pte_table(pte, new_table); } else if (pte_type(pte) == PTE_TYPE_BLOCK) { - debug("Split block into subtable for addr 0x%llx blksize=0x%llx\n", - addr, blocksize); + debug("Split block into subtable for virt 0x%llx blksize=0x%llx\n", + virt, blocksize); split_block(pte, level); } } @@ -271,7 +274,7 @@ static int count_required_pts(u64 addr, int level, u64 maxaddr) for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) { struct mm_region *map = &mem_map[i]; - u64 start = map->base; + u64 start = map->virt; u64 end = start + map->size; /* Check if the PTE would overlap with the map */ diff --git a/arch/arm/cpu/armv8/s32v234/cpu.c b/arch/arm/cpu/armv8/s32v234/cpu.c index dac12a2..5c97e0e 100644 --- a/arch/arm/cpu/armv8/s32v234/cpu.c +++ b/arch/arm/cpu/armv8/s32v234/cpu.c @@ -32,24 +32,28 @@ u32 cpu_mask(void) static struct mm_region s32v234_mem_map[] = { { - .base = S32V234_IRAM_BASE, + .virt = S32V234_IRAM_BASE, + .phys = S32V234_IRAM_BASE, .size = S32V234_IRAM_SIZE, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE }, { - .base = S32V234_DRAM_BASE1, + .virt = S32V234_DRAM_BASE1, + .phys = S32V234_DRAM_BASE1, .size = S32V234_DRAM_SIZE1, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE }, { - .base = S32V234_PERIPH_BASE, + .virt = S32V234_PERIPH_BASE, + .phys = S32V234_PERIPH_BASE, .size = S32V234_PERIPH_SIZE, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE /* TODO: Do we need these? */ /* | PTE_BLOCK_PXN | PTE_BLOCK_UXN */ }, { - .base = S32V234_DRAM_BASE2, + .virt = S32V234_DRAM_BASE2, + .phys = S32V234_DRAM_BASE2, .size = S32V234_DRAM_SIZE2, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | PTE_BLOCK_OUTER_SHARE diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index 509f0aa..b0f1295 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -18,40 +18,47 @@ DECLARE_GLOBAL_DATA_PTR; static struct mm_region zynqmp_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0x70000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0xf8000000UL, + .virt = 0xf8000000UL, + .phys = 0xf8000000UL, .size = 0x07e00000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0xffe00000UL, + .virt = 0xffe00000UL, + .phys = 0xffe00000UL, .size = 0x00200000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x400000000UL, + .virt = 0x400000000UL, + .phys = 0x400000000UL, .size = 0x200000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x600000000UL, + .virt = 0x600000000UL, + .phys = 0x600000000UL, .size = 0x800000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0xe00000000UL, + .virt = 0xe00000000UL, + .phys = 0xe00000000UL, .size = 0xf200000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h index b7b4706..aa0f3c4 100644 --- a/arch/arm/include/asm/armv8/mmu.h +++ b/arch/arm/include/asm/armv8/mmu.h @@ -135,7 +135,8 @@ static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr) } struct mm_region { - u64 base; + u64 virt; + u64 phys; u64 size; u64 attrs; }; diff --git a/arch/arm/mach-exynos/mmu-arm64.c b/arch/arm/mach-exynos/mmu-arm64.c index ba6d99d..2381422 100644 --- a/arch/arm/mach-exynos/mmu-arm64.c +++ b/arch/arm/mach-exynos/mmu-arm64.c @@ -13,21 +13,20 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_EXYNOS7420 static struct mm_region exynos7420_mem_map[] = { { - .base = 0x10000000UL, + .virt = 0x10000000UL, + .phys = 0x10000000UL, .size = 0x10000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN, }, { - .base = 0x40000000UL, + .virt = 0x40000000UL, + .phys = 0x40000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE, }, { /* List terminator */ - .base = 0, - .size = 0, - .attrs = 0, }, }; diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board.c index 64fa3c1..1dd53e2 100644 --- a/arch/arm/mach-meson/board.c +++ b/arch/arm/mach-meson/board.c @@ -48,12 +48,14 @@ void reset_cpu(ulong addr) static struct mm_region gxbb_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | diff --git a/arch/arm/mach-snapdragon/sysmap-apq8016.c b/arch/arm/mach-snapdragon/sysmap-apq8016.c index ef0db2a..580b9c7 100644 --- a/arch/arm/mach-snapdragon/sysmap-apq8016.c +++ b/arch/arm/mach-snapdragon/sysmap-apq8016.c @@ -11,13 +11,15 @@ static struct mm_region apq8016_mem_map[] = { { - .base = 0x0UL, /* Peripheral block */ + .virt = 0x0UL, /* Peripheral block */ + .phys = 0x0UL, /* Peripheral block */ .size = 0x8000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x80000000UL, /* DDR */ + .virt = 0x80000000UL, /* DDR */ + .phys = 0x80000000UL, /* DDR */ .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 66e028e..01bfc93 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -46,13 +46,15 @@ struct fel_stash fel_stash __attribute__((section(".data"))); static struct mm_region sunxi_mem_map[] = { { /* SRAM, MMIO regions */ - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x40000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE }, { /* RAM */ - .base = 0x40000000UL, + .virt = 0x40000000UL, + .phys = 0x40000000UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/arch/arm/mach-tegra/arm64-mmu.c b/arch/arm/mach-tegra/arm64-mmu.c index 501c4f0..7b1d258 100644 --- a/arch/arm/mach-tegra/arm64-mmu.c +++ b/arch/arm/mach-tegra/arm64-mmu.c @@ -14,13 +14,15 @@ static struct mm_region tegra_mem_map[] = { { - .base = 0x0UL, + .virt = 0x0UL, + .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x80000000UL, + .virt = 0x80000000UL, + .phys = 0x80000000UL, .size = 0xff80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE diff --git a/arch/arm/mach-uniphier/arm64/mem_map.c b/arch/arm/mach-uniphier/arm64/mem_map.c index 74ef919..67bc4f1 100644 --- a/arch/arm/mach-uniphier/arm64/mem_map.c +++ b/arch/arm/mach-uniphier/arm64/mem_map.c @@ -10,14 +10,16 @@ static struct mm_region uniphier_mem_map[] = { { - .base = 0x00000000, + .virt = 0x00000000, + .phys = 0x00000000, .size = 0x80000000, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { - .base = 0x80000000, + .virt = 0x80000000, + .phys = 0x80000000, .size = 0xc0000000, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE -- cgit v1.1