Update from upstream to 2.4.0 version
[platform/core/security/tef-optee_os.git] / core / arch / arm / include / mm / core_mmu.h
1 /*
2  * Copyright (c) 2016, Linaro Limited
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 #ifndef CORE_MMU_H
29 #define CORE_MMU_H
30
31 #include <compiler.h>
32 #include <kernel/user_ta.h>
33 #include <mm/tee_mmu_types.h>
34 #include <types_ext.h>
35
36 /* A small page is the smallest unit of memory that can be mapped */
37 #define SMALL_PAGE_SHIFT        12
38 #define SMALL_PAGE_MASK         0x00000fff
39 #define SMALL_PAGE_SIZE         0x00001000
40
41 /*
42  * PGDIR is the translation table above the translation table that holds
43  * the pages.
44  */
45 #ifdef CFG_WITH_LPAE
46 #define CORE_MMU_PGDIR_SHIFT    21
47 #else
48 #define CORE_MMU_PGDIR_SHIFT    20
49 #endif
50 #define CORE_MMU_PGDIR_SIZE             (1 << CORE_MMU_PGDIR_SHIFT)
51 #define CORE_MMU_PGDIR_MASK             (CORE_MMU_PGDIR_SIZE - 1)
52
53 /* Devices are mapped using this granularity */
54 #define CORE_MMU_DEVICE_SHIFT           CORE_MMU_PGDIR_SHIFT
55 #define CORE_MMU_DEVICE_SIZE            (1 << CORE_MMU_DEVICE_SHIFT)
56 #define CORE_MMU_DEVICE_MASK            (CORE_MMU_DEVICE_SIZE - 1)
57
58 /* TA user space code, data, stack and heap are mapped using this granularity */
59 #ifdef CFG_SMALL_PAGE_USER_TA
60 #define CORE_MMU_USER_CODE_SHIFT        SMALL_PAGE_SHIFT
61 #else
62 #define CORE_MMU_USER_CODE_SHIFT        CORE_MMU_PGDIR_SHIFT
63 #endif
64 #define CORE_MMU_USER_CODE_SIZE         (1 << CORE_MMU_USER_CODE_SHIFT)
65 #define CORE_MMU_USER_CODE_MASK         (CORE_MMU_USER_CODE_SIZE - 1)
66
67 /* TA user space parameters are mapped using this granularity */
68 #ifdef CFG_SMALL_PAGE_USER_TA
69 #define CORE_MMU_USER_PARAM_SHIFT       SMALL_PAGE_SHIFT
70 #else
71 #define CORE_MMU_USER_PARAM_SHIFT       CORE_MMU_PGDIR_SHIFT
72 #endif
73 #define CORE_MMU_USER_PARAM_SIZE        (1 << CORE_MMU_USER_PARAM_SHIFT)
74 #define CORE_MMU_USER_PARAM_MASK        (CORE_MMU_USER_PARAM_SIZE - 1)
75
76 /*
77  * Memory area type:
78  * MEM_AREA_NOTYPE:   Undefined type. Used as end of table.
79  * MEM_AREA_TEE_RAM:  teecore execution RAM (secure, reserved to TEE, unused)
80  * MEM_AREA_TEE_COHERENT: teecore coherent RAM (secure, reserved to TEE)
81  * MEM_AREA_TA_RAM:   Secure RAM where teecore loads/exec TA instances.
82  * MEM_AREA_NSEC_SHM: NonSecure shared RAM between NSec and TEE.
83  * MEM_AREA_RAM_NSEC: NonSecure RAM storing data
84  * MEM_AREA_RAM_SEC:  Secure RAM storing some secrets
85  * MEM_AREA_IO_NSEC:  NonSecure HW mapped registers
86  * MEM_AREA_IO_SEC:   Secure HW mapped registers
87  * MEM_AREA_RES_VASPACE: Reserved virtual memory space
88  * MEM_AREA_TA_VASPACE: TA va space, only used with phys_to_virt()
89  * MEM_AREA_MAXTYPE:  lower invalid 'type' value
90  */
91 enum teecore_memtypes {
92         MEM_AREA_NOTYPE = 0,
93         MEM_AREA_TEE_RAM,
94         MEM_AREA_TEE_COHERENT,
95         MEM_AREA_TA_RAM,
96         MEM_AREA_NSEC_SHM,
97         MEM_AREA_RAM_NSEC,
98         MEM_AREA_RAM_SEC,
99         MEM_AREA_IO_NSEC,
100         MEM_AREA_IO_SEC,
101         MEM_AREA_RES_VASPACE,
102         MEM_AREA_TA_VASPACE,
103         MEM_AREA_SDP_MEM,
104         MEM_AREA_MAXTYPE
105 };
106
107 struct core_mmu_phys_mem {
108         const char *name;
109         enum teecore_memtypes type;
110         paddr_t addr;
111         size_t size;
112 };
113
114 #define register_phys_mem(type, addr, size) \
115         static const struct core_mmu_phys_mem __phys_mem_ ## addr \
116                 __used __section("phys_mem_map_section") = \
117                 { #addr, (type), (addr), (size) }
118
119 #define __register_sdp_mem2(pa, sz, id) \
120         static const struct core_mmu_phys_mem __phys_sdp_mem_ ## id \
121                 __used __section("phys_sdp_mem_section") = \
122                 { .type = MEM_AREA_SDP_MEM, .addr = (pa), .size = (sz), }
123
124 #define __register_sdp_mem1(pa, sz, id) __register_sdp_mem2(pa, sz, id)
125 #define register_sdp_mem(pa, sz)        __register_sdp_mem1(pa, sz, __COUNTER__)
126
127 /* Default NSec shared memory allocated from NSec world */
128 extern unsigned long default_nsec_shm_paddr;
129 extern unsigned long default_nsec_shm_size;
130
131 void core_init_mmu_map(void);
132 void core_init_mmu_regs(void);
133
134 bool core_mmu_place_tee_ram_at_top(paddr_t paddr);
135
136 #ifdef CFG_WITH_LPAE
137 /*
138  * struct core_mmu_user_map - current user mapping register state
139  * @user_map:   physical address of user map translation table
140  * @asid:       ASID for the user map
141  *
142  * Note that this struct should be treated as an opaque struct since
143  * the content depends on descriptor table format.
144  */
145 struct core_mmu_user_map {
146         uint64_t user_map;
147         uint32_t asid;
148 };
149 #else
150 /*
151  * struct core_mmu_user_map - current user mapping register state
152  * @ttbr0:      content of ttbr0
153  * @ctxid:      content of contextidr
154  *
155  * Note that this struct should be treated as an opaque struct since
156  * the content depends on descriptor table format.
157  */
158 struct core_mmu_user_map {
159         uint32_t ttbr0;
160         uint32_t ctxid;
161 };
162 #endif
163
164 #ifdef CFG_WITH_LPAE
165 bool core_mmu_user_va_range_is_defined(void);
166 #else
167 static inline bool core_mmu_user_va_range_is_defined(void)
168 {
169         return true;
170 }
171 #endif
172
173 /*
174  * core_mmu_get_user_va_range() - Return range of user va space
175  * @base:       Lowest user virtual address
176  * @size:       Size in bytes of user address space
177  */
178 void core_mmu_get_user_va_range(vaddr_t *base, size_t *size);
179
180 /*
181  * enum core_mmu_fault - different kinds of faults
182  * @CORE_MMU_FAULT_ALIGNMENT:           alignment fault
183  * @CORE_MMU_FAULT_DEBUG_EVENT:         debug event
184  * @CORE_MMU_FAULT_TRANSLATION:         translation fault
185  * @CORE_MMU_FAULT_WRITE_PERMISSION:    Permission fault during write
186  * @CORE_MMU_FAULT_READ_PERMISSION:     Permission fault during read
187  * @CORE_MMU_FAULT_ASYNC_EXTERNAL:      asynchronous external abort
188  * @CORE_MMU_FAULT_ACCESS_BIT:          access bit fault
189  * @CORE_MMU_FAULT_OTHER:               Other/unknown fault
190  */
191 enum core_mmu_fault {
192         CORE_MMU_FAULT_ALIGNMENT,
193         CORE_MMU_FAULT_DEBUG_EVENT,
194         CORE_MMU_FAULT_TRANSLATION,
195         CORE_MMU_FAULT_WRITE_PERMISSION,
196         CORE_MMU_FAULT_READ_PERMISSION,
197         CORE_MMU_FAULT_ASYNC_EXTERNAL,
198         CORE_MMU_FAULT_ACCESS_BIT,
199         CORE_MMU_FAULT_OTHER,
200 };
201
202 /*
203  * core_mmu_get_fault_type() - get fault type
204  * @fault_descr:        Content of fault status or exception syndrome register
205  * @returns an enum describing the content of fault status register.
206  */
207 enum core_mmu_fault core_mmu_get_fault_type(uint32_t fault_descr);
208
209 /*
210  * core_mm_type_to_attr() - convert memory type to attribute
211  * @t: memory type
212  * @returns an attribute that can be passed to core_mm_set_entry() and friends
213  */
214 uint32_t core_mmu_type_to_attr(enum teecore_memtypes t);
215
216 /*
217  * core_mmu_create_user_map() - Create user space mapping
218  * @utc:        Pointer to user TA context
219  * @map:        MMU configuration to use when activating this VA space
220  */
221 void core_mmu_create_user_map(struct user_ta_ctx *utc,
222                               struct core_mmu_user_map *map);
223 /*
224  * core_mmu_get_user_map() - Reads current MMU configuration for user VA space
225  * @map:        MMU configuration for current user VA space.
226  */
227 void core_mmu_get_user_map(struct core_mmu_user_map *map);
228
229 /*
230  * core_mmu_set_user_map() - Set new MMU configuration for user VA space
231  * @map:        If NULL will disable user VA space, if not NULL the user
232  *              VA space to activate.
233  */
234 void core_mmu_set_user_map(struct core_mmu_user_map *map);
235
236 /*
237  * struct core_mmu_table_info - Properties for a translation table
238  * @table:      Pointer to translation table
239  * @va_base:    VA base address of the transaltion table
240  * @level:      Translation table level
241  * @shift:      The shift of each entry in the table
242  * @num_entries: Number of entries in this table.
243  */
244 struct core_mmu_table_info {
245         void *table;
246         vaddr_t va_base;
247         unsigned level;
248         unsigned shift;
249         unsigned num_entries;
250 };
251
252 /*
253  * core_mmu_find_table() - Locates a translation table
254  * @va:         Virtual address for the table to cover
255  * @max_level:  Don't traverse beyond this level
256  * @tbl_info:   Pointer to where to store properties.
257  * @return true if a translation table was found, false on error
258  */
259 bool core_mmu_find_table(vaddr_t va, unsigned max_level,
260                 struct core_mmu_table_info *tbl_info);
261
262 /*
263  * core_mmu_divide_block() - divide larger block/section into smaller ones
264  * @tbl_info:   table where target record located
265  * @idx:        index of record
266  * @return true if function was able to divide block, false on error
267  */
268 bool core_mmu_divide_block(struct core_mmu_table_info *tbl_info,
269                            unsigned int idx);
270
271 void core_mmu_set_entry_primitive(void *table, size_t level, size_t idx,
272                                   paddr_t pa, uint32_t attr);
273
274 void core_mmu_get_user_pgdir(struct core_mmu_table_info *pgd_info);
275
276 /*
277  * core_mmu_set_entry() - Set entry in translation table
278  * @tbl_info:   Translation table properties
279  * @idx:        Index of entry to update
280  * @pa:         Physical address to assign entry
281  * @attr:       Attributes to assign entry
282  */
283 void core_mmu_set_entry(struct core_mmu_table_info *tbl_info, unsigned idx,
284                         paddr_t pa, uint32_t attr);
285
286 void core_mmu_get_entry_primitive(const void *table, size_t level, size_t idx,
287                                   paddr_t *pa, uint32_t *attr);
288
289 /*
290  * core_mmu_get_entry() - Get entry from translation table
291  * @tbl_info:   Translation table properties
292  * @idx:        Index of entry to read
293  * @pa:         Physical address is returned here if pa is not NULL
294  * @attr:       Attributues are returned here if attr is not NULL
295  */
296 void core_mmu_get_entry(struct core_mmu_table_info *tbl_info, unsigned idx,
297                         paddr_t *pa, uint32_t *attr);
298
299 /*
300  * core_mmu_va2idx() - Translate from virtual address to table index
301  * @tbl_info:   Translation table properties
302  * @va:         Virtual address to translate
303  * @returns index in transaltion table
304  */
305 static inline unsigned core_mmu_va2idx(struct core_mmu_table_info *tbl_info,
306                         vaddr_t va)
307 {
308         return (va - tbl_info->va_base) >> tbl_info->shift;
309 }
310
311 /*
312  * core_mmu_idx2va() - Translate from table index to virtual address
313  * @tbl_info:   Translation table properties
314  * @idx:        Index to translate
315  * @returns Virtual address
316  */
317 static inline vaddr_t core_mmu_idx2va(struct core_mmu_table_info *tbl_info,
318                         unsigned idx)
319 {
320         return (idx << tbl_info->shift) + tbl_info->va_base;
321 }
322
323 /*
324  * core_mmu_get_block_offset() - Get offset inside a block/page
325  * @tbl_info:   Translation table properties
326  * @pa:         Physical address
327  * @returns offset within one block of the translation table
328  */
329 static inline size_t core_mmu_get_block_offset(
330                         struct core_mmu_table_info *tbl_info, paddr_t pa)
331 {
332         return pa & ((1 << tbl_info->shift) - 1);
333 }
334
335 /*
336  * core_mmu_user_mapping_is_active() - Report if user mapping is active
337  * @returns true if a user VA space is active, false if user VA space is
338  *          inactive.
339  */
340 bool core_mmu_user_mapping_is_active(void);
341
342 /*
343  * core_mmu_mattr_is_ok() - Check that supplied mem attributes can be used
344  * @returns true if the attributes can be used, false if not.
345  */
346 bool core_mmu_mattr_is_ok(uint32_t mattr);
347
348 void core_mmu_get_mem_by_type(enum teecore_memtypes type, vaddr_t *s,
349                               vaddr_t *e);
350
351 enum teecore_memtypes core_mmu_get_type_by_pa(paddr_t pa);
352
353 /* Function is deprecated, use virt_to_phys() instead */
354 int core_va2pa_helper(void *va, paddr_t *pa);
355
356 /* routines to retreive shared mem configuration */
357 bool core_mmu_is_shm_cached(void);
358
359 bool core_mmu_add_mapping(enum teecore_memtypes type, paddr_t addr, size_t len);
360
361 /* various invalidate secure TLB */
362 enum teecore_tlb_op {
363         TLBINV_UNIFIEDTLB,      /* invalidate unified tlb */
364         TLBINV_CURRENT_ASID,    /* invalidate unified tlb for current ASID */
365         TLBINV_BY_ASID,         /* invalidate unified tlb by ASID */
366         TLBINV_BY_MVA,          /* invalidate unified tlb by MVA */
367 };
368
369 int core_tlb_maintenance(int op, unsigned int a);
370
371 /* Cache maintenance operation type */
372 enum cache_op {
373         DCACHE_CLEAN,
374         DCACHE_AREA_CLEAN,
375         DCACHE_INVALIDATE,
376         DCACHE_AREA_INVALIDATE,
377         ICACHE_INVALIDATE,
378         ICACHE_AREA_INVALIDATE,
379         DCACHE_CLEAN_INV,
380         DCACHE_AREA_CLEAN_INV,
381 };
382
383 /* L1/L2 cache maintenance */
384 TEE_Result cache_op_inner(enum cache_op op, void *va, size_t len);
385 #ifdef CFG_PL310
386 TEE_Result cache_op_outer(enum cache_op op, paddr_t pa, size_t len);
387 #else
388 static inline TEE_Result cache_op_outer(enum cache_op op __unused,
389                                                 paddr_t pa __unused,
390                                                 size_t len __unused)
391 {
392         /* Nothing to do about L2 Cache Maintenance when no PL310 */
393         return TEE_SUCCESS;
394 }
395 #endif
396
397 /* Check cpu mmu enabled or not */
398 bool cpu_mmu_enabled(void);
399
400 #ifdef CFG_SECURE_DATA_PATH
401 /* Alloc and fill SDP memory objects table - table is NULL terminated */
402 struct mobj **core_sdp_mem_create_mobjs(void);
403 #endif
404
405 #endif /* CORE_MMU_H */