Commit cd4b0c5f authored by York Sun's avatar York Sun

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: default avatarYork Sun <york.sun@nxp.com>
parent f733d466
......@@ -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 |
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment