1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 */ 5 #include <kernel/cache_helpers.h> 6 #include <kernel/tee_common_otp.h> 7 #include <kernel/tee_common.h> 8 #include <kernel/tee_misc.h> 9 #include <malloc.h> 10 #include <mm/core_memprot.h> 11 #include <trace.h> 12 13 static uint8_t tee_b2hs_add_base(uint8_t in) 14 { 15 if (in > 9) 16 return in + 55; 17 else 18 return in + 48; 19 } 20 21 static int tee_hs2b_rem_base(uint8_t in, uint8_t *out) 22 { 23 if (in < 48 || in > 70 || (in > 57 && in < 65)) 24 return -1; 25 26 if (in < 58) 27 *out = in - 48; 28 else 29 *out = in - 55; 30 31 return 0; 32 } 33 34 uint32_t tee_b2hs(uint8_t *b, uint8_t *hs, uint32_t blen, uint32_t hslen) 35 { 36 uint32_t i = 0; 37 38 if (blen * 2 + 1 > hslen) 39 return 0; 40 41 for (; i < blen; i++) { 42 hs[i * 2 + 1] = tee_b2hs_add_base(b[i] & 0xf); 43 hs[i * 2] = tee_b2hs_add_base(b[i] >> 4); 44 } 45 hs[blen * 2] = 0; 46 47 return blen * 2; 48 } 49 50 uint32_t tee_hs2b(uint8_t *hs, uint8_t *b, uint32_t hslen, uint32_t blen) 51 { 52 uint32_t i = 0; 53 uint32_t len = TEE_HS2B_BBUF_SIZE(hslen); 54 uint8_t hi; 55 uint8_t lo; 56 57 if (len > blen) 58 return 0; 59 60 for (; i < len; i++) { 61 if (tee_hs2b_rem_base(hs[i * 2], &hi)) 62 return 0; 63 if (tee_hs2b_rem_base(hs[i * 2 + 1], &lo)) 64 return 0; 65 b[i] = (hi << 4) + lo; 66 } 67 68 return len; 69 } 70 71 static bool is_valid_conf_and_notnull_size(paddr_t b, paddr_size_t bl, 72 paddr_t a, paddr_size_t al) 73 { 74 /* invalid config return false */ 75 if ((b - 1 + bl < b) || (a - 1 + al < a)) 76 return false; 77 /* null sized areas are never inside / outside / overlap */ 78 if (!bl || !al) 79 return false; 80 return true; 81 } 82 83 /* Returns true when buffer 'b' is fully contained in area 'a' */ 84 bool core_is_buffer_inside(paddr_t b, paddr_size_t bl, 85 paddr_t a, paddr_size_t al) 86 { 87 /* invalid config or "null size" return false */ 88 if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 89 return false; 90 91 if ((b >= a) && (b - 1 + bl <= a - 1 + al)) 92 return true; 93 return false; 94 } 95 96 /* Returns true when buffer 'b' is fully outside area 'a' */ 97 bool core_is_buffer_outside(paddr_t b, paddr_size_t bl, 98 paddr_t a, paddr_size_t al) 99 { 100 /* invalid config or "null size" return false */ 101 if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 102 return false; 103 104 if ((b + bl - 1 < a) || (b > a + al - 1)) 105 return true; 106 return false; 107 } 108 109 /* Returns true when buffer 'b' intersects area 'a' */ 110 bool core_is_buffer_intersect(paddr_t b, paddr_size_t bl, 111 paddr_t a, paddr_size_t al) 112 { 113 /* invalid config or "null size" return false */ 114 if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 115 return false; 116 117 if ((b + bl - 1 < a) || (b > a + al - 1)) 118 return false; 119 return true; 120 } 121 122 void *alloc_cache_aligned(size_t size) 123 { 124 void *ptr = NULL; 125 size_t alloc_size = 0; 126 uint32_t cacheline_size = 0; 127 128 cacheline_size = cache_get_max_line_size(); 129 if (ROUNDUP_OVERFLOW(size, cacheline_size, &alloc_size)) 130 return NULL; 131 132 ptr = memalign(cacheline_size, alloc_size); 133 if (!ptr) 134 return NULL; 135 136 memset(ptr, 0, size); 137 138 return ptr; 139 } 140