1*3de7021fSJerome Forissier /* 2*3de7021fSJerome Forissier * Copyright (c) 2016, Linaro Limited 3*3de7021fSJerome Forissier * All rights reserved. 4*3de7021fSJerome Forissier * 5*3de7021fSJerome Forissier * Redistribution and use in source and binary forms, with or without 6*3de7021fSJerome Forissier * modification, are permitted provided that the following conditions are met: 7*3de7021fSJerome Forissier * 8*3de7021fSJerome Forissier * 1. Redistributions of source code must retain the above copyright notice, 9*3de7021fSJerome Forissier * this list of conditions and the following disclaimer. 10*3de7021fSJerome Forissier * 11*3de7021fSJerome Forissier * 2. Redistributions in binary form must reproduce the above copyright notice, 12*3de7021fSJerome Forissier * this list of conditions and the following disclaimer in the documentation 13*3de7021fSJerome Forissier * and/or other materials provided with the distribution. 14*3de7021fSJerome Forissier * 15*3de7021fSJerome Forissier * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16*3de7021fSJerome Forissier * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*3de7021fSJerome Forissier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*3de7021fSJerome Forissier * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19*3de7021fSJerome Forissier * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*3de7021fSJerome Forissier * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*3de7021fSJerome Forissier * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*3de7021fSJerome Forissier * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*3de7021fSJerome Forissier * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*3de7021fSJerome Forissier * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*3de7021fSJerome Forissier * POSSIBILITY OF SUCH DAMAGE. 26*3de7021fSJerome Forissier */ 27*3de7021fSJerome Forissier 28*3de7021fSJerome Forissier /* Driver for the internal Random Number Generator of HiSilicon P660/Hi16xx */ 29*3de7021fSJerome Forissier 30*3de7021fSJerome Forissier #include <initcall.h> 31*3de7021fSJerome Forissier #include <io.h> 32*3de7021fSJerome Forissier #include <kernel/mutex.h> 33*3de7021fSJerome Forissier #include <kernel/tee_time.h> 34*3de7021fSJerome Forissier #include <mm/core_memprot.h> 35*3de7021fSJerome Forissier #include <mm/core_mmu.h> 36*3de7021fSJerome Forissier #include <platform_config.h> 37*3de7021fSJerome Forissier #include <rng_support.h> 38*3de7021fSJerome Forissier #include <trace.h> 39*3de7021fSJerome Forissier #include <types_ext.h> 40*3de7021fSJerome Forissier #include <util.h> 41*3de7021fSJerome Forissier 42*3de7021fSJerome Forissier /* ALG sub-controller registers */ 43*3de7021fSJerome Forissier 44*3de7021fSJerome Forissier #define ALG_SC_RNG_RESET_DREQ 0xAB4 /* RNG reset cancel */ 45*3de7021fSJerome Forissier # define ALG_SC_SRST_DREQ_RNG BIT(0) 46*3de7021fSJerome Forissier 47*3de7021fSJerome Forissier /* RNG registers */ 48*3de7021fSJerome Forissier 49*3de7021fSJerome Forissier #define RNG_SEED 0x0 /* Initial seed */ 50*3de7021fSJerome Forissier #define RNG_CTRL 0x4 /* Control register */ 51*3de7021fSJerome Forissier # define RNG_SEED_SEL BIT(2) /* Re-seed source: 1: ring osc., 0: LFSR */ 52*3de7021fSJerome Forissier # define RNG_RING_EN BIT(1) /* Enable ring oscillator */ 53*3de7021fSJerome Forissier # define RNG_EN BIT(0) /* Enable RNG */ 54*3de7021fSJerome Forissier #define RNG_NUM 0x10 /* Random number output */ 55*3de7021fSJerome Forissier #define RNG_PHY_SEED 0x14 /* Ring oscillator output */ 56*3de7021fSJerome Forissier 57*3de7021fSJerome Forissier register_phys_mem(MEM_AREA_IO_SEC, ALG_SC_BASE, ALG_SC_REG_SIZE); 58*3de7021fSJerome Forissier register_phys_mem(MEM_AREA_IO_SEC, RNG_BASE, RNG_REG_SIZE); 59*3de7021fSJerome Forissier 60*3de7021fSJerome Forissier static struct mutex rng_mutex = MUTEX_INITIALIZER; 61*3de7021fSJerome Forissier 62*3de7021fSJerome Forissier static TEE_Result hi16xx_rng_init(void) 63*3de7021fSJerome Forissier { 64*3de7021fSJerome Forissier vaddr_t alg = (vaddr_t)phys_to_virt(ALG_SC_BASE, MEM_AREA_IO_SEC); 65*3de7021fSJerome Forissier vaddr_t rng = (vaddr_t)phys_to_virt(RNG_BASE, MEM_AREA_IO_SEC); 66*3de7021fSJerome Forissier TEE_Time time; 67*3de7021fSJerome Forissier 68*3de7021fSJerome Forissier /* ALG sub-controller must allow RNG out of reset */ 69*3de7021fSJerome Forissier write32(ALG_SC_SRST_DREQ_RNG, alg + ALG_SC_RNG_RESET_DREQ); 70*3de7021fSJerome Forissier 71*3de7021fSJerome Forissier /* Set initial seed */ 72*3de7021fSJerome Forissier tee_time_get_sys_time(&time); 73*3de7021fSJerome Forissier write32(time.seconds * 1000 + time.millis, rng + RNG_SEED); 74*3de7021fSJerome Forissier 75*3de7021fSJerome Forissier /* 76*3de7021fSJerome Forissier * Enable RNG and configure it to re-seed automatically from the 77*3de7021fSJerome Forissier * internal ring oscillator 78*3de7021fSJerome Forissier */ 79*3de7021fSJerome Forissier write32(RNG_EN | RNG_RING_EN | RNG_SEED_SEL, rng + RNG_CTRL); 80*3de7021fSJerome Forissier 81*3de7021fSJerome Forissier IMSG("Hi16xx RNG initialized"); 82*3de7021fSJerome Forissier return TEE_SUCCESS; 83*3de7021fSJerome Forissier } 84*3de7021fSJerome Forissier 85*3de7021fSJerome Forissier uint8_t hw_get_random_byte(void) 86*3de7021fSJerome Forissier { 87*3de7021fSJerome Forissier static vaddr_t r; 88*3de7021fSJerome Forissier static int pos; 89*3de7021fSJerome Forissier static union { 90*3de7021fSJerome Forissier uint32_t val; 91*3de7021fSJerome Forissier uint8_t byte[4]; 92*3de7021fSJerome Forissier } random; 93*3de7021fSJerome Forissier uint8_t ret; 94*3de7021fSJerome Forissier 95*3de7021fSJerome Forissier mutex_lock(&rng_mutex); 96*3de7021fSJerome Forissier 97*3de7021fSJerome Forissier if (!r) 98*3de7021fSJerome Forissier r = (vaddr_t)phys_to_virt(RNG_BASE, MEM_AREA_IO_SEC) + RNG_NUM; 99*3de7021fSJerome Forissier 100*3de7021fSJerome Forissier if (!pos) 101*3de7021fSJerome Forissier random.val = read32(r); 102*3de7021fSJerome Forissier 103*3de7021fSJerome Forissier ret = random.byte[pos++]; 104*3de7021fSJerome Forissier 105*3de7021fSJerome Forissier if (pos == 4) 106*3de7021fSJerome Forissier pos = 0; 107*3de7021fSJerome Forissier 108*3de7021fSJerome Forissier mutex_unlock(&rng_mutex); 109*3de7021fSJerome Forissier 110*3de7021fSJerome Forissier return ret; 111*3de7021fSJerome Forissier } 112*3de7021fSJerome Forissier 113*3de7021fSJerome Forissier driver_init(hi16xx_rng_init); 114