1*185b4595SMarouene Boubakri /* SPDX-License-Identifier: BSD-2-Clause */ 2*185b4595SMarouene Boubakri /* 3*185b4595SMarouene Boubakri * Copyright (c) 2016-2017, Linaro Limited 4*185b4595SMarouene Boubakri */ 5*185b4595SMarouene Boubakri 6*185b4595SMarouene Boubakri #ifndef __MM_MOBJ_H 7*185b4595SMarouene Boubakri #define __MM_MOBJ_H 8*185b4595SMarouene Boubakri 9*185b4595SMarouene Boubakri #include <compiler.h> 10*185b4595SMarouene Boubakri #include <mm/core_memprot.h> 11*185b4595SMarouene Boubakri #include <mm/file.h> 12*185b4595SMarouene Boubakri #include <mm/fobj.h> 13*185b4595SMarouene Boubakri #include <string_ext.h> 14*185b4595SMarouene Boubakri #include <sys/queue.h> 15*185b4595SMarouene Boubakri #include <tee_api_types.h> 16*185b4595SMarouene Boubakri #include <types_ext.h> 17*185b4595SMarouene Boubakri 18*185b4595SMarouene Boubakri struct mobj { 19*185b4595SMarouene Boubakri const struct mobj_ops *ops; 20*185b4595SMarouene Boubakri size_t size; 21*185b4595SMarouene Boubakri size_t phys_granule; 22*185b4595SMarouene Boubakri struct refcount refc; 23*185b4595SMarouene Boubakri }; 24*185b4595SMarouene Boubakri 25*185b4595SMarouene Boubakri struct mobj_ops { 26*185b4595SMarouene Boubakri void *(*get_va)(struct mobj *mobj, size_t offs); 27*185b4595SMarouene Boubakri TEE_Result (*get_pa)(struct mobj *mobj, size_t offs, size_t granule, 28*185b4595SMarouene Boubakri paddr_t *pa); 29*185b4595SMarouene Boubakri size_t (*get_phys_offs)(struct mobj *mobj, size_t granule); 30*185b4595SMarouene Boubakri TEE_Result (*get_cattr)(struct mobj *mobj, uint32_t *cattr); 31*185b4595SMarouene Boubakri bool (*matches)(struct mobj *mobj, enum buf_is_attr attr); 32*185b4595SMarouene Boubakri void (*free)(struct mobj *mobj); 33*185b4595SMarouene Boubakri uint64_t (*get_cookie)(struct mobj *mobj); 34*185b4595SMarouene Boubakri struct fobj *(*get_fobj)(struct mobj *mobj); 35*185b4595SMarouene Boubakri TEE_Result (*inc_map)(struct mobj *mobj); 36*185b4595SMarouene Boubakri TEE_Result (*dec_map)(struct mobj *mobj); 37*185b4595SMarouene Boubakri }; 38*185b4595SMarouene Boubakri 39*185b4595SMarouene Boubakri extern struct mobj mobj_virt; 40*185b4595SMarouene Boubakri extern struct mobj *mobj_sec_ddr; 41*185b4595SMarouene Boubakri extern struct mobj *mobj_tee_ram; 42*185b4595SMarouene Boubakri 43*185b4595SMarouene Boubakri static inline void *mobj_get_va(struct mobj *mobj, size_t offset) 44*185b4595SMarouene Boubakri { 45*185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_va) 46*185b4595SMarouene Boubakri return mobj->ops->get_va(mobj, offset); 47*185b4595SMarouene Boubakri return NULL; 48*185b4595SMarouene Boubakri } 49*185b4595SMarouene Boubakri 50*185b4595SMarouene Boubakri static inline TEE_Result mobj_get_pa(struct mobj *mobj, size_t offs, 51*185b4595SMarouene Boubakri size_t granule, paddr_t *pa) 52*185b4595SMarouene Boubakri { 53*185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_pa) 54*185b4595SMarouene Boubakri return mobj->ops->get_pa(mobj, offs, granule, pa); 55*185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 56*185b4595SMarouene Boubakri } 57*185b4595SMarouene Boubakri 58*185b4595SMarouene Boubakri static inline size_t mobj_get_phys_offs(struct mobj *mobj, size_t granule) 59*185b4595SMarouene Boubakri { 60*185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_phys_offs) 61*185b4595SMarouene Boubakri return mobj->ops->get_phys_offs(mobj, granule); 62*185b4595SMarouene Boubakri return 0; 63*185b4595SMarouene Boubakri } 64*185b4595SMarouene Boubakri 65*185b4595SMarouene Boubakri static inline TEE_Result mobj_get_cattr(struct mobj *mobj, uint32_t *cattr) 66*185b4595SMarouene Boubakri { 67*185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_cattr) 68*185b4595SMarouene Boubakri return mobj->ops->get_cattr(mobj, cattr); 69*185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 70*185b4595SMarouene Boubakri } 71*185b4595SMarouene Boubakri 72*185b4595SMarouene Boubakri static inline bool mobj_matches(struct mobj *mobj, enum buf_is_attr attr) 73*185b4595SMarouene Boubakri { 74*185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->matches) 75*185b4595SMarouene Boubakri return mobj->ops->matches(mobj, attr); 76*185b4595SMarouene Boubakri return false; 77*185b4595SMarouene Boubakri } 78*185b4595SMarouene Boubakri 79*185b4595SMarouene Boubakri /** 80*185b4595SMarouene Boubakri * mobj_inc_map() - increase map count 81*185b4595SMarouene Boubakri * @mobj: pointer to a MOBJ 82*185b4595SMarouene Boubakri * 83*185b4595SMarouene Boubakri * Maps the MOBJ if it isn't mapped already and increases the map count 84*185b4595SMarouene Boubakri * Each call to mobj_inc_map() is supposed to be matches by a call to 85*185b4595SMarouene Boubakri * mobj_dec_map(). 86*185b4595SMarouene Boubakri * 87*185b4595SMarouene Boubakri * Returns TEE_SUCCESS on success or an error code on failure 88*185b4595SMarouene Boubakri */ 89*185b4595SMarouene Boubakri static inline TEE_Result mobj_inc_map(struct mobj *mobj) 90*185b4595SMarouene Boubakri { 91*185b4595SMarouene Boubakri if (mobj && mobj->ops) { 92*185b4595SMarouene Boubakri if (mobj->ops->inc_map) 93*185b4595SMarouene Boubakri return mobj->ops->inc_map(mobj); 94*185b4595SMarouene Boubakri return TEE_SUCCESS; 95*185b4595SMarouene Boubakri } 96*185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 97*185b4595SMarouene Boubakri } 98*185b4595SMarouene Boubakri 99*185b4595SMarouene Boubakri /** 100*185b4595SMarouene Boubakri * mobj_dec_map() - decrease map count 101*185b4595SMarouene Boubakri * @mobj: pointer to a MOBJ 102*185b4595SMarouene Boubakri * 103*185b4595SMarouene Boubakri * Decreases the map count and also unmaps the MOBJ if the map count 104*185b4595SMarouene Boubakri * reaches 0. Each call to mobj_inc_map() is supposed to be matched by a 105*185b4595SMarouene Boubakri * call to mobj_dec_map(). 106*185b4595SMarouene Boubakri * 107*185b4595SMarouene Boubakri * Returns TEE_SUCCESS on success or an error code on failure 108*185b4595SMarouene Boubakri */ 109*185b4595SMarouene Boubakri static inline TEE_Result mobj_dec_map(struct mobj *mobj) 110*185b4595SMarouene Boubakri { 111*185b4595SMarouene Boubakri if (mobj && mobj->ops) { 112*185b4595SMarouene Boubakri if (mobj->ops->dec_map) 113*185b4595SMarouene Boubakri return mobj->ops->dec_map(mobj); 114*185b4595SMarouene Boubakri return TEE_SUCCESS; 115*185b4595SMarouene Boubakri } 116*185b4595SMarouene Boubakri return TEE_ERROR_GENERIC; 117*185b4595SMarouene Boubakri } 118*185b4595SMarouene Boubakri 119*185b4595SMarouene Boubakri /** 120*185b4595SMarouene Boubakri * mobj_get() - get a MOBJ 121*185b4595SMarouene Boubakri * @mobj: Pointer to a MOBJ or NULL 122*185b4595SMarouene Boubakri * 123*185b4595SMarouene Boubakri * Increases reference counter of the @mobj 124*185b4595SMarouene Boubakri * 125*185b4595SMarouene Boubakri * Returns @mobj with reference counter increased or NULL if @mobj was NULL 126*185b4595SMarouene Boubakri */ 127*185b4595SMarouene Boubakri static inline struct mobj *mobj_get(struct mobj *mobj) 128*185b4595SMarouene Boubakri { 129*185b4595SMarouene Boubakri if (mobj && !refcount_inc(&mobj->refc)) 130*185b4595SMarouene Boubakri panic(); 131*185b4595SMarouene Boubakri 132*185b4595SMarouene Boubakri return mobj; 133*185b4595SMarouene Boubakri } 134*185b4595SMarouene Boubakri 135*185b4595SMarouene Boubakri /** 136*185b4595SMarouene Boubakri * mobj_put() - put a MOBJ 137*185b4595SMarouene Boubakri * @mobj: Pointer to a MOBJ or NULL 138*185b4595SMarouene Boubakri * 139*185b4595SMarouene Boubakri * Decreases reference counter of the @mobj and frees it if the counter 140*185b4595SMarouene Boubakri * reaches 0. 141*185b4595SMarouene Boubakri */ 142*185b4595SMarouene Boubakri static inline void mobj_put(struct mobj *mobj) 143*185b4595SMarouene Boubakri { 144*185b4595SMarouene Boubakri if (mobj && refcount_dec(&mobj->refc)) 145*185b4595SMarouene Boubakri mobj->ops->free(mobj); 146*185b4595SMarouene Boubakri } 147*185b4595SMarouene Boubakri 148*185b4595SMarouene Boubakri /** 149*185b4595SMarouene Boubakri * mobj_put_wipe() - wipe and put a MOBJ 150*185b4595SMarouene Boubakri * @mobj: Pointer to a MOBJ or NULL 151*185b4595SMarouene Boubakri * 152*185b4595SMarouene Boubakri * Clears the memory represented by the mobj and then puts it. 153*185b4595SMarouene Boubakri */ 154*185b4595SMarouene Boubakri static inline void mobj_put_wipe(struct mobj *mobj) 155*185b4595SMarouene Boubakri { 156*185b4595SMarouene Boubakri void *buf = mobj_get_va(mobj, 0); 157*185b4595SMarouene Boubakri 158*185b4595SMarouene Boubakri if (buf) 159*185b4595SMarouene Boubakri memzero_explicit(buf, mobj->size); 160*185b4595SMarouene Boubakri mobj_put(mobj); 161*185b4595SMarouene Boubakri } 162*185b4595SMarouene Boubakri 163*185b4595SMarouene Boubakri static inline uint64_t mobj_get_cookie(struct mobj *mobj) 164*185b4595SMarouene Boubakri { 165*185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_cookie) 166*185b4595SMarouene Boubakri return mobj->ops->get_cookie(mobj); 167*185b4595SMarouene Boubakri 168*185b4595SMarouene Boubakri return 0; 169*185b4595SMarouene Boubakri } 170*185b4595SMarouene Boubakri 171*185b4595SMarouene Boubakri static inline struct fobj *mobj_get_fobj(struct mobj *mobj) 172*185b4595SMarouene Boubakri { 173*185b4595SMarouene Boubakri if (mobj && mobj->ops && mobj->ops->get_fobj) 174*185b4595SMarouene Boubakri return mobj->ops->get_fobj(mobj); 175*185b4595SMarouene Boubakri 176*185b4595SMarouene Boubakri return NULL; 177*185b4595SMarouene Boubakri } 178*185b4595SMarouene Boubakri 179*185b4595SMarouene Boubakri static inline bool mobj_is_nonsec(struct mobj *mobj) 180*185b4595SMarouene Boubakri { 181*185b4595SMarouene Boubakri return mobj_matches(mobj, CORE_MEM_NON_SEC); 182*185b4595SMarouene Boubakri } 183*185b4595SMarouene Boubakri 184*185b4595SMarouene Boubakri static inline bool mobj_is_secure(struct mobj *mobj) 185*185b4595SMarouene Boubakri { 186*185b4595SMarouene Boubakri return mobj_matches(mobj, CORE_MEM_SEC); 187*185b4595SMarouene Boubakri } 188*185b4595SMarouene Boubakri 189*185b4595SMarouene Boubakri static inline bool mobj_is_sdp_mem(struct mobj *mobj) 190*185b4595SMarouene Boubakri { 191*185b4595SMarouene Boubakri return mobj_matches(mobj, CORE_MEM_SDP_MEM); 192*185b4595SMarouene Boubakri } 193*185b4595SMarouene Boubakri 194*185b4595SMarouene Boubakri static inline size_t mobj_get_phys_granule(struct mobj *mobj) 195*185b4595SMarouene Boubakri { 196*185b4595SMarouene Boubakri if (mobj->phys_granule) 197*185b4595SMarouene Boubakri return mobj->phys_granule; 198*185b4595SMarouene Boubakri return mobj->size; 199*185b4595SMarouene Boubakri } 200*185b4595SMarouene Boubakri 201*185b4595SMarouene Boubakri struct mobj *mobj_mm_alloc(struct mobj *mobj_parent, size_t size, 202*185b4595SMarouene Boubakri tee_mm_pool_t *pool); 203*185b4595SMarouene Boubakri 204*185b4595SMarouene Boubakri struct mobj *mobj_phys_alloc(paddr_t pa, size_t size, uint32_t cattr, 205*185b4595SMarouene Boubakri enum buf_is_attr battr); 206*185b4595SMarouene Boubakri 207*185b4595SMarouene Boubakri #if defined(CFG_CORE_FFA) 208*185b4595SMarouene Boubakri struct mobj *mobj_ffa_get_by_cookie(uint64_t cookie, 209*185b4595SMarouene Boubakri unsigned int internal_offs); 210*185b4595SMarouene Boubakri 211*185b4595SMarouene Boubakri TEE_Result mobj_ffa_unregister_by_cookie(uint64_t cookie); 212*185b4595SMarouene Boubakri 213*185b4595SMarouene Boubakri /* Functions for SPMC */ 214*185b4595SMarouene Boubakri #ifdef CFG_CORE_SEL1_SPMC 215*185b4595SMarouene Boubakri struct mobj_ffa *mobj_ffa_sel1_spmc_new(unsigned int num_pages); 216*185b4595SMarouene Boubakri void mobj_ffa_sel1_spmc_delete(struct mobj_ffa *mobj); 217*185b4595SMarouene Boubakri TEE_Result mobj_ffa_sel1_spmc_reclaim(uint64_t cookie); 218*185b4595SMarouene Boubakri #endif 219*185b4595SMarouene Boubakri uint64_t mobj_ffa_get_cookie(struct mobj_ffa *mobj); 220*185b4595SMarouene Boubakri TEE_Result mobj_ffa_add_pages_at(struct mobj_ffa *mobj, unsigned int *idx, 221*185b4595SMarouene Boubakri paddr_t pa, unsigned int num_pages); 222*185b4595SMarouene Boubakri uint64_t mobj_ffa_push_to_inactive(struct mobj_ffa *mobj); 223*185b4595SMarouene Boubakri 224*185b4595SMarouene Boubakri #elif defined(CFG_CORE_DYN_SHM) 225*185b4595SMarouene Boubakri /* reg_shm represents TEE shared memory */ 226*185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_alloc(paddr_t *pages, size_t num_pages, 227*185b4595SMarouene Boubakri paddr_t page_offset, uint64_t cookie); 228*185b4595SMarouene Boubakri 229*185b4595SMarouene Boubakri /** 230*185b4595SMarouene Boubakri * mobj_reg_shm_get_by_cookie() - get a MOBJ based on cookie 231*185b4595SMarouene Boubakri * @cookie: Cookie used by normal world when suppling the shared memory 232*185b4595SMarouene Boubakri * 233*185b4595SMarouene Boubakri * Searches for a registered shared memory MOBJ and if one with a matching 234*185b4595SMarouene Boubakri * @cookie is found its reference counter is increased before returning 235*185b4595SMarouene Boubakri * the MOBJ. 236*185b4595SMarouene Boubakri * 237*185b4595SMarouene Boubakri * Returns a valid pointer on success or NULL on failure. 238*185b4595SMarouene Boubakri */ 239*185b4595SMarouene Boubakri struct mobj *mobj_reg_shm_get_by_cookie(uint64_t cookie); 240*185b4595SMarouene Boubakri 241*185b4595SMarouene Boubakri TEE_Result mobj_reg_shm_release_by_cookie(uint64_t cookie); 242*185b4595SMarouene Boubakri 243*185b4595SMarouene Boubakri /** 244*185b4595SMarouene Boubakri * mobj_reg_shm_unguard() - unguards a reg_shm 245*185b4595SMarouene Boubakri * @mobj: pointer to a registered shared memory mobj 246*185b4595SMarouene Boubakri * 247*185b4595SMarouene Boubakri * A registered shared memory mobj is normally guarded against being 248*185b4595SMarouene Boubakri * released with mobj_reg_shm_try_release_by_cookie(). After this function 249*185b4595SMarouene Boubakri * has returned the mobj can be released by a call to 250*185b4595SMarouene Boubakri * mobj_reg_shm_try_release_by_cookie() if the reference counter allows it. 251*185b4595SMarouene Boubakri */ 252*185b4595SMarouene Boubakri void mobj_reg_shm_unguard(struct mobj *mobj); 253*185b4595SMarouene Boubakri 254*185b4595SMarouene Boubakri /* 255*185b4595SMarouene Boubakri * mapped_shm represents registered shared buffer 256*185b4595SMarouene Boubakri * which is mapped into OPTEE va space 257*185b4595SMarouene Boubakri */ 258*185b4595SMarouene Boubakri struct mobj *mobj_mapped_shm_alloc(paddr_t *pages, size_t num_pages, 259*185b4595SMarouene Boubakri paddr_t page_offset, uint64_t cookie); 260*185b4595SMarouene Boubakri #endif /*CFG_CORE_DYN_SHM*/ 261*185b4595SMarouene Boubakri 262*185b4595SMarouene Boubakri #if !defined(CFG_CORE_DYN_SHM) 263*185b4595SMarouene Boubakri static inline struct mobj *mobj_mapped_shm_alloc(paddr_t *pages __unused, 264*185b4595SMarouene Boubakri size_t num_pages __unused, 265*185b4595SMarouene Boubakri paddr_t page_offset __unused, 266*185b4595SMarouene Boubakri uint64_t cookie __unused) 267*185b4595SMarouene Boubakri { 268*185b4595SMarouene Boubakri return NULL; 269*185b4595SMarouene Boubakri } 270*185b4595SMarouene Boubakri #endif 271*185b4595SMarouene Boubakri 272*185b4595SMarouene Boubakri struct mobj *mobj_shm_alloc(paddr_t pa, size_t size, uint64_t cookie); 273*185b4595SMarouene Boubakri 274*185b4595SMarouene Boubakri #ifdef CFG_PAGED_USER_TA 275*185b4595SMarouene Boubakri bool mobj_is_paged(struct mobj *mobj); 276*185b4595SMarouene Boubakri #else 277*185b4595SMarouene Boubakri static inline bool mobj_is_paged(struct mobj *mobj __unused) 278*185b4595SMarouene Boubakri { 279*185b4595SMarouene Boubakri return false; 280*185b4595SMarouene Boubakri } 281*185b4595SMarouene Boubakri #endif 282*185b4595SMarouene Boubakri 283*185b4595SMarouene Boubakri struct mobj *mobj_seccpy_shm_alloc(size_t size); 284*185b4595SMarouene Boubakri 285*185b4595SMarouene Boubakri struct mobj *mobj_with_fobj_alloc(struct fobj *fobj, struct file *file); 286*185b4595SMarouene Boubakri 287*185b4595SMarouene Boubakri #endif /*__MM_MOBJ_H*/ 288