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>
This commit is contained in:
		
							parent
							
								
									f733d46620
								
							
						
					
					
						commit
						cd4b0c5fea
					
				|  | @ -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 */ | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | | ||||
|  |  | |||
|  | @ -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; | ||||
| }; | ||||
|  |  | |||
|  | @ -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, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -31,13 +31,15 @@ U_BOOT_DEVICE(vexpress_serials) = { | |||
| 
 | ||||
| static struct mm_region vexpress64_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 | ||||
|  |  | |||
|  | @ -45,16 +45,19 @@ DECLARE_GLOBAL_DATA_PTR; | |||
| 
 | ||||
| static struct mm_region thunderx_mem_map[] = { | ||||
| 	{ | ||||
| 		.base = 0x000000000000UL, | ||||
| 		.virt = 0x000000000000UL, | ||||
| 		.phys = 0x000000000000UL, | ||||
| 		.size = 0x40000000000UL, | ||||
| 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE, | ||||
| 	}, { | ||||
| 		.base = 0x800000000000UL, | ||||
| 		.virt = 0x800000000000UL, | ||||
| 		.phys = 0x800000000000UL, | ||||
| 		.size = 0x40000000000UL, | ||||
| 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | ||||
| 			 PTE_BLOCK_NON_SHARE, | ||||
| 	}, { | ||||
| 		.base = 0x840000000000UL, | ||||
| 		.virt = 0x840000000000UL, | ||||
| 		.phys = 0x840000000000UL, | ||||
| 		.size = 0x40000000000UL, | ||||
| 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | ||||
| 			 PTE_BLOCK_NON_SHARE, | ||||
|  |  | |||
|  | @ -93,12 +93,14 @@ U_BOOT_DEVICE(hikey_seriala) = { | |||
| 
 | ||||
| static struct mm_region hikey_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 | | ||||
|  |  | |||
|  | @ -234,12 +234,14 @@ static const struct rpi_model *model; | |||
| #ifdef CONFIG_ARM64 | ||||
| static struct mm_region bcm2837_mem_map[] = { | ||||
| 	{ | ||||
| 		.base = 0x00000000UL, | ||||
| 		.virt = 0x00000000UL, | ||||
| 		.phys = 0x00000000UL, | ||||
| 		.size = 0x3f000000UL, | ||||
| 		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | | ||||
| 			 PTE_BLOCK_INNER_SHARE | ||||
| 	}, { | ||||
| 		.base = 0x3f000000UL, | ||||
| 		.virt = 0x3f000000UL, | ||||
| 		.phys = 0x3f000000UL, | ||||
| 		.size = 0x01000000UL, | ||||
| 		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | ||||
| 			 PTE_BLOCK_NON_SHARE | | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue