1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 */ 5 6 #include <initcall.h> 7 #include <io.h> 8 #include <mm/core_memprot.h> 9 #include <platform_config.h> 10 #include <rng_support.h> 11 12 #define SEC_PRNG_REG_SIZE 0x1000 13 14 #define SEC_PRNG_DATA_OUT 0x0 15 #define SEC_PRNG_STATUS 0x4 16 #define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1 17 18 static struct { 19 paddr_t pa; 20 vaddr_t va; 21 } prng = { 22 .pa = SEC_PRNG_REG_BASE, 23 }; 24 hw_get_random_bytes(void * buf,size_t len)25TEE_Result hw_get_random_bytes(void *buf, size_t len) 26 { 27 uint8_t *out = buf; 28 uint32_t val; 29 30 if (!prng.va) 31 return TEE_ERROR_NOT_SUPPORTED; 32 33 if (!out || !len) 34 return TEE_ERROR_BAD_PARAMETERS; 35 36 while (len) { 37 if (!(io_read32(prng.va + SEC_PRNG_STATUS) & 38 SEC_PRNG_STATUS_DATA_AVAIL_BMSK)) 39 continue; 40 41 while ((val = io_read32(prng.va + SEC_PRNG_DATA_OUT)) == 0) 42 ; 43 44 for (size_t i = 0; i < sizeof(val) && len; i++) { 45 *out++ = (uint8_t)(val >> (i * 8)); 46 len--; 47 } 48 } 49 50 return TEE_SUCCESS; 51 } 52 qcom_prng_init(void)53static TEE_Result qcom_prng_init(void) 54 { 55 if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, prng.pa, SEC_PRNG_REG_SIZE)) 56 return TEE_ERROR_GENERIC; 57 58 prng.va = (vaddr_t)phys_to_virt_io(prng.pa, SEC_PRNG_REG_SIZE); 59 if (!prng.va) 60 return TEE_ERROR_ACCESS_DENIED; 61 62 return TEE_SUCCESS; 63 } 64 65 early_init(qcom_prng_init); 66