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