11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 254e04708SPascal Brand /* 354e04708SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 454e04708SPascal Brand */ 54682bf0fSVesa Jääskeläinen #include <kernel/cache_helpers.h> 654e04708SPascal Brand #include <kernel/chip_services.h> 7f6b4561aSVesa Jääskeläinen #include <kernel/tee_common_otp.h> 8f6b4561aSVesa Jääskeläinen #include <kernel/tee_common.h> 954e04708SPascal Brand #include <kernel/tee_misc.h> 104682bf0fSVesa Jääskeläinen #include <malloc.h> 1154e04708SPascal Brand #include <mm/core_memprot.h> 12f6b4561aSVesa Jääskeläinen #include <stdio.h> 134de4bebcSJens Wiklander #include <trace.h> 1454e04708SPascal Brand 1554e04708SPascal Brand static uint8_t tee_b2hs_add_base(uint8_t in) 1654e04708SPascal Brand { 1754e04708SPascal Brand if (in > 9) 1854e04708SPascal Brand return in + 55; 1954e04708SPascal Brand else 2054e04708SPascal Brand return in + 48; 2154e04708SPascal Brand } 2254e04708SPascal Brand 2354e04708SPascal Brand static int tee_hs2b_rem_base(uint8_t in, uint8_t *out) 2454e04708SPascal Brand { 2554e04708SPascal Brand if (in < 48 || in > 70 || (in > 57 && in < 65)) 2654e04708SPascal Brand return -1; 2754e04708SPascal Brand 2854e04708SPascal Brand if (in < 58) 2954e04708SPascal Brand *out = in - 48; 3054e04708SPascal Brand else 3154e04708SPascal Brand *out = in - 55; 3254e04708SPascal Brand 3354e04708SPascal Brand return 0; 3454e04708SPascal Brand } 3554e04708SPascal Brand 3654e04708SPascal Brand uint32_t tee_b2hs(uint8_t *b, uint8_t *hs, uint32_t blen, uint32_t hslen) 3754e04708SPascal Brand { 3854e04708SPascal Brand uint32_t i = 0; 3954e04708SPascal Brand 4054e04708SPascal Brand if (blen * 2 + 1 > hslen) 4154e04708SPascal Brand return 0; 4254e04708SPascal Brand 4354e04708SPascal Brand for (; i < blen; i++) { 4454e04708SPascal Brand hs[i * 2 + 1] = tee_b2hs_add_base(b[i] & 0xf); 4554e04708SPascal Brand hs[i * 2] = tee_b2hs_add_base(b[i] >> 4); 4654e04708SPascal Brand } 4754e04708SPascal Brand hs[blen * 2] = 0; 4854e04708SPascal Brand 4954e04708SPascal Brand return blen * 2; 5054e04708SPascal Brand } 5154e04708SPascal Brand 5254e04708SPascal Brand uint32_t tee_hs2b(uint8_t *hs, uint8_t *b, uint32_t hslen, uint32_t blen) 5354e04708SPascal Brand { 5454e04708SPascal Brand uint32_t i = 0; 5554e04708SPascal Brand uint32_t len = TEE_HS2B_BBUF_SIZE(hslen); 5654e04708SPascal Brand uint8_t hi; 5754e04708SPascal Brand uint8_t lo; 5854e04708SPascal Brand 5954e04708SPascal Brand if (len > blen) 6054e04708SPascal Brand return 0; 6154e04708SPascal Brand 6254e04708SPascal Brand for (; i < len; i++) { 6354e04708SPascal Brand if (tee_hs2b_rem_base(hs[i * 2], &hi)) 6454e04708SPascal Brand return 0; 6554e04708SPascal Brand if (tee_hs2b_rem_base(hs[i * 2 + 1], &lo)) 6654e04708SPascal Brand return 0; 6754e04708SPascal Brand b[i] = (hi << 4) + lo; 6854e04708SPascal Brand } 6954e04708SPascal Brand 7054e04708SPascal Brand return len; 7154e04708SPascal Brand } 72106d8aa6SPascal Brand 73c3682b1cSJens Wiklander static bool is_valid_conf_and_notnull_size(paddr_t b, paddr_size_t bl, 74c3682b1cSJens Wiklander paddr_t a, paddr_size_t al) 75106d8aa6SPascal Brand { 76106d8aa6SPascal Brand /* invalid config return false */ 77d87d5edeSPeng Fan if ((b - 1 + bl < b) || (a - 1 + al < a)) 78106d8aa6SPascal Brand return false; 79106d8aa6SPascal Brand /* null sized areas are never inside / outside / overlap */ 80106d8aa6SPascal Brand if (!bl || !al) 81106d8aa6SPascal Brand return false; 82106d8aa6SPascal Brand return true; 83106d8aa6SPascal Brand } 84106d8aa6SPascal Brand 85106d8aa6SPascal Brand /* Returns true when buffer 'b' is fully contained in area 'a' */ 86c3682b1cSJens Wiklander bool core_is_buffer_inside(paddr_t b, paddr_size_t bl, 87c3682b1cSJens Wiklander paddr_t a, paddr_size_t al) 88106d8aa6SPascal Brand { 89106d8aa6SPascal Brand /* invalid config or "null size" return false */ 90106d8aa6SPascal Brand if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 91106d8aa6SPascal Brand return false; 92106d8aa6SPascal Brand 93d87d5edeSPeng Fan if ((b >= a) && (b - 1 + bl <= a - 1 + al)) 94106d8aa6SPascal Brand return true; 95106d8aa6SPascal Brand return false; 96106d8aa6SPascal Brand } 97106d8aa6SPascal Brand 98*33e931b1SMark-PK Tsai /* Returns true when buffer 'b' is fully outside area 'a' */ 99c3682b1cSJens Wiklander bool core_is_buffer_outside(paddr_t b, paddr_size_t bl, 100c3682b1cSJens Wiklander paddr_t a, paddr_size_t al) 101106d8aa6SPascal Brand { 102106d8aa6SPascal Brand /* invalid config or "null size" return false */ 103106d8aa6SPascal Brand if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 104106d8aa6SPascal Brand return false; 105106d8aa6SPascal Brand 106385000b0SEtienne Carriere if ((b + bl - 1 < a) || (b > a + al - 1)) 107106d8aa6SPascal Brand return true; 108106d8aa6SPascal Brand return false; 109106d8aa6SPascal Brand } 110106d8aa6SPascal Brand 111106d8aa6SPascal Brand /* Returns true when buffer 'b' intersects area 'a' */ 112c3682b1cSJens Wiklander bool core_is_buffer_intersect(paddr_t b, paddr_size_t bl, 113c3682b1cSJens Wiklander paddr_t a, paddr_size_t al) 114106d8aa6SPascal Brand { 115106d8aa6SPascal Brand /* invalid config or "null size" return false */ 116106d8aa6SPascal Brand if (!is_valid_conf_and_notnull_size(b, bl, a, al)) 117106d8aa6SPascal Brand return false; 118106d8aa6SPascal Brand 119385000b0SEtienne Carriere if ((b + bl - 1 < a) || (b > a + al - 1)) 120106d8aa6SPascal Brand return false; 121106d8aa6SPascal Brand return true; 122106d8aa6SPascal Brand } 1234682bf0fSVesa Jääskeläinen 1244682bf0fSVesa Jääskeläinen void *alloc_cache_aligned(size_t size) 1254682bf0fSVesa Jääskeläinen { 1264682bf0fSVesa Jääskeläinen void *ptr = NULL; 1274682bf0fSVesa Jääskeläinen size_t alloc_size = 0; 1284682bf0fSVesa Jääskeläinen uint32_t cacheline_size = 0; 1294682bf0fSVesa Jääskeläinen 1304682bf0fSVesa Jääskeläinen cacheline_size = cache_get_max_line_size(); 1314682bf0fSVesa Jääskeläinen if (ROUNDUP_OVERFLOW(size, cacheline_size, &alloc_size)) 1324682bf0fSVesa Jääskeläinen return NULL; 1334682bf0fSVesa Jääskeläinen 1344682bf0fSVesa Jääskeläinen ptr = memalign(cacheline_size, alloc_size); 1354682bf0fSVesa Jääskeläinen if (!ptr) 1364682bf0fSVesa Jääskeläinen return NULL; 1374682bf0fSVesa Jääskeläinen 1384682bf0fSVesa Jääskeläinen memset(ptr, 0, size); 1394682bf0fSVesa Jääskeläinen 1404682bf0fSVesa Jääskeläinen return ptr; 1414682bf0fSVesa Jääskeläinen } 142