First version
[3rdparty/ote_partner/tlk.git] / arch / arm / include / arch / arm / mmu_sdesc_macros.h
1 /*
2  * Copyright (c) 2013, 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_sdesc.h>
25
26 #define MMU_PAGE_TABLE          tt
27
28 #define MMU_PTE_L1_MMIO_FLAGS   \
29         ((MMU_MEMORY_L1_TYPE_STRONGLY_ORDERED | \
30           MMU_MEMORY_L1_AP_P_RW_U_NA) | 0x2)
31
32 #define MMU_PTE_L1_KERN_FLAGS   \
33         ((MMU_MEMORY_SET_L1_INNER(MMU_MEMORY_WRITE_BACK_ALLOCATE) |     \
34           MMU_MEMORY_SET_L1_OUTER(MMU_MEMORY_WRITE_BACK_NO_ALLOCATE) |  \
35           MMU_MEMORY_SET_L1_CACHEABLE_MEM |     \
36           MMU_MEMORY_L1_AP_P_RW_U_NA) | 0x2)
37
38 #define MMU_TTBR1_IWBA_OWBA     \
39         (MMU_MEMORY_TTBR1_IRGN_RGN)
40
41
42 /* loads 32-bit value into a register */
43 .macro mov32, reg, val
44         movw    \reg, #:lower16:\val
45         movt    \reg, #:upper16:\val
46 .endm
47
48 /* sections require 1MB alignment */
49 .macro mmu_desc_phy_align, base, size, tmp
50         mov32   \tmp, 0xFFFFF
51         tst     \base, \tmp
52         bne     .               @ base not aligned
53         cmp     \size, #0
54         beq     .               @ size is zero
55         tst     \size, \tmp
56         bne     .               @ size not aligned
57 .endm
58
59 /* fill in pagetable */
60 .macro mmu_desc_setup_pt, pt, pte, idx, tmp, tmp2
61         /* NULL entry */
62         ldr     \pt, =MMU_PAGE_TABLE            @ virt pt addr
63         adr     \tmp, __load_phys_base
64         ldr     \tmp, [\tmp]
65         mov32   \idx, VMEMBASE
66         sub     \idx, \tmp, \idx
67         add     \pt, \idx, \pt                  @ phys pt addr
68         mov     \pte, #0
69         mov     \idx, #0
70         str     \pte, [\pt, \idx, lsl #2]       @ NULL ptr access fault
71
72         /* create identity entries */
73         mov32   \tmp, MMU_PTE_L1_MMIO_FLAGS
74         add     \idx, #1
75 ident_loop:
76         add     \pte, \tmp, \idx, lsl #20
77         str     \pte, [\pt, \idx, lsl #2]       @ identity mapping
78         add     \idx, #1
79         cmp     \idx, #0x1000                   @ number of 1MB mappings
80         blt     ident_loop
81
82         /* map VMEMBASE for physize entries */
83         adr     \tmp, __load_phys_base
84         ldr     \tmp, [\tmp]
85         mov32   \pte, MMU_PTE_L1_KERN_FLAGS
86         add     \pte, \pte, \tmp
87
88         adr     \tmp, __load_phys_size
89         ldr     \tmp, [\tmp]
90         mov32   \idx, (VMEMBASE >> 20)
91         add     \tmp, \idx, \tmp, lsr #20       @ last VMEM index
92
93 vtop_loop:
94         str     \pte, [\pt, \idx, lsl #2]       @ VMEMBASE mapping
95         add     \idx, #1
96         add     \pte, \pte, #(1 << 20)
97         cmp     \idx, \tmp
98         blt     vtop_loop
99
100         /* map phys alias with same KERN_FLAG ptes */
101         adr     \tmp, __load_phys_base
102         ldr     \tmp, [\tmp]
103         mov32   \pte, MMU_PTE_L1_KERN_FLAGS
104         mov     \idx, \tmp, lsr #20
105         add     \pte, \pte, \tmp
106
107         adr     \tmp, __load_phys_size
108         ldr     \tmp, [\tmp]
109         add     \tmp, \idx, \tmp, lsr #20       @ last alias index
110
111 alias_loop:
112         str     \pte, [\pt, \idx, lsl #2]       @ phys alias mapping
113         add     \idx, #1
114         add     \pte, \pte, #(1 << 20)
115         cmp     \idx, \tmp
116         blt     alias_loop
117 .endm
118
119 /* init MMU registers and enable */
120 .macro mmu_desc_init_mmu, tmp, tmp2
121         mov     \tmp, #MMU_MEMORY_TTBCR_N
122         mcr     p15, 0, \tmp, c2, c0, 2         @ TTBCR
123
124         adr     \tmp, __load_phys_base
125         ldr     \tmp, [\tmp]
126         mov32   \tmp2, VMEMBASE
127         sub     \tmp2, \tmp, \tmp2              @ vtop offset
128
129         ldr     \tmp, =MMU_PAGE_TABLE           @ virt pt addr
130         add     \tmp, \tmp2, \tmp               @ phys pt addr
131
132         mov32   \tmp2, MMU_TTBR1_IWBA_OWBA
133         orr     \tmp, \tmp2
134         mcr     p15, 0, \tmp, c2, c0, 1         @ TTBR1
135
136         mov     \tmp, #1
137         mcr     p15, 0, \tmp, c3, c0, 0         @ DACR
138
139         mrc     p15, 0, \tmp, c1, c0, 0
140         orr     \tmp, \tmp, #1
141         mcr     p15, 0, \tmp, c1, c0, 0         @ SCTLR
142 .endm
143
144 .macro mmu_desc_switch_pt, new, asid, tmp, tmp2
145         /*
146          * This is a thread that's part of a task, so switch the setup
147          * user mode context (i.e. make sure the user mode pagetables
148          * are loaded and update the VFP state).
149          *
150          * When switching user-mode translation tables we need to be sure that
151          * no pages are prefetched from the outgoing table.  To do this we
152          * we must first switch to the global translation table (ttbr1)
153          * using the following sequence:
154          *
155          *   1- switch ttbr0 to global translation table ttbr1
156          *   2- ISB
157          *   3- change state (i.e. contextidr)
158          *   4- DSB
159          *   5- switch ttbr0 to new translation table for this thread
160          */
161         mrc     p15, 0, \tmp, c2, c0, 1         @ get ttbr1
162         mcr     p15, 0, \tmp, c2, c0, 0         @ load into ttbr0
163         isb
164         dsb                                     @ ARM_ERRATA_754322
165         mcr     p15, 0, \asid, c13, c0, 1       @ contextidr
166         isb
167 #if ARM_USE_CPU_CACHING
168         /* I:wb/alloc O:wb/alloc */
169         orr     \new, \new, #0x48
170 #endif
171         mcr     p15, 0, \new, c2, c0, 0         @ ttbr0
172 .endm
173
174 #define MMU_DESC_CONTEXT_INTS   5
175
176 /* save MMU context */
177 .macro mmu_desc_save_context, base, tmp, tmp2
178         mrc     p15, 0, \tmp, c2, c0, 2         @ TTBCR
179         str     \tmp, [\base], #4
180         mrc     p15, 0, \tmp, c2, c0, 0         @ TTBR0
181         str     \tmp, [\base], #4
182         mrc     p15, 0, \tmp, c13, c0, 1        @ CONTEXTIDR
183         str     \tmp, [\base], #4
184         mrc     p15, 0, \tmp, c2, c0, 1         @ TTBR1
185         str     \tmp, [\base], #4
186         mrc     p15, 0, \tmp, c3, c0, 0         @ DACR
187         str     \tmp, [\base], #4
188 .endm
189
190
191 /* restore MMU context */
192 .macro mmu_desc_restore_context, base, tmp, tmp2
193         ldr     \tmp, [\base], #4
194         mcr     p15, 0, \tmp, c2, c0, 2         @ TTBCR
195         ldr     \tmp, [\base], #4
196         mcr     p15, 0, \tmp, c2, c0, 0         @ TTBR0
197         ldr     \tmp, [\base], #4
198         mcr     p15, 0, \tmp, c13, c0, 1        @ CONTEXTIDR
199         ldr     \tmp, [\base], #4
200         mcr     p15, 0, \tmp, c2, c0, 1         @ TTBR1
201         ldr     \tmp, [\base], #4
202         mcr     p15, 0, \tmp, c3, c0, 0         @ DACR
203 .endm