summaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorRaphael Poggi <poggi.raph@gmail.com>2016-07-04 13:52:53 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2016-07-06 11:23:49 +0200
commit7cc98fbb6128ad015e29349370bdd582c6347e5b (patch)
tree35db0b561c7725ea9af50a85ceeaab248e5e760c /arch/arm/include
parentada79ea0790fa3a7d311a985eea0eb168cb829c5 (diff)
downloadbarebox-7cc98fbb6128ad015e29349370bdd582c6347e5b.tar.gz
barebox-7cc98fbb6128ad015e29349370bdd582c6347e5b.tar.xz
arm: cpu: add basic arm64 mmu support
This commit adds basic mmu support, ie: - DMA cache handling is not supported - Remapping memory region also The current mmu setting is: - 4KB granularity - 3 level lookup (skipping L0) - 33 bits per VA This is based on coreboot and u-boot mmu configuration. Signed-off-by: Raphael Poggi <poggi.raph@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/mmu.h14
-rw-r--r--arch/arm/include/asm/pgtable64.h140
2 files changed, 151 insertions, 3 deletions
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 8de6544657..f68ab37143 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -6,16 +6,24 @@
#include <malloc.h>
#include <xfuncs.h>
+#ifdef CONFIG_CPU_64v8
+#include <asm/pgtable64.h>
+
+#define DEV_MEM (PMD_ATTRINDX(MT_DEVICE_nGnRnE) | PMD_SECT_AF | PMD_TYPE_SECT)
+#define CACHED_MEM (PMD_ATTRINDX(MT_NORMAL) | PMD_SECT_S | PMD_SECT_AF | PMD_TYPE_SECT)
+#define UNCACHED_MEM (PMD_ATTRINDX(MT_NORMAL_NC) | PMD_SECT_S | PMD_SECT_AF | PMD_TYPE_SECT)
+#else
#include <asm/pgtable.h>
#define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT)
#define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED)
+#endif
+
+
struct arm_memory;
-static inline void mmu_enable(void)
-{
-}
+void mmu_enable(void);
void mmu_disable(void);
static inline void arm_create_section(unsigned long virt, unsigned long phys, int size_m,
unsigned int flags)
diff --git a/arch/arm/include/asm/pgtable64.h b/arch/arm/include/asm/pgtable64.h
new file mode 100644
index 0000000000..20bea5b28a
--- /dev/null
+++ b/arch/arm/include/asm/pgtable64.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_PGTABLE64_H
+#define __ASM_PGTABLE64_H
+
+#define UL(x) _AC(x, UL)
+
+#define UNUSED_DESC 0x6EbAAD0BBADbA6E0
+
+#define VA_START 0x0
+#define BITS_PER_VA 33
+
+/* Granule size of 4KB is being used */
+#define GRANULE_SIZE_SHIFT 12
+#define GRANULE_SIZE (1 << GRANULE_SIZE_SHIFT)
+#define XLAT_ADDR_MASK ((1UL << BITS_PER_VA) - GRANULE_SIZE)
+#define GRANULE_SIZE_MASK ((1 << GRANULE_SIZE_SHIFT) - 1)
+
+#define BITS_RESOLVED_PER_LVL (GRANULE_SIZE_SHIFT - 3)
+#define L1_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 2)
+#define L2_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 1)
+#define L3_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 0)
+
+
+#define L1_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L1_ADDR_SHIFT)
+#define L2_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L2_ADDR_SHIFT)
+#define L3_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L3_ADDR_SHIFT)
+
+/* These macros give the size of the region addressed by each entry of a xlat
+ table at any given level */
+#define L3_XLAT_SIZE (1UL << L3_ADDR_SHIFT)
+#define L2_XLAT_SIZE (1UL << L2_ADDR_SHIFT)
+#define L1_XLAT_SIZE (1UL << L1_ADDR_SHIFT)
+
+#define GRANULE_MASK GRANULE_SIZE
+
+
+/*
+ * Level 2 descriptor (PMD).
+ */
+#define PMD_TYPE_MASK (3 << 0)
+#define PMD_TYPE_FAULT (0 << 0)
+#define PMD_TYPE_TABLE (3 << 0)
+#define PMD_TYPE_SECT (1 << 0)
+#define PMD_TABLE_BIT (1 << 1)
+
+/*
+ * Section
+ */
+#define PMD_SECT_VALID (1 << 0)
+#define PMD_SECT_USER (1 << 6) /* AP[1] */
+#define PMD_SECT_RDONLY (1 << 7) /* AP[2] */
+#define PMD_SECT_S (3 << 8)
+#define PMD_SECT_AF (1 << 10)
+#define PMD_SECT_NG (1 << 11)
+#define PMD_SECT_CONT (1 << 52)
+#define PMD_SECT_PXN (1 << 53)
+#define PMD_SECT_UXN (1 << 54)
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define PMD_ATTRINDX(t) ((t) << 2)
+#define PMD_ATTRINDX_MASK (7 << 2)
+
+/*
+ * Level 3 descriptor (PTE).
+ */
+#define PTE_TYPE_MASK (3 << 0)
+#define PTE_TYPE_FAULT (0 << 0)
+#define PTE_TYPE_PAGE (3 << 0)
+#define PTE_TABLE_BIT (1 << 1)
+#define PTE_USER (1 << 6) /* AP[1] */
+#define PTE_RDONLY (1 << 7) /* AP[2] */
+#define PTE_SHARED (3 << 8) /* SH[1:0], inner shareable */
+#define PTE_AF (1 << 10) /* Access Flag */
+#define PTE_NG (1 << 11) /* nG */
+#define PTE_DBM (1 << 51) /* Dirty Bit Management */
+#define PTE_CONT (1 << 52) /* Contiguous range */
+#define PTE_PXN (1 << 53) /* Privileged XN */
+#define PTE_UXN (1 << 54) /* User XN */
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define PTE_ATTRINDX(t) ((t) << 2)
+#define PTE_ATTRINDX_MASK (7 << 2)
+
+/*
+ * Memory types available.
+ */
+#define MT_DEVICE_nGnRnE 0
+#define MT_DEVICE_nGnRE 1
+#define MT_DEVICE_GRE 2
+#define MT_NORMAL_NC 3
+#define MT_NORMAL 4
+#define MT_NORMAL_WT 5
+
+/*
+ * TCR flags.
+ */
+#define TCR_T0SZ(x) ((64 - (x)) << 0)
+#define TCR_IRGN_NC (0 << 8)
+#define TCR_IRGN_WBWA (1 << 8)
+#define TCR_IRGN_WT (2 << 8)
+#define TCR_IRGN_WBNWA (3 << 8)
+#define TCR_IRGN_MASK (3 << 8)
+#define TCR_ORGN_NC (0 << 10)
+#define TCR_ORGN_WBWA (1 << 10)
+#define TCR_ORGN_WT (2 << 10)
+#define TCR_ORGN_WBNWA (3 << 10)
+#define TCR_ORGN_MASK (3 << 10)
+#define TCR_SHARED_NON (0 << 12)
+#define TCR_SHARED_OUTER (2 << 12)
+#define TCR_SHARED_INNER (3 << 12)
+#define TCR_TG0_4K (0 << 14)
+#define TCR_TG0_64K (1 << 14)
+#define TCR_TG0_16K (2 << 14)
+#define TCR_EL1_IPS_BITS (UL(3) << 32) /* 42 bits physical address */
+#define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */
+#define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */
+
+#define TCR_EL1_RSVD (1 << 31)
+#define TCR_EL2_RSVD (1 << 31 | 1 << 23)
+#define TCR_EL3_RSVD (1 << 31 | 1 << 23)
+
+#endif