1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2016, Linaro Limited 4 */ 5 #ifndef MM_PGT_CACHE_H 6 #define MM_PGT_CACHE_H 7 8 #ifdef CFG_WITH_LPAE 9 #define PGT_SIZE (4 * 1024) 10 #define PGT_NUM_PGT_PER_PAGE 1 11 #else 12 #define PGT_SIZE (1 * 1024) 13 #define PGT_NUM_PGT_PER_PAGE 4 14 #endif 15 16 #include <assert.h> 17 #include <kernel/tee_ta_manager.h> 18 #include <sys/queue.h> 19 #include <types_ext.h> 20 #include <util.h> 21 22 struct ts_ctx; 23 24 struct pgt { 25 void *tbl; 26 vaddr_t vabase; 27 #if defined(CFG_PAGED_USER_TA) 28 struct ts_ctx *ctx; 29 size_t num_used_entries; 30 #endif 31 #if defined(CFG_WITH_PAGER) 32 #if !defined(CFG_WITH_LPAE) 33 struct pgt_parent *parent; 34 #endif 35 #endif 36 SLIST_ENTRY(pgt) link; 37 }; 38 39 /* 40 * A proper value for PGT_CACHE_SIZE depends on many factors: CFG_WITH_LPAE, 41 * CFG_TA_ASLR, size of TA, size of memrefs passed to TA, CFG_ULIBS_SHARED and 42 * possibly others. The value is based on the number of threads as an indicator 43 * on how large the system might be. 44 */ 45 #if CFG_NUM_THREADS < 2 46 #define PGT_CACHE_SIZE 4 47 #elif (CFG_NUM_THREADS == 2 && !defined(CFG_WITH_LPAE)) 48 #define PGT_CACHE_SIZE 8 49 #else 50 #define PGT_CACHE_SIZE ROUNDUP(CFG_NUM_THREADS * 2, PGT_NUM_PGT_PER_PAGE) 51 #endif 52 53 SLIST_HEAD(pgt_cache, pgt); 54 55 static inline bool pgt_check_avail(size_t num_tbls) 56 { 57 return num_tbls <= PGT_CACHE_SIZE; 58 } 59 60 void pgt_alloc(struct pgt_cache *pgt_cache, struct ts_ctx *owning_ctx, 61 vaddr_t begin, vaddr_t last); 62 void pgt_free(struct pgt_cache *pgt_cache, bool save_ctx); 63 64 void pgt_clear_ctx_range(struct pgt_cache *pgt_cache, struct ts_ctx *ctx, 65 vaddr_t begin, vaddr_t end); 66 #ifdef CFG_PAGED_USER_TA 67 void pgt_flush_ctx_range(struct pgt_cache *pgt_cache, struct ts_ctx *ctx, 68 vaddr_t begin, vaddr_t last); 69 #else 70 static inline void pgt_flush_ctx_range(struct pgt_cache *pgt_cache __unused, 71 struct ts_ctx *ctx __unused, 72 vaddr_t begin __unused, 73 vaddr_t last __unused) 74 { 75 } 76 #endif 77 78 void pgt_init(void); 79 80 #if defined(CFG_PAGED_USER_TA) 81 void pgt_flush_ctx(struct ts_ctx *ctx); 82 83 static inline void pgt_inc_used_entries(struct pgt *pgt) 84 { 85 pgt->num_used_entries++; 86 assert(pgt->num_used_entries); 87 } 88 89 static inline void pgt_dec_used_entries(struct pgt *pgt) 90 { 91 assert(pgt->num_used_entries); 92 pgt->num_used_entries--; 93 } 94 95 static inline void pgt_set_used_entries(struct pgt *pgt, size_t val) 96 { 97 pgt->num_used_entries = val; 98 } 99 100 #else 101 static inline void pgt_flush_ctx(struct ts_ctx *ctx __unused) 102 { 103 } 104 105 static inline void pgt_inc_used_entries(struct pgt *pgt __unused) 106 { 107 } 108 109 static inline void pgt_dec_used_entries(struct pgt *pgt __unused) 110 { 111 } 112 113 static inline void pgt_set_used_entries(struct pgt *pgt __unused, 114 size_t val __unused) 115 { 116 } 117 118 #endif 119 120 #endif /*MM_PGT_CACHE_H*/ 121