62dda7398dfa2626b5032e2ed6f3e9c126105619
[platform/core/security/tef-optee_os.git] / core / arch / arm / mm / core_mmu.c
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
29 /*
30  * This core mmu supports static section mapping (1MByte) and finer mapping
31  * with 4k pages.
32  *       It should also allow core to map/unmap (and va/pa) at run-time.
33  */
34
35 #include <arm.h>
36 #include <assert.h>
37 #include <kernel/generic_boot.h>
38 #include <kernel/panic.h>
39 #include <kernel/tee_l2cc_mutex.h>
40 #include <kernel/tee_misc.h>
41 #include <kernel/tee_ta_manager.h>
42 #include <kernel/thread.h>
43 #include <kernel/tz_ssvce.h>
44 #include <kernel/tz_ssvce_pl310.h>
45 #include <mm/core_memprot.h>
46 #include <mm/core_mmu.h>
47 #include <mm/mobj.h>
48 #include <mm/pgt_cache.h>
49 #include <mm/tee_mmu.h>
50 #include <mm/tee_pager.h>
51 #include <platform_config.h>
52 #include <stdlib.h>
53 #include <trace.h>
54 #include <util.h>
55
56 #include "core_mmu_private.h"
57
58 #define MAX_MMAP_REGIONS        10
59 #define RES_VASPACE_SIZE        (CORE_MMU_PGDIR_SIZE * 10)
60
61 /*
62  * These variables are initialized before .bss is cleared. To avoid
63  * resetting them when .bss is cleared we're storing them in .data instead,
64  * even if they initially are zero.
65  */
66
67 /* Default NSec shared memory allocated from NSec world */
68 unsigned long default_nsec_shm_size __early_bss;
69 unsigned long default_nsec_shm_paddr __early_bss;
70
71 static struct tee_mmap_region
72         static_memory_map[MAX_MMAP_REGIONS + 1] __early_bss;
73 static bool mem_map_inited __early_bss;
74
75 static struct tee_mmap_region *map_tee_ram __early_bss;
76 static struct tee_mmap_region *map_ta_ram __early_bss;
77 static struct tee_mmap_region *map_nsec_shm __early_bss;
78
79 /* Define the platform's memory layout. */
80 struct memaccess_area {
81         paddr_t paddr;
82         size_t size;
83 };
84 #define MEMACCESS_AREA(a, s) { .paddr = a, .size = s }
85
86 static struct memaccess_area ddr[] = {
87         MEMACCESS_AREA(DRAM0_BASE, DRAM0_SIZE),
88 #ifdef DRAM1_BASE
89         MEMACCESS_AREA(DRAM1_BASE, DRAM1_SIZE),
90 #endif
91 };
92
93 static struct memaccess_area secure_only[] = {
94 #ifdef TZSRAM_BASE
95         MEMACCESS_AREA(TZSRAM_BASE, TZSRAM_SIZE),
96 #endif
97         MEMACCESS_AREA(TZDRAM_BASE, TZDRAM_SIZE),
98 };
99
100 static struct memaccess_area nsec_shared[] = {
101         MEMACCESS_AREA(CFG_SHMEM_START, CFG_SHMEM_SIZE),
102 };
103
104 register_phys_mem(MEM_AREA_TEE_RAM, CFG_TEE_RAM_START, CFG_TEE_RAM_PH_SIZE);
105 register_phys_mem(MEM_AREA_TA_RAM, CFG_TA_RAM_START, CFG_TA_RAM_SIZE);
106 register_phys_mem(MEM_AREA_NSEC_SHM, CFG_SHMEM_START, CFG_SHMEM_SIZE);
107 #ifdef DEVICE0_PA_BASE
108 register_phys_mem(DEVICE0_TYPE, DEVICE0_PA_BASE, DEVICE0_SIZE);
109 #endif
110 #ifdef DEVICE1_PA_BASE
111 register_phys_mem(DEVICE1_TYPE, DEVICE1_PA_BASE, DEVICE1_SIZE);
112 #endif
113 #ifdef DEVICE2_PA_BASE
114 register_phys_mem(DEVICE2_TYPE, DEVICE2_PA_BASE, DEVICE2_SIZE);
115 #endif
116 #ifdef DEVICE3_PA_BASE
117 register_phys_mem(DEVICE3_TYPE, DEVICE3_PA_BASE, DEVICE3_SIZE);
118 #endif
119 #ifdef DEVICE4_PA_BASE
120 register_phys_mem(DEVICE4_TYPE, DEVICE4_PA_BASE, DEVICE4_SIZE);
121 #endif
122 #ifdef DEVICE5_PA_BASE
123 register_phys_mem(DEVICE5_TYPE, DEVICE5_PA_BASE, DEVICE5_SIZE);
124 #endif
125 #ifdef DEVICE6_PA_BASE
126 register_phys_mem(DEVICE6_TYPE, DEVICE6_PA_BASE, DEVICE6_SIZE);
127 #endif
128
129 static bool _pbuf_intersects(struct memaccess_area *a, size_t alen,
130                              paddr_t pa, size_t size)
131 {
132         size_t n;
133
134         for (n = 0; n < alen; n++)
135                 if (core_is_buffer_intersect(pa, size, a[n].paddr, a[n].size))
136                         return true;
137         return false;
138 }
139 #define pbuf_intersects(a, pa, size) \
140         _pbuf_intersects((a), ARRAY_SIZE(a), (pa), (size))
141
142 static bool _pbuf_is_inside(struct memaccess_area *a, size_t alen,
143                             paddr_t pa, size_t size)
144 {
145         size_t n;
146
147         for (n = 0; n < alen; n++)
148                 if (core_is_buffer_inside(pa, size, a[n].paddr, a[n].size))
149                         return true;
150         return false;
151 }
152 #define pbuf_is_inside(a, pa, size) \
153         _pbuf_is_inside((a), ARRAY_SIZE(a), (pa), (size))
154
155 static bool pa_is_in_map(struct tee_mmap_region *map, paddr_t pa)
156 {
157         if (!map)
158                 return false;
159         return (pa >= map->pa && pa <= (map->pa + map->size - 1));
160 }
161
162 static bool va_is_in_map(struct tee_mmap_region *map, vaddr_t va)
163 {
164         if (!map)
165                 return false;
166         return (va >= map->va && va <= (map->va + map->size - 1));
167 }
168
169 /* check if target buffer fits in a core default map area */
170 static bool pbuf_inside_map_area(unsigned long p, size_t l,
171                                  struct tee_mmap_region *map)
172 {
173         return core_is_buffer_inside(p, l, map->pa, map->size);
174 }
175
176 static struct tee_mmap_region *find_map_by_type(enum teecore_memtypes type)
177 {
178         struct tee_mmap_region *map;
179
180         for (map = static_memory_map; map->type != MEM_AREA_NOTYPE; map++)
181                 if (map->type == type)
182                         return map;
183         return NULL;
184 }
185
186 static struct tee_mmap_region *find_map_by_type_and_pa(
187                         enum teecore_memtypes type, paddr_t pa)
188 {
189         struct tee_mmap_region *map;
190
191         for (map = static_memory_map; map->type != MEM_AREA_NOTYPE; map++) {
192                 if (map->type != type)
193                         continue;
194                 if (pa_is_in_map(map, pa))
195                         return map;
196         }
197         return NULL;
198 }
199
200 static struct tee_mmap_region *find_map_by_va(void *va)
201 {
202         struct tee_mmap_region *map = static_memory_map;
203         unsigned long a = (unsigned long)va;
204
205         while (map->type != MEM_AREA_NOTYPE) {
206                 if ((a >= map->va) && (a <= (map->va - 1 + map->size)))
207                         return map;
208                 map++;
209         }
210         return NULL;
211 }
212
213 static struct tee_mmap_region *find_map_by_pa(unsigned long pa)
214 {
215         struct tee_mmap_region *map = static_memory_map;
216
217         while (map->type != MEM_AREA_NOTYPE) {
218                 if ((pa >= map->pa) && (pa < (map->pa + map->size)))
219                         return map;
220                 map++;
221         }
222         return NULL;
223 }
224
225 extern const struct core_mmu_phys_mem __start_phys_mem_map_section;
226 extern const struct core_mmu_phys_mem __end_phys_mem_map_section;
227
228 static void add_phys_mem(struct tee_mmap_region *memory_map, size_t num_elems,
229                          const struct core_mmu_phys_mem *mem, size_t *last)
230 {
231         size_t n = 0;
232         paddr_t pa;
233         size_t size;
234
235         /*
236          * When all entries are added we'd like to have it in a sorted
237          * array first based on memory type and secondly on physical
238          * address. If some ranges of memory of the same type overlaps of
239          * are next to each others they are coalesced into one entry. This
240          * makes it easier later when building the translation tables.
241          *
242          * Note that it's valid to have the same physical memory as several
243          * different memory types, for instance the same device memory
244          * mapped as both secure and non-secure. This will probably not
245          * happen often in practice.
246          */
247         DMSG("%s %d 0x%08" PRIxPA " size 0x%08zx",
248              mem->name, mem->type, mem->addr, mem->size);
249         while (true) {
250                 if (n >= (num_elems - 1)) {
251                         EMSG("Out of entries (%zu) in memory_map", num_elems);
252                         panic();
253                 }
254                 if (n == *last)
255                         break;
256                 pa = memory_map[n].pa;
257                 size = memory_map[n].size;
258                 if (mem->addr >= pa && mem->addr <= (pa + (size - 1)) &&
259                     mem->type == memory_map[n].type) {
260                         DMSG("Physical mem map overlaps 0x%" PRIxPA, mem->addr);
261                         memory_map[n].pa = MIN(pa, mem->addr);
262                         memory_map[n].size = MAX(size, mem->size) +
263                                              (pa - memory_map[n].pa);
264                         return;
265                 }
266                 if (mem->type < memory_map[n].type ||
267                     (mem->type == memory_map[n].type && mem->addr < pa))
268                         break; /* found the spot where to inseart this memory */
269                 n++;
270         }
271
272         memmove(memory_map + n + 1, memory_map + n,
273                 sizeof(struct tee_mmap_region) * (*last - n));
274         (*last)++;
275         memset(memory_map + n, 0, sizeof(memory_map[0]));
276         memory_map[n].type = mem->type;
277         memory_map[n].pa = mem->addr;
278         memory_map[n].size = mem->size;
279 }
280
281 static void add_va_space(struct tee_mmap_region *memory_map, size_t num_elems,
282                          unsigned int type, size_t size, size_t *last) {
283         size_t n = 0;
284
285         DMSG("type %d size 0x%08zx", type, size);
286         while (true) {
287                 if (n >= (num_elems - 1)) {
288                         EMSG("Out of entries (%zu) in memory_map", num_elems);
289                         panic();
290                 }
291                 if (n == *last)
292                         break;
293                 if (type < memory_map[n].type)
294                         break;
295                 n++;
296         }
297
298         memmove(memory_map + n + 1, memory_map + n,
299                 sizeof(struct tee_mmap_region) * (*last - n));
300         (*last)++;
301         memset(memory_map + n, 0, sizeof(memory_map[0]));
302         memory_map[n].type = type;
303         memory_map[n].size = size;
304 }
305
306 uint32_t core_mmu_type_to_attr(enum teecore_memtypes t)
307 {
308         const uint32_t attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW |
309                               TEE_MATTR_GLOBAL;
310         const uint32_t cached = TEE_MATTR_CACHE_CACHED << TEE_MATTR_CACHE_SHIFT;
311         const uint32_t noncache = TEE_MATTR_CACHE_NONCACHE <<
312                                   TEE_MATTR_CACHE_SHIFT;
313
314         switch (t) {
315         case MEM_AREA_TEE_RAM:
316                 return attr | TEE_MATTR_SECURE | TEE_MATTR_PX | cached;
317         case MEM_AREA_TA_RAM:
318                 return attr | TEE_MATTR_SECURE | cached;
319         case MEM_AREA_NSEC_SHM:
320                 return attr | cached;
321         case MEM_AREA_IO_NSEC:
322                 return attr | noncache;
323         case MEM_AREA_IO_SEC:
324                 return attr | TEE_MATTR_SECURE | noncache;
325         case MEM_AREA_RAM_NSEC:
326                 return attr | cached;
327         case MEM_AREA_RAM_SEC:
328                 return attr | TEE_MATTR_SECURE | cached;
329         case MEM_AREA_RES_VASPACE:
330                 return 0;
331         default:
332                 panic("invalid type");
333         }
334 }
335
336 static void init_mem_map(struct tee_mmap_region *memory_map, size_t num_elems)
337 {
338         const struct core_mmu_phys_mem *mem;
339         struct tee_mmap_region *map;
340         size_t last = 0;
341         vaddr_t va;
342         size_t n;
343
344         for (mem = &__start_phys_mem_map_section;
345              mem < &__end_phys_mem_map_section; mem++) {
346                 struct core_mmu_phys_mem m = *mem;
347
348                 if (m.type == MEM_AREA_IO_NSEC || m.type == MEM_AREA_IO_SEC) {
349                         m.addr = ROUNDDOWN(m.addr, CORE_MMU_PGDIR_SIZE);
350                         m.size = ROUNDUP(m.size + (mem->addr - m.addr),
351                                          CORE_MMU_PGDIR_SIZE);
352                 }
353                 add_phys_mem(memory_map, num_elems, &m, &last);
354         }
355
356         add_va_space(memory_map, num_elems, MEM_AREA_RES_VASPACE,
357                      RES_VASPACE_SIZE, &last);
358
359         memory_map[last].type = MEM_AREA_NOTYPE;
360
361         /*
362          * Assign region sizes, note that MEM_AREA_TEE_RAM always uses
363          * SMALL_PAGE_SIZE if paging is enabled.
364          */
365         for (map = memory_map; map->type != MEM_AREA_NOTYPE; map++) {
366                 paddr_t mask = map->pa | map->size;
367
368                 if (!(mask & CORE_MMU_PGDIR_MASK))
369                         map->region_size = CORE_MMU_PGDIR_SIZE;
370                 else if (!(mask & SMALL_PAGE_MASK))
371                         map->region_size = SMALL_PAGE_SIZE;
372                 else
373                         panic("Impossible memory alignment");
374         }
375
376         /*
377          * bootcfg_memory_map is sorted in order first by type and last by
378          * address. This puts TEE_RAM first and TA_RAM second
379          *
380          */
381         map = memory_map;
382         assert(map->type == MEM_AREA_TEE_RAM);
383         map->va = map->pa;
384 #ifdef CFG_WITH_PAGER
385         map->region_size = SMALL_PAGE_SIZE,
386 #endif
387         map->attr = core_mmu_type_to_attr(map->type);
388
389
390         if (core_mmu_place_tee_ram_at_top(map->pa)) {
391                 va = map->va;
392                 map++;
393                 while (map->type != MEM_AREA_NOTYPE) {
394                         map->attr = core_mmu_type_to_attr(map->type);
395                         va -= map->size;
396                         map->va = va;
397                         map++;
398                 }
399                 /*
400                  * The memory map should be sorted by virtual address
401                  * when this function returns. As we're assigning va in
402                  * the oposite direction we need to reverse the list.
403                  */
404                 for (n = 0; n < last / 2; n++) {
405                         struct tee_mmap_region r;
406
407                         r = memory_map[last - n - 1];
408                         memory_map[last - n - 1] = memory_map[n];
409                         memory_map[n] = r;
410                 }
411         } else {
412                 va = ROUNDUP(map->va + map->size, CORE_MMU_PGDIR_SIZE);
413                 map++;
414                 while (map->type != MEM_AREA_NOTYPE) {
415                         map->attr = core_mmu_type_to_attr(map->type);
416                         map->va = va;
417                         va += map->size;
418                         map++;
419                 }
420         }
421
422         for (map = memory_map; map->type != MEM_AREA_NOTYPE; map++) {
423                 vaddr_t __maybe_unused vstart;
424
425                 vstart = map->va + ((vaddr_t)map->pa & (map->region_size - 1));
426                 DMSG("type va %d 0x%08" PRIxVA "..0x%08" PRIxVA
427                      " pa 0x%08" PRIxPA "..0x%08" PRIxPA " size %#zx",
428                      map->type, vstart, vstart + map->size - 1,
429                      (paddr_t)map->pa, (paddr_t)map->pa + map->size - 1,
430                      map->size);
431         }
432 }
433
434 /*
435  * core_init_mmu_map - init tee core default memory mapping
436  *
437  * this routine sets the static default tee core mapping.
438  *
439  * If an error happend: core_init_mmu_map is expected to reset.
440  */
441 void core_init_mmu_map(void)
442 {
443         struct tee_mmap_region *map;
444         size_t n;
445
446         for (n = 0; n < ARRAY_SIZE(secure_only); n++) {
447                 if (pbuf_intersects(nsec_shared, secure_only[n].paddr,
448                                     secure_only[n].size))
449                         panic("Invalid memory access config: sec/nsec");
450         }
451
452         if (!mem_map_inited)
453                 init_mem_map(static_memory_map, ARRAY_SIZE(static_memory_map));
454
455         map = static_memory_map;
456         while (map->type != MEM_AREA_NOTYPE) {
457                 switch (map->type) {
458                 case MEM_AREA_TEE_RAM:
459                         if (!pbuf_is_inside(secure_only, map->pa, map->size))
460                                 panic("TEE_RAM can't fit in secure_only");
461
462                         map_tee_ram = map;
463                         break;
464                 case MEM_AREA_TA_RAM:
465                         if (!pbuf_is_inside(secure_only, map->pa, map->size))
466                                 panic("TA_RAM can't fit in secure_only");
467                         map_ta_ram = map;
468                         break;
469                 case MEM_AREA_NSEC_SHM:
470                         if (!pbuf_is_inside(nsec_shared, map->pa, map->size))
471                                 panic("NS_SHM can't fit in nsec_shared");
472                         map_nsec_shm = map;
473                         break;
474                 case MEM_AREA_IO_SEC:
475                 case MEM_AREA_IO_NSEC:
476                 case MEM_AREA_RAM_SEC:
477                 case MEM_AREA_RAM_NSEC:
478                 case MEM_AREA_RES_VASPACE:
479                         break;
480                 default:
481                         EMSG("Uhandled memtype %d", map->type);
482                         panic();
483                 }
484                 map++;
485         }
486
487         /* Check that we have the mandatory memory areas defined */
488         if (!map_tee_ram || !map_ta_ram || !map_nsec_shm)
489                 panic("mandatory area(s) not found");
490
491         core_init_mmu_tables(static_memory_map);
492 }
493
494 /* routines to retrieve shared mem configuration */
495 bool core_mmu_is_shm_cached(void)
496 {
497         if (!map_nsec_shm)
498                 return false;
499         return map_nsec_shm->attr >> TEE_MATTR_CACHE_SHIFT ==
500                TEE_MATTR_CACHE_CACHED;
501 }
502
503 bool core_mmu_mattr_is_ok(uint32_t mattr)
504 {
505         /*
506          * Keep in sync with core_mmu_lpae.c:mattr_to_desc and
507          * core_mmu_v7.c:mattr_to_texcb
508          */
509
510         switch ((mattr >> TEE_MATTR_CACHE_SHIFT) & TEE_MATTR_CACHE_MASK) {
511         case TEE_MATTR_CACHE_NONCACHE:
512         case TEE_MATTR_CACHE_CACHED:
513                 return true;
514         default:
515                 return false;
516         }
517 }
518
519 /*
520  * test attributes of target physical buffer
521  *
522  * Flags: pbuf_is(SECURE, NOT_SECURE, RAM, IOMEM, KEYVAULT).
523  *
524  */
525 bool core_pbuf_is(uint32_t attr, paddr_t pbuf, size_t len)
526 {
527         struct tee_mmap_region *map;
528
529         /* Empty buffers complies with anything */
530         if (len == 0)
531                 return true;
532
533         switch (attr) {
534         case CORE_MEM_SEC:
535                 return pbuf_is_inside(secure_only, pbuf, len);
536         case CORE_MEM_NON_SEC:
537                 return pbuf_is_inside(nsec_shared, pbuf, len);
538         case CORE_MEM_TEE_RAM:
539                 return pbuf_inside_map_area(pbuf, len, map_tee_ram);
540         case CORE_MEM_TA_RAM:
541                 return pbuf_inside_map_area(pbuf, len, map_ta_ram);
542         case CORE_MEM_NSEC_SHM:
543                 return pbuf_inside_map_area(pbuf, len, map_nsec_shm);
544         case CORE_MEM_EXTRAM:
545                 return pbuf_is_inside(ddr, pbuf, len);
546         case CORE_MEM_CACHED:
547                 map = find_map_by_pa(pbuf);
548                 if (map == NULL || !pbuf_inside_map_area(pbuf, len, map))
549                         return false;
550                 return map->attr >> TEE_MATTR_CACHE_SHIFT ==
551                        TEE_MATTR_CACHE_CACHED;
552         default:
553                 return false;
554         }
555 }
556
557 /* test attributes of target virtual buffer (in core mapping) */
558 bool core_vbuf_is(uint32_t attr, const void *vbuf, size_t len)
559 {
560         paddr_t p;
561
562         /* Empty buffers complies with anything */
563         if (len == 0)
564                 return true;
565
566         p = virt_to_phys((void *)vbuf);
567         if (!p)
568                 return false;
569
570         return core_pbuf_is(attr, p, len);
571 }
572
573
574 /* core_va2pa - teecore exported service */
575 int core_va2pa_helper(void *va, paddr_t *pa)
576 {
577         struct tee_mmap_region *map;
578
579         map = find_map_by_va(va);
580         if (!va_is_in_map(map, (vaddr_t)va))
581                 return -1;
582
583         *pa = ((uintptr_t)va & (map->region_size - 1)) |
584             ((map->pa + (uintptr_t)va - map->va) & ~(map->region_size - 1));
585         return 0;
586 }
587
588 static void *map_pa2va(struct tee_mmap_region *map, paddr_t pa)
589 {
590         if (!pa_is_in_map(map, pa))
591                 return NULL;
592         return (void *)((pa & (map->region_size - 1)) |
593                 ((map->va + pa - map->pa) & ~((vaddr_t)map->region_size - 1)));
594 }
595
596 /*
597  * teecore gets some memory area definitions
598  */
599 void core_mmu_get_mem_by_type(unsigned int type, vaddr_t *s, vaddr_t *e)
600 {
601         struct tee_mmap_region *map = find_map_by_type(type);
602
603         if (map) {
604                 *s = map->va;
605                 *e = map->va + map->size;
606         } else {
607                 *s = 0;
608                 *e = 0;
609         }
610 }
611
612 enum teecore_memtypes core_mmu_get_type_by_pa(paddr_t pa)
613 {
614         struct tee_mmap_region *map = find_map_by_pa(pa);
615
616         if (!map)
617                 return MEM_AREA_NOTYPE;
618         return map->type;
619 }
620
621 int core_tlb_maintenance(int op, unsigned int a)
622 {
623         /*
624          * We're doing TLB invalidation because we've changed mapping.
625          * The dsb() makes sure that written data is visible.
626          */
627         dsb();
628
629         switch (op) {
630         case TLBINV_UNIFIEDTLB:
631                 secure_mmu_unifiedtlbinvall();
632                 break;
633         case TLBINV_CURRENT_ASID:
634                 secure_mmu_unifiedtlbinv_curasid();
635                 break;
636         case TLBINV_BY_ASID:
637                 secure_mmu_unifiedtlbinv_byasid(a);
638                 break;
639         case TLBINV_BY_MVA:
640                 EMSG("TLB_INV_SECURE_MVA is not yet supported!");
641                 while (1)
642                         ;
643                 secure_mmu_unifiedtlbinvbymva(a);
644                 break;
645         default:
646                 return 1;
647         }
648         return 0;
649 }
650
651 unsigned int cache_maintenance_l1(int op, void *va, size_t len)
652 {
653         switch (op) {
654         case DCACHE_CLEAN:
655                 arm_cl1_d_cleanbysetway();
656                 break;
657         case DCACHE_AREA_CLEAN:
658                 if (len)
659                         arm_cl1_d_cleanbyva(va, (char *)va + len - 1);
660                 break;
661         case DCACHE_INVALIDATE:
662                 arm_cl1_d_invbysetway();
663                 break;
664         case DCACHE_AREA_INVALIDATE:
665                 if (len)
666                         arm_cl1_d_invbyva(va, (char *)va + len - 1);
667                 break;
668         case ICACHE_INVALIDATE:
669                 arm_cl1_i_inv_all();
670                 break;
671         case ICACHE_AREA_INVALIDATE:
672                 if (len)
673                         arm_cl1_i_inv(va, (char *)va + len - 1);
674                 break;
675         case WRITE_BUFFER_DRAIN:
676                 DMSG("unsupported operation 0x%X (WRITE_BUFFER_DRAIN)",
677                      (unsigned int)op);
678                 return -1;
679         case DCACHE_CLEAN_INV:
680                 arm_cl1_d_cleaninvbysetway();
681                 break;
682         case DCACHE_AREA_CLEAN_INV:
683                 if (len)
684                         arm_cl1_d_cleaninvbyva(va, (char *)va + len - 1);
685                 break;
686         default:
687                 return TEE_ERROR_NOT_IMPLEMENTED;
688         }
689         return TEE_SUCCESS;
690 }
691
692 #ifdef CFG_PL310
693 unsigned int cache_maintenance_l2(int op, paddr_t pa, size_t len)
694 {
695         unsigned int ret = TEE_SUCCESS;
696         uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_IRQ);
697
698         tee_l2cc_mutex_lock();
699         switch (op) {
700         case L2CACHE_INVALIDATE:
701                 arm_cl2_invbyway(pl310_base());
702                 break;
703         case L2CACHE_AREA_INVALIDATE:
704                 if (len)
705                         arm_cl2_invbypa(pl310_base(), pa, pa + len - 1);
706                 break;
707         case L2CACHE_CLEAN:
708                 arm_cl2_cleanbyway(pl310_base());
709                 break;
710         case L2CACHE_AREA_CLEAN:
711                 if (len)
712                         arm_cl2_cleanbypa(pl310_base(), pa, pa + len - 1);
713                 break;
714         case L2CACHE_CLEAN_INV:
715                 arm_cl2_cleaninvbyway(pl310_base());
716                 break;
717         case L2CACHE_AREA_CLEAN_INV:
718                 if (len)
719                         arm_cl2_cleaninvbypa(pl310_base(), pa, pa + len - 1);
720                 break;
721         default:
722                 ret = TEE_ERROR_NOT_IMPLEMENTED;
723         }
724
725         tee_l2cc_mutex_unlock();
726         thread_set_exceptions(exceptions);
727         return ret;
728 }
729 #endif /*CFG_PL310*/
730
731 void core_mmu_set_entry(struct core_mmu_table_info *tbl_info, unsigned idx,
732                         paddr_t pa, uint32_t attr)
733 {
734         assert(idx < tbl_info->num_entries);
735         core_mmu_set_entry_primitive(tbl_info->table, tbl_info->level,
736                                      idx, pa, attr);
737 }
738
739 void core_mmu_get_entry(struct core_mmu_table_info *tbl_info, unsigned idx,
740                         paddr_t *pa, uint32_t *attr)
741 {
742         assert(idx < tbl_info->num_entries);
743         core_mmu_get_entry_primitive(tbl_info->table, tbl_info->level,
744                                      idx, pa, attr);
745 }
746
747 static void set_region(struct core_mmu_table_info *tbl_info,
748                 struct tee_mmap_region *region)
749 {
750         unsigned end;
751         unsigned idx;
752         paddr_t pa;
753
754         /* va, len and pa should be block aligned */
755         assert(!core_mmu_get_block_offset(tbl_info, region->va));
756         assert(!core_mmu_get_block_offset(tbl_info, region->size));
757         assert(!core_mmu_get_block_offset(tbl_info, region->pa));
758
759         idx = core_mmu_va2idx(tbl_info, region->va);
760         end = core_mmu_va2idx(tbl_info, region->va + region->size);
761         pa = region->pa;
762
763         while (idx < end) {
764                 core_mmu_set_entry(tbl_info, idx, pa, region->attr);
765                 idx++;
766                 pa += 1 << tbl_info->shift;
767         }
768 }
769
770 #ifdef CFG_SMALL_PAGE_USER_TA
771 static void set_pg_region(struct core_mmu_table_info *dir_info,
772                         struct tee_ta_region *region, struct pgt **pgt,
773                         struct core_mmu_table_info *pg_info)
774 {
775         struct tee_mmap_region r = {
776                 .va = region->va,
777                 .size = region->size,
778                 .attr = region->attr,
779         };
780         vaddr_t end = r.va + r.size;
781         uint32_t pgt_attr = (r.attr & TEE_MATTR_SECURE) | TEE_MATTR_TABLE;
782
783         while (r.va < end) {
784                 if (!pg_info->table ||
785                      r.va >= (pg_info->va_base + CORE_MMU_PGDIR_SIZE)) {
786                         /*
787                          * We're assigning a new translation table.
788                          */
789                         unsigned int idx;
790
791                         assert(*pgt); /* We should have alloced enough */
792
793                         /* Virtual addresses must grow */
794                         assert(r.va > pg_info->va_base);
795
796                         idx = core_mmu_va2idx(dir_info, r.va);
797                         pg_info->table = (*pgt)->tbl;
798                         pg_info->va_base = core_mmu_idx2va(dir_info, idx);
799 #ifdef CFG_PAGED_USER_TA
800                         assert((*pgt)->vabase == pg_info->va_base);
801 #endif
802                         *pgt = SLIST_NEXT(*pgt, link);
803
804                         core_mmu_set_entry(dir_info, idx,
805                                            virt_to_phys(pg_info->table),
806                                            pgt_attr);
807                 }
808
809                 r.size = MIN(CORE_MMU_PGDIR_SIZE - (r.va - pg_info->va_base),
810                              end - r.va);
811                 if (!mobj_is_paged(region->mobj)) {
812                         size_t granule = BIT(pg_info->shift);
813                         size_t offset = r.va - region->va + region->offset;
814
815                         if (mobj_get_pa(region->mobj, offset, granule,
816                                         &r.pa) != TEE_SUCCESS)
817                                 panic("Failed to get PA of unpaged mobj");
818                         set_region(pg_info, &r);
819                 }
820                 r.va += r.size;
821         }
822 }
823
824 void core_mmu_populate_user_map(struct core_mmu_table_info *dir_info,
825                                 struct user_ta_ctx *utc)
826 {
827         struct core_mmu_table_info pg_info;
828         struct pgt_cache *pgt_cache = &thread_get_tsd()->pgt_cache;
829         struct pgt *pgt;
830         size_t n;
831
832         /* Find the last valid entry */
833         n = ARRAY_SIZE(utc->mmu->regions);
834         while (true) {
835                 n--;
836                 if (utc->mmu->regions[n].size)
837                         break;
838                 if (!n)
839                         return; /* Nothing to map */
840         }
841
842         /*
843          * Allocate all page tables in advance.
844          */
845         pgt_alloc(pgt_cache, &utc->ctx, utc->mmu->regions[0].va,
846                   utc->mmu->regions[n].va + utc->mmu->regions[n].size - 1);
847         pgt = SLIST_FIRST(pgt_cache);
848
849         core_mmu_set_info_table(&pg_info, dir_info->level + 1, 0, NULL);
850
851         for (n = 0; n < ARRAY_SIZE(utc->mmu->regions); n++)
852                 mobj_update_mapping(utc->mmu->regions[n].mobj, utc,
853                                     utc->mmu->regions[n].va);
854
855         for (n = 0; n < ARRAY_SIZE(utc->mmu->regions); n++) {
856                 if (!utc->mmu->regions[n].size)
857                         continue;
858                 set_pg_region(dir_info, utc->mmu->regions + n, &pgt, &pg_info);
859         }
860 }
861
862 #else
863 void core_mmu_populate_user_map(struct core_mmu_table_info *dir_info,
864                                 struct user_ta_ctx *utc)
865 {
866         unsigned n;
867         struct tee_mmap_region r;
868         size_t offset;
869         size_t granule = BIT(dir_info->shift);
870
871         memset(&r, 0, sizeof(r));
872         for (n = 0; n < ARRAY_SIZE(utc->mmu->regions); n++) {
873                 if (!utc->mmu->regions[n].size)
874                         continue;
875
876                 offset = utc->mmu->regions[n].offset;
877                 r.va = utc->mmu->regions[n].va;
878                 r.size = utc->mmu->regions[n].size;
879                 r.attr = utc->mmu->regions[n].attr;
880
881                 if (mobj_get_pa(utc->mmu->regions[n].mobj, offset, granule,
882                                 &r.pa) != TEE_SUCCESS)
883                         panic("Failed to get PA of unpaged mobj");
884
885                 set_region(dir_info, &r);
886         }
887 }
888 #endif
889
890 bool core_mmu_add_mapping(enum teecore_memtypes type, paddr_t addr, size_t len)
891 {
892         struct core_mmu_table_info tbl_info;
893         struct tee_mmap_region *map;
894         size_t n;
895         size_t granule;
896         paddr_t p;
897         size_t l;
898
899         if (!len)
900                 return true;
901
902         /* Check if the memory is already mapped */
903         map = find_map_by_type_and_pa(type, addr);
904         if (map && pbuf_inside_map_area(addr, len, map))
905                 return true;
906
907         /* Find the reserved va space used for late mappings */
908         map = find_map_by_type(MEM_AREA_RES_VASPACE);
909         if (!map)
910                 return false;
911
912         if (!core_mmu_find_table(map->va, UINT_MAX, &tbl_info))
913                 return false;
914
915         granule = 1 << tbl_info.shift;
916         p = ROUNDDOWN(addr, granule);
917         l = ROUNDUP(len + addr - p, granule);
918         /*
919          * Something is wrong, we can't fit the va range into the selected
920          * table. The reserved va range is possibly missaligned with
921          * granule.
922          */
923         if (core_mmu_va2idx(&tbl_info, map->va + len) >= tbl_info.num_entries)
924                 return false;
925
926         /* Find end of the memory map */
927         n = 0;
928         while (static_memory_map[n].type != MEM_AREA_NOTYPE)
929                 n++;
930
931         if (n < (ARRAY_SIZE(static_memory_map) - 1)) {
932                 /* There's room for another entry */
933                 static_memory_map[n].va = map->va;
934                 static_memory_map[n].size = l;
935                 static_memory_map[n + 1].type = MEM_AREA_NOTYPE;
936                 map->va += l;
937                 map->size -= l;
938                 map = static_memory_map + n;
939         } else {
940                 /*
941                  * There isn't room for another entry, steal the reserved
942                  * entry as it's not useful for anything else any longer.
943                  */
944                 map->size = l;
945         }
946         map->type = type;
947         map->region_size = granule;
948         map->attr = core_mmu_type_to_attr(type);
949         map->pa = p;
950
951         set_region(&tbl_info, map);
952         return true;
953 }
954
955 static bool arm_va2pa_helper(void *va, paddr_t *pa)
956 {
957         uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);
958         paddr_t par;
959         paddr_t par_pa_mask;
960         bool ret = false;
961
962 #ifdef ARM32
963         write_ats1cpr((vaddr_t)va);
964         isb();
965 #ifdef CFG_WITH_LPAE
966         par = read_par64();
967         par_pa_mask = PAR64_PA_MASK;
968 #else
969         par = read_par32();
970         par_pa_mask = PAR32_PA_MASK;
971 #endif
972 #endif /*ARM32*/
973
974 #ifdef ARM64
975         write_at_s1e1r((vaddr_t)va);
976         isb();
977         par = read_par_el1();
978         par_pa_mask = PAR_PA_MASK;
979 #endif
980         if (par & PAR_F)
981                 goto out;
982         *pa = (par & (par_pa_mask << PAR_PA_SHIFT)) |
983                 ((vaddr_t)va & ((1 << PAR_PA_SHIFT) - 1));
984
985         ret = true;
986 out:
987         thread_unmask_exceptions(exceptions);
988         return ret;
989 }
990
991 #ifdef CFG_WITH_PAGER
992 static vaddr_t get_linear_map_end(void)
993 {
994         /* this is synced with the generic linker file kern.ld.S */
995         return (vaddr_t)__heap2_end;
996 }
997 #endif
998
999 #if defined(CFG_TEE_CORE_DEBUG)
1000 static void check_pa_matches_va(void *va, paddr_t pa)
1001 {
1002         TEE_Result res;
1003         vaddr_t v = (vaddr_t)va;
1004         paddr_t p = 0;
1005
1006         if (core_mmu_user_va_range_is_defined()) {
1007                 vaddr_t user_va_base;
1008                 size_t user_va_size;
1009
1010                 core_mmu_get_user_va_range(&user_va_base, &user_va_size);
1011                 if (v >= user_va_base &&
1012                     v <= (user_va_base - 1 + user_va_size)) {
1013                         if (!core_mmu_user_mapping_is_active()) {
1014                                 if (pa)
1015                                         panic("issue in linear address space");
1016                                 return;
1017                         }
1018
1019                         res = tee_mmu_user_va2pa_helper(
1020                                 to_user_ta_ctx(tee_mmu_get_ctx()), va, &p);
1021                         if (res == TEE_SUCCESS && pa != p)
1022                                 panic("bad pa");
1023                         if (res != TEE_SUCCESS && pa)
1024                                 panic("false pa");
1025                         return;
1026                 }
1027         }
1028 #ifdef CFG_WITH_PAGER
1029         if (v >= CFG_TEE_LOAD_ADDR && v < get_linear_map_end()) {
1030                 if (v != pa)
1031                         panic("issue in linear address space");
1032                 return;
1033         }
1034         if (v >= (CFG_TEE_LOAD_ADDR & ~CORE_MMU_PGDIR_MASK) &&
1035             v <= (CFG_TEE_LOAD_ADDR | CORE_MMU_PGDIR_MASK)) {
1036                 struct core_mmu_table_info *ti = &tee_pager_tbl_info;
1037                 uint32_t a;
1038
1039                 /*
1040                  * Lookups in the page table managed by the pager is
1041                  * dangerous for addresses in the paged area as those pages
1042                  * changes all the time. But some ranges are safe,
1043                  * rw-locked areas when the page is populated for instance.
1044                  */
1045                 core_mmu_get_entry(ti, core_mmu_va2idx(ti, v), &p, &a);
1046                 if (a & TEE_MATTR_VALID_BLOCK) {
1047                         paddr_t mask = ((1 << ti->shift) - 1);
1048
1049                         p |= v & mask;
1050                         if (pa != p)
1051                                 panic();
1052                 } else
1053                         if (pa)
1054                                 panic();
1055                 return;
1056         }
1057 #endif
1058         if (!core_va2pa_helper(va, &p)) {
1059                 if (pa != p)
1060                         panic();
1061         } else {
1062                 if (pa)
1063                         panic();
1064         }
1065 }
1066 #else
1067 static void check_pa_matches_va(void *va __unused, paddr_t pa __unused)
1068 {
1069 }
1070 #endif
1071
1072 paddr_t virt_to_phys(void *va)
1073 {
1074         paddr_t pa;
1075
1076         if (!arm_va2pa_helper(va, &pa))
1077                 pa = 0;
1078         check_pa_matches_va(va, pa);
1079         return pa;
1080 }
1081
1082 #if defined(CFG_TEE_CORE_DEBUG)
1083 static void check_va_matches_pa(paddr_t pa, void *va)
1084 {
1085         if (va && virt_to_phys(va) != pa)
1086                 panic();
1087 }
1088 #else
1089 static void check_va_matches_pa(paddr_t pa __unused, void *va __unused)
1090 {
1091 }
1092 #endif
1093
1094 static void *phys_to_virt_ta_vaspace(paddr_t pa)
1095 {
1096         TEE_Result res;
1097         void *va = NULL;
1098
1099         if (!core_mmu_user_mapping_is_active())
1100                 return NULL;
1101
1102         res = tee_mmu_user_pa2va_helper(to_user_ta_ctx(tee_mmu_get_ctx()),
1103                                         pa, &va);
1104         if (res != TEE_SUCCESS)
1105                 return NULL;
1106         return va;
1107 }
1108
1109 #ifdef CFG_WITH_PAGER
1110 static void *phys_to_virt_tee_ram(paddr_t pa)
1111 {
1112         struct core_mmu_table_info *ti = &tee_pager_tbl_info;
1113         unsigned idx;
1114         unsigned end_idx;
1115         uint32_t a;
1116         paddr_t p;
1117
1118         if (pa >= CFG_TEE_LOAD_ADDR && pa < get_linear_map_end())
1119                 return (void *)(vaddr_t)pa;
1120
1121         end_idx = core_mmu_va2idx(ti, CFG_TEE_RAM_START +
1122                                       CFG_TEE_RAM_VA_SIZE);
1123         /* Most addresses are mapped lineary, try that first if possible. */
1124         idx = core_mmu_va2idx(ti, pa);
1125         if (idx >= core_mmu_va2idx(ti, CFG_TEE_RAM_START) &&
1126             idx < end_idx) {
1127                 core_mmu_get_entry(ti, idx, &p, &a);
1128                 if ((a & TEE_MATTR_VALID_BLOCK) && p == pa)
1129                         return (void *)core_mmu_idx2va(ti, idx);
1130         }
1131
1132         for (idx = core_mmu_va2idx(ti, CFG_TEE_RAM_START);
1133              idx < end_idx; idx++) {
1134                 core_mmu_get_entry(ti, idx, &p, &a);
1135                 if ((a & TEE_MATTR_VALID_BLOCK) && p == pa)
1136                         return (void *)core_mmu_idx2va(ti, idx);
1137         }
1138
1139         return NULL;
1140 }
1141 #else
1142 static void *phys_to_virt_tee_ram(paddr_t pa)
1143 {
1144         return map_pa2va(find_map_by_type_and_pa(MEM_AREA_TEE_RAM, pa), pa);
1145 }
1146 #endif
1147
1148 void *phys_to_virt(paddr_t pa, enum teecore_memtypes m)
1149 {
1150         void *va;
1151
1152         switch (m) {
1153         case MEM_AREA_TA_VASPACE:
1154                 va = phys_to_virt_ta_vaspace(pa);
1155                 break;
1156         case MEM_AREA_TEE_RAM:
1157                 va = phys_to_virt_tee_ram(pa);
1158                 break;
1159         default:
1160                 va = map_pa2va(find_map_by_type_and_pa(m, pa), pa);
1161         }
1162         check_va_matches_pa(pa, va);
1163         return va;
1164 }
1165
1166 bool cpu_mmu_enabled(void)
1167 {
1168         uint32_t sctlr;
1169
1170 #ifdef ARM32
1171         sctlr =  read_sctlr();
1172 #else
1173         sctlr =  read_sctlr_el1();
1174 #endif
1175
1176         return sctlr & SCTLR_M ? true : false;
1177 }