[Docs] Added Information about Secure Monitor
[3rdparty/ote_partner/tlk.git] / arch / arm / include / arch / arm / mmu_ldesc_macros.h
1 /*
2  * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <config.h>
24 #include <arch/arm/mmu_ldesc.h>
25
26 #define MMU_PTE_L2_BLOCK_MMIO_LOWER     \
27         (MMU_MEMORY_SET_ATTR_IDX(MMU_MEMORY_STRONGLY_ORDERED) | \
28          MMU_MEMORY_ACCESS_FLAG |       \
29          MMU_MEMORY_AP_P_RW_U_NA | 0x1)
30
31 /* no execute for bits for EL1/EL0 */
32 #define MMU_PTE_L2_BLOCK_MMIO_UXN       (1 << 54)
33 #define MMU_PTE_L2_BLOCK_MMIO_PXN       (1 << 53)
34
35 #define MMU_PTE_L2_BLOCK_MMIO_UPPER     \
36         (MMU_PTE_L2_BLOCK_MMIO_UXN | MMU_PTE_L2_BLOCK_MMIO_PXN)
37
38 #define MMU_PTE_L2_BLOCK_KERN_FLAGS     \
39         (MMU_MEMORY_SET_ATTR_IDX(MMU_MEMORY_WB_OUTER_NO_ALLOC_INNER_ALLOC) | \
40          MMU_MEMORY_ACCESS_FLAG |       \
41          MMU_MEMORY_AP_P_RW_U_NA | 0x1)
42
43 #define MMU_PTE_L3_KERN_FLAGS   \
44         (MMU_MEMORY_SET_ATTR_IDX(MMU_MEMORY_WB_OUTER_NO_ALLOC_INNER_ALLOC) | \
45          MMU_MEMORY_ACCESS_FLAG |       \
46          MMU_MEMORY_AP_P_RW_U_NA | 0x3)
47
48 #define MMU_TTBCR_FLAGS         \
49         (MMU_MEMORY_TTBCR_EAE | MMU_MEMORY_TTBCR_A1 | \
50          MMU_MEMORY_TTBCR_OUTER_RGN1(MMU_MEMORY_RGN_WRITE_BACK_ALLOCATE) | \
51          MMU_MEMORY_TTBCR_OUTER_RGN0(MMU_MEMORY_RGN_WRITE_BACK_ALLOCATE) | \
52          MMU_MEMORY_TTBCR_INNER_RGN1(MMU_MEMORY_RGN_WRITE_BACK_ALLOCATE) | \
53          MMU_MEMORY_TTBCR_INNER_RGN0(MMU_MEMORY_RGN_WRITE_BACK_ALLOCATE) | \
54          MMU_MEMORY_TTBCR_T1SZ | MMU_MEMORY_TTBCR_T0SZ)
55
56 /* loads 32-bit value into a register */
57 .macro mov32, reg, val
58         movw    \reg, #:lower16:\val
59         movt    \reg, #:upper16:\val
60 .endm
61
62 /* size/align check of carveout */
63 .macro mmu_desc_phy_align, base, size, tmp
64         mov32   \tmp, (MMU_L2_BLOCK_SIZE - 1)
65         tst     \base, \tmp
66         bne     .               @ base not aligned
67         cmp     \size, #0
68         beq     .               @ size is zero
69         tst     \size, \tmp
70         bne     .               @ size not aligned
71 .endm
72
73 /* create NULL 2MB entry to guarantee a NULL ptr fault */
74 .macro mmu_desc_create_null_entry, pt, tmp
75         mov     \tmp, #0
76         str     \tmp, [\pt], #4
77         str     \tmp, [\pt], #4         @ write PTE and upper 0
78 .endm
79
80 /* create identity 2MB entries for MMIO */
81 .macro mmu_desc_create_ident_mapping, pt, pte, idx, upper
82         /* create second level identity entries */
83         mov32   \pte, MMU_PTE_L2_BLOCK_MMIO_LOWER
84         mov     \idx, #1
85         mov     \upper, #(MMU_PTE_L2_BLOCK_MMIO_UPPER >> 32)
86 1:
87         add     \pte, \pte, #(1 << MMU_L2_BLOCK_SHIFT)
88         stmia   \pt!, {\pte, \upper}    @ write PTE and upper 0
89         add     \idx, #1
90         cmp     \idx, #0x800            @ # of 2MB mappings in 32bit VA
91         blt     1b
92 .endm
93
94 /* create identity 2MB entries for TZ carveout */
95 .macro mmu_desc_setup_carveout_ident, pt, addr, len, pte, tmp
96         /* create second level identity entries */
97         mov32   \pte, MMU_PTE_L2_BLOCK_MMIO_LOWER
98         lsr     \addr, #MMU_L2_BLOCK_SHIFT
99         mov     \tmp, \addr
100         lsl     \addr, #MMU_L2_BLOCK_SHIFT
101         orr     \pte, \addr
102         add     \pt, \tmp, lsl #3
103
104         /* roundup length to L2 blocks */
105         mov32   \tmp, ((1 << MMU_L2_BLOCK_SHIFT) - 1)
106         add     \tmp, \len, \tmp
107         lsr     \len, \tmp, #MMU_L2_BLOCK_SHIFT         @ L2 block count
108         mov     \tmp, #0
109 1:
110         stmia   \pt!, {\pte, \tmp}    @ write PTE and upper 0
111         add     \pte, \pte, #(1 << MMU_L2_BLOCK_SHIFT)
112         subs    \len, \len, #0x1
113         bne     1b
114 .endm
115
116 /* map phys carveout with L3 entries */
117 .macro mmu_desc_map_phys_l3, virt, phys, len, pt, l2, tmp, tmp2, zero
118         /* setup L2 entries */
119         mov32   \tmp, ((1 << MMU_L3_MAP_SHIFT) - 1)
120         add     \tmp2, \len, \tmp
121         lsr     \tmp2, \tmp2, #MMU_L3_MAP_SHIFT                 @ roundup to L3 map size
122         lsl     \tmp2, \tmp2, #MMU_L3_SIZE_SHIFT                @ bytes of L3 tables
123         lsr     \tmp2, \tmp2, #MMU_MEMORY_TTBR_L3_VADDR_SHIFT   @ # of L2 entries
124
125         lsr     \tmp, \virt, #MMU_MEMORY_TTBR_L2_VADDR_SHIFT
126         add     \l2, \tmp, lsl #MMU_ENTRY_SHIFT         @ starting L2 entry
127         orr     \tmp, \pt, #0x3
128 2:
129         stmia   \l2!, {\tmp, \zero}             @ write PTE for level 3
130         add     \tmp, \tmp, #(1 << MMU_MEMORY_TTBR_L3_VADDR_SHIFT)
131         subs    \tmp2, \tmp2, #0x1
132         bne     2b
133
134         /* setup L3 entries */
135         mov32   \tmp, MMU_PTE_L3_KERN_FLAGS
136         add     \phys, \phys, \tmp                      @ setup PTE
137         lsr     \virt, \virt, #MMU_MEMORY_TTBR_L3_VADDR_SHIFT
138         mov32   \tmp2, MMU_MEMORY_TTBR_L3_INDEX_MASK
139         and     \virt, \virt, \tmp2
140         add     \pt, \virt, lsl #MMU_ENTRY_SHIFT        @ starting PT entry
141         mov32   \tmp2, (1 << MMU_MEMORY_TTBR_L3_VADDR_SHIFT)
142         mov     \tmp, \len
143 3:
144         stmia   \pt!, {\phys, \zero}                    @ write PTE and upper 0
145         add     \phys, \phys, \tmp2
146         subs    \tmp, \tmp, #(1 << MMU_MEMORY_TTBR_L3_VADDR_SHIFT)
147         bne     3b
148
149         /* clear what remains of the page */
150         mov32   \tmp, (MMU_MEMORY_TTBR_L3_SIZE - 1)
151         ands    \tmp, \pt, \tmp
152         beq     5f                              @ done, ended on a page
153
154         mov32   \tmp2, MMU_MEMORY_TTBR_L3_SIZE
155         sub     \tmp, \tmp2, \tmp               @ bytes until end of page
156         mov     \tmp2, \zero
157 4:
158         stmia   \pt!, {\tmp2, \zero}            @ write PTE and upper 0
159         subs    \tmp, \tmp, #(1 << MMU_ENTRY_SHIFT)
160         bne     4b
161 5:
162 .endm
163
164 /* map phys carveout with L2 block entries */
165 .macro mmu_desc_map_phys_l2, virt, phys, len, pt, tmp
166         mov32   \tmp, MMU_PTE_L2_BLOCK_KERN_FLAGS
167         add     \phys, \phys, \tmp
168         lsr     \virt, \virt, #(MMU_L2_BLOCK_SHIFT - MMU_ENTRY_SHIFT)
169         add     \pt, \pt, \virt
170         add     \len, \phys, \len
171         mov     \tmp, #0
172 1:
173         stmia   \pt!, {\phys, \tmp}     @ write PTE and upper 0
174         add     \phys, \phys, #(1 << MMU_L2_BLOCK_SHIFT)
175         cmp     \phys, \len
176         bne     1b
177 .endm
178
179 /* map phys carveout in L1 */
180 .macro mmu_desc_map_phys_l1, phys, pt, zero
181         orr     \phys, \phys, #0x3
182         /* write first level entries (with the 4 parts of the main tt) */
183         stmia   \pt!, {\phys, \zero}            @ index 0
184         add     \phys, \phys, #(1 << 12)
185         stmia   \pt!, {\phys, \zero}            @ index 1
186         add     \phys, \phys, #(1 << 12)
187         stmia   \pt!, {\phys, \zero}            @ index 2
188         add     \phys, \phys, #(1 << 12)
189         stmia   \pt!, {\phys, \zero}            @ index 3
190 .endm
191
192 /* init MMU registers and enable */
193 .macro mmu_desc_init_mmu, pt1, pt2, tmp
194         /* init kernel referenced mem attribs */
195         mov32   \tmp, MMU_MEMORY_ATTR_INDIR_0
196         mcr     p15, 0, \tmp, c10, c2, 0        @ MAIR0
197         mov32   \tmp, MMU_MEMORY_ATTR_INDIR_1
198         mcr     p15, 0, \tmp, c10, c2, 1        @ MAIR1
199
200         mov32   \tmp, MMU_TTBCR_FLAGS
201         mcr     p15, 0, \tmp, c2, c0, 2         @ TTBCR
202
203         mov     \tmp, #0
204         mcrr    p15, 1, \pt1, \tmp, c2          @ TTBR1 64bit write (tmp | pt1)
205
206         mrc     p15, 0, \tmp, c1, c0, 0
207         orr     \tmp, \tmp, #1
208         mcr     p15, 0, \tmp, c1, c0, 0         @ SCTLR
209 .endm
210
211 .macro mmu_desc_switch_pt, new, asid, tmp, tmp2
212         /*
213          * This is a thread that's part of a task, so switch the setup
214          * user mode context (i.e. make sure the user mode pagetables
215          * are loaded and update the VFP state).
216          *
217          * When switching user-mode translation tables we need to be sure that
218          * no pages are prefetched from the outgoing table.  To do this we
219          * we must first switch to the global translation table (ttbr1)
220          * using the following sequence:
221          *
222          *   1- switch ttbr0 to global translation table ttbr1
223          *   2- ISB
224          *   4- DSB
225          *   5- switch ttbr0 to new translation table for this thread
226          */
227         mrrc    p15, 1, \tmp, \tmp2, c2         @ get ttbr1
228         mcrr    p15, 0, \tmp, \tmp2, c2         @ load into ttbr0
229         isb
230         dsb                                     @ ARM_ERRATA_754322
231         lsl     \asid, \asid, #16               @ asid is bits[55:48]
232         mcrr    p15, 0, \new, \asid, c2         @ load into ttbr0
233 .endm
234
235 #define MMU_DESC_CONTEXT_INTS   7
236
237 /* save MMU context */
238 .macro mmu_desc_save_context, base, tmp, tmp2
239         mrc     p15, 0, \tmp, c10, c2, 0        @ MAIR0
240         str     \tmp, [\base], #4
241         mrc     p15, 0, \tmp, c10, c2, 1        @ MAIR1
242         str     \tmp, [\base], #4
243         mrc     p15, 0, \tmp, c2, c0, 2         @ TTBCR
244         str     \tmp, [\base], #4
245         mrrc    p15, 0, \tmp, \tmp2, c2         @ TTBR0 64bit
246         str     \tmp, [\base], #4
247         str     \tmp2, [\base], #4
248         mrrc    p15, 1, \tmp, \tmp2, c2         @ TTBR1 64bit
249         str     \tmp, [\base], #4
250         str     \tmp2, [\base], #4
251 .endm
252
253 /* restore MMU context */
254 .macro mmu_desc_restore_context, base, tmp, tmp2
255         ldr     \tmp, [\base], #4
256         mcr     p15, 0, \tmp, c10, c2, 0        @ MAIR0
257         ldr     \tmp, [\base], #4
258         mcr     p15, 0, \tmp, c10, c2, 1        @ MAIR1
259         ldr     \tmp, [\base], #4
260         mcr     p15, 0, \tmp, c2, c0, 2         @ TTBCR
261         ldr     \tmp, [\base], #4
262         ldr     \tmp2, [\base], #4
263         mcrr    p15, 0, \tmp, \tmp2, c2         @ TTBR0 64bit
264         ldr     \tmp, [\base], #4
265         ldr     \tmp2, [\base], #4
266         mcrr    p15, 1, \tmp, \tmp2, c2         @ TTBR1 64bit
267 .endm