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