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 <york.sun@nxp.com>
master
York Sun 8 years ago
parent f733d46620
commit cd4b0c5fea
  1. 37
      arch/arm/cpu/armv8/cache_v8.c
  2. 12
      arch/arm/cpu/armv8/s32v234/cpu.c
  3. 21
      arch/arm/cpu/armv8/zynqmp/cpu.c
  4. 3
      arch/arm/include/asm/armv8/mmu.h
  5. 9
      arch/arm/mach-exynos/mmu-arm64.c
  6. 6
      arch/arm/mach-meson/board.c
  7. 6
      arch/arm/mach-snapdragon/sysmap-apq8016.c
  8. 6
      arch/arm/mach-sunxi/board.c
  9. 6
      arch/arm/mach-tegra/arm64-mmu.c
  10. 6
      arch/arm/mach-uniphier/arm64/mem_map.c
  11. 6
      board/armltd/vexpress64/vexpress64.c
  12. 9
      board/cavium/thunderx/thunderx.c
  13. 6
      board/hisilicon/hikey/hikey.c
  14. 6
      board/raspberrypi/rpi/rpi.c

@ -44,7 +44,7 @@ u64 get_tcr(int el, u64 *pips, u64 *pva_bits)
/* Find the largest address we need to support */ /* Find the largest address we need to support */
for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) 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 */ /* Calculate the maximum physical (and thus virtual) address */
if (max_addr > (1ULL << 44)) { 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) static void add_map(struct mm_region *map)
{ {
u64 *pte; u64 *pte;
u64 addr = map->base; u64 virt = map->virt;
u64 phys = map->phys;
u64 size = map->size; u64 size = map->size;
u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF; u64 attrs = map->attrs | PTE_TYPE_BLOCK | PTE_BLOCK_AF;
u64 blocksize; u64 blocksize;
@ -210,37 +211,39 @@ static void add_map(struct mm_region *map)
u64 *new_table; u64 *new_table;
while (size) { while (size) {
pte = find_pte(addr, 0); pte = find_pte(virt, 0);
if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) { 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(); new_table = create_table();
set_pte_table(pte, new_table); set_pte_table(pte, new_table);
} }
for (level = 1; level < 4; level++) { for (level = 1; level < 4; level++) {
pte = find_pte(addr, level); pte = find_pte(virt, level);
if (!pte) if (!pte)
panic("pte not found\n"); panic("pte not found\n");
blocksize = 1ULL << level2shift(level); blocksize = 1ULL << level2shift(level);
debug("Checking if pte fits for addr=%llx size=%llx " debug("Checking if pte fits for virt=%llx size=%llx blocksize=%llx\n",
"blocksize=%llx\n", addr, size, blocksize); virt, size, blocksize);
if (size >= blocksize && !(addr & (blocksize - 1))) { if (size >= blocksize && !(virt & (blocksize - 1))) {
/* Page fits, create block PTE */ /* Page fits, create block PTE */
debug("Setting PTE %p to block addr=%llx\n", debug("Setting PTE %p to block virt=%llx\n",
pte, addr); pte, virt);
*pte = addr | attrs; *pte = phys | attrs;
addr += blocksize; virt += blocksize;
phys += blocksize;
size -= blocksize; size -= blocksize;
break; break;
} else if (pte_type(pte) == PTE_TYPE_FAULT) { } else if (pte_type(pte) == PTE_TYPE_FAULT) {
/* Page doesn't fit, create subpages */ /* Page doesn't fit, create subpages */
debug("Creating subtable for addr 0x%llx " debug("Creating subtable for virt 0x%llx blksize=%llx\n",
"blksize=%llx\n", addr, blocksize); virt, blocksize);
new_table = create_table(); new_table = create_table();
set_pte_table(pte, new_table); set_pte_table(pte, new_table);
} else if (pte_type(pte) == PTE_TYPE_BLOCK) { } else if (pte_type(pte) == PTE_TYPE_BLOCK) {
debug("Split block into subtable for addr 0x%llx blksize=0x%llx\n", debug("Split block into subtable for virt 0x%llx blksize=0x%llx\n",
addr, blocksize); virt, blocksize);
split_block(pte, level); 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++) { for (i = 0; mem_map[i].size || mem_map[i].attrs; i++) {
struct mm_region *map = &mem_map[i]; struct mm_region *map = &mem_map[i];
u64 start = map->base; u64 start = map->virt;
u64 end = start + map->size; u64 end = start + map->size;
/* Check if the PTE would overlap with the map */ /* Check if the PTE would overlap with the map */

@ -32,24 +32,28 @@ u32 cpu_mask(void)
static struct mm_region s32v234_mem_map[] = { static struct mm_region s32v234_mem_map[] = {
{ {
.base = S32V234_IRAM_BASE, .virt = S32V234_IRAM_BASE,
.phys = S32V234_IRAM_BASE,
.size = S32V234_IRAM_SIZE, .size = S32V234_IRAM_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE PTE_BLOCK_OUTER_SHARE
}, { }, {
.base = S32V234_DRAM_BASE1, .virt = S32V234_DRAM_BASE1,
.phys = S32V234_DRAM_BASE1,
.size = S32V234_DRAM_SIZE1, .size = S32V234_DRAM_SIZE1,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_OUTER_SHARE PTE_BLOCK_OUTER_SHARE
}, { }, {
.base = S32V234_PERIPH_BASE, .virt = S32V234_PERIPH_BASE,
.phys = S32V234_PERIPH_BASE,
.size = S32V234_PERIPH_SIZE, .size = S32V234_PERIPH_SIZE,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE PTE_BLOCK_NON_SHARE
/* TODO: Do we need these? */ /* TODO: Do we need these? */
/* | PTE_BLOCK_PXN | PTE_BLOCK_UXN */ /* | PTE_BLOCK_PXN | PTE_BLOCK_UXN */
}, { }, {
.base = S32V234_DRAM_BASE2, .virt = S32V234_DRAM_BASE2,
.phys = S32V234_DRAM_BASE2,
.size = S32V234_DRAM_SIZE2, .size = S32V234_DRAM_SIZE2,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
PTE_BLOCK_OUTER_SHARE PTE_BLOCK_OUTER_SHARE

@ -18,40 +18,47 @@ DECLARE_GLOBAL_DATA_PTR;
static struct mm_region zynqmp_mem_map[] = { static struct mm_region zynqmp_mem_map[] = {
{ {
.base = 0x0UL, .virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
.base = 0x80000000UL, .virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 0x70000000UL, .size = 0x70000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, { }, {
.base = 0xf8000000UL, .virt = 0xf8000000UL,
.phys = 0xf8000000UL,
.size = 0x07e00000UL, .size = 0x07e00000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, { }, {
.base = 0xffe00000UL, .virt = 0xffe00000UL,
.phys = 0xffe00000UL,
.size = 0x00200000UL, .size = 0x00200000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
.base = 0x400000000UL, .virt = 0x400000000UL,
.phys = 0x400000000UL,
.size = 0x200000000UL, .size = 0x200000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, { }, {
.base = 0x600000000UL, .virt = 0x600000000UL,
.phys = 0x600000000UL,
.size = 0x800000000UL, .size = 0x800000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
.base = 0xe00000000UL, .virt = 0xe00000000UL,
.phys = 0xe00000000UL,
.size = 0xf200000000UL, .size = 0xf200000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |

@ -135,7 +135,8 @@ static inline void set_ttbr_tcr_mair(int el, u64 table, u64 tcr, u64 attr)
} }
struct mm_region { struct mm_region {
u64 base; u64 virt;
u64 phys;
u64 size; u64 size;
u64 attrs; u64 attrs;
}; };

@ -13,21 +13,20 @@ DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_EXYNOS7420 #ifdef CONFIG_EXYNOS7420
static struct mm_region exynos7420_mem_map[] = { static struct mm_region exynos7420_mem_map[] = {
{ {
.base = 0x10000000UL, .virt = 0x10000000UL,
.phys = 0x10000000UL,
.size = 0x10000000UL, .size = 0x10000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN, PTE_BLOCK_PXN | PTE_BLOCK_UXN,
}, { }, {
.base = 0x40000000UL, .virt = 0x40000000UL,
.phys = 0x40000000UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE, PTE_BLOCK_INNER_SHARE,
}, { }, {
/* List terminator */ /* List terminator */
.base = 0,
.size = 0,
.attrs = 0,
}, },
}; };

@ -48,12 +48,14 @@ void reset_cpu(ulong addr)
static struct mm_region gxbb_mem_map[] = { static struct mm_region gxbb_mem_map[] = {
{ {
.base = 0x0UL, .virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
.base = 0x80000000UL, .virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |

@ -11,13 +11,15 @@
static struct mm_region apq8016_mem_map[] = { static struct mm_region apq8016_mem_map[] = {
{ {
.base = 0x0UL, /* Peripheral block */ .virt = 0x0UL, /* Peripheral block */
.phys = 0x0UL, /* Peripheral block */
.size = 0x8000000UL, .size = 0x8000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, { }, {
.base = 0x80000000UL, /* DDR */ .virt = 0x80000000UL, /* DDR */
.phys = 0x80000000UL, /* DDR */
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE

@ -46,13 +46,15 @@ struct fel_stash fel_stash __attribute__((section(".data")));
static struct mm_region sunxi_mem_map[] = { static struct mm_region sunxi_mem_map[] = {
{ {
/* SRAM, MMIO regions */ /* SRAM, MMIO regions */
.base = 0x0UL, .virt = 0x0UL,
.phys = 0x0UL,
.size = 0x40000000UL, .size = 0x40000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE PTE_BLOCK_NON_SHARE
}, { }, {
/* RAM */ /* RAM */
.base = 0x40000000UL, .virt = 0x40000000UL,
.phys = 0x40000000UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE

@ -14,13 +14,15 @@
static struct mm_region tegra_mem_map[] = { static struct mm_region tegra_mem_map[] = {
{ {
.base = 0x0UL, .virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, { }, {
.base = 0x80000000UL, .virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 0xff80000000UL, .size = 0xff80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE

@ -10,14 +10,16 @@
static struct mm_region uniphier_mem_map[] = { static struct mm_region uniphier_mem_map[] = {
{ {
.base = 0x00000000, .virt = 0x00000000,
.phys = 0x00000000,
.size = 0x80000000, .size = 0x80000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, },
{ {
.base = 0x80000000, .virt = 0x80000000,
.phys = 0x80000000,
.size = 0xc0000000, .size = 0xc0000000,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE

@ -31,13 +31,15 @@ U_BOOT_DEVICE(vexpress_serials) = {
static struct mm_region vexpress64_mem_map[] = { static struct mm_region vexpress64_mem_map[] = {
{ {
.base = 0x0UL, .virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, { }, {
.base = 0x80000000UL, .virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 0xff80000000UL, .size = 0xff80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE

@ -45,16 +45,19 @@ DECLARE_GLOBAL_DATA_PTR;
static struct mm_region thunderx_mem_map[] = { static struct mm_region thunderx_mem_map[] = {
{ {
.base = 0x000000000000UL, .virt = 0x000000000000UL,
.phys = 0x000000000000UL,
.size = 0x40000000000UL, .size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE,
}, { }, {
.base = 0x800000000000UL, .virt = 0x800000000000UL,
.phys = 0x800000000000UL,
.size = 0x40000000000UL, .size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE, PTE_BLOCK_NON_SHARE,
}, { }, {
.base = 0x840000000000UL, .virt = 0x840000000000UL,
.phys = 0x840000000000UL,
.size = 0x40000000000UL, .size = 0x40000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE, PTE_BLOCK_NON_SHARE,

@ -93,12 +93,14 @@ U_BOOT_DEVICE(hikey_seriala) = {
static struct mm_region hikey_mem_map[] = { static struct mm_region hikey_mem_map[] = {
{ {
.base = 0x0UL, .virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
.base = 0x80000000UL, .virt = 0x80000000UL,
.phys = 0x80000000UL,
.size = 0x80000000UL, .size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |

@ -234,12 +234,14 @@ static const struct rpi_model *model;
#ifdef CONFIG_ARM64 #ifdef CONFIG_ARM64
static struct mm_region bcm2837_mem_map[] = { static struct mm_region bcm2837_mem_map[] = {
{ {
.base = 0x00000000UL, .virt = 0x00000000UL,
.phys = 0x00000000UL,
.size = 0x3f000000UL, .size = 0x3f000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE PTE_BLOCK_INNER_SHARE
}, { }, {
.base = 0x3f000000UL, .virt = 0x3f000000UL,
.phys = 0x3f000000UL,
.size = 0x01000000UL, .size = 0x01000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE | PTE_BLOCK_NON_SHARE |

Loading…
Cancel
Save