diff --git a/drivers/rpi3/rng/rpi3_rng.c b/drivers/rpi3/rng/rpi3_rng.c new file mode 100644 index 0000000..b6bf005 --- /dev/null +++ b/drivers/rpi3/rng/rpi3_rng.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include + +/* Initial amount of values to discard */ +#define RNG_WARMUP_COUNT U(0x40000) + +static void rpi3_rng_initialize(void) +{ + uint32_t int_mask, ctrl; + + /* Return if it is already enabled */ + ctrl = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET); + if ((ctrl & RPI3_RNG_CTRL_ENABLE) != 0U) { + return; + } + + /* Mask interrupts */ + int_mask = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET); + int_mask |= RPI3_RNG_INT_MASK_DISABLE; + mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET, int_mask); + + /* Discard several values when initializing to give it time to warmup */ + mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET, RNG_WARMUP_COUNT); + + mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET, + RPI3_RNG_CTRL_ENABLE); +} + +static uint32_t rpi3_rng_get_word(void) +{ + size_t nwords; + + do { + /* Get number of available words to read */ + nwords = (mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET) + >> RPI3_RNG_STATUS_NUM_WORDS_SHIFT) + & RPI3_RNG_STATUS_NUM_WORDS_MASK; + } while (nwords == 0U); + + return mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_DATA_OFFSET); +} + +void rpi3_rng_read(void *buf, size_t len) +{ + uint32_t data; + size_t left = len; + uint32_t *dst = buf; + + assert(buf != NULL); + assert(len != 0U); + assert(check_uptr_overflow((uintptr_t) buf, (uintptr_t) len) == 0); + + rpi3_rng_initialize(); + + while (left >= sizeof(uint32_t)) { + data = rpi3_rng_get_word(); + *dst++ = data; + left -= sizeof(uint32_t); + } + + if (left > 0U) { + data = rpi3_rng_get_word(); + memcpy(dst, &data, left); + } +} diff --git a/include/drivers/rpi3/rng/rpi3_rng.h b/include/drivers/rpi3/rng/rpi3_rng.h new file mode 100644 index 0000000..ea5a677 --- /dev/null +++ b/include/drivers/rpi3/rng/rpi3_rng.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RPI3_RNG_H +#define RPI3_RNG_H + +void rpi3_rng_read(void *buf, size_t len); + +#endif diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index b0e7b70..21a880c 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -159,7 +159,7 @@ endif ifneq ($(ENABLE_STACK_PROTECTOR), 0) -PLAT_BL_COMMON_SOURCES += plat/rpi/rpi3/rpi3_rng.c \ +PLAT_BL_COMMON_SOURCES += drivers/rpi3/rng/rpi3_rng.c \ plat/rpi/rpi3/rpi3_stack_protector.c endif diff --git a/plat/rpi/rpi3/rpi3_private.h b/plat/rpi/rpi3/rpi3_private.h index 53078f8..b01c40c 100644 --- a/plat/rpi/rpi3/rpi3_private.h +++ b/plat/rpi/rpi3/rpi3_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -33,9 +33,6 @@ /* IO storage utility functions */ void plat_rpi3_io_setup(void); -/* Hardware RNG functions */ -void rpi3_rng_read(void *buf, size_t len); - /* VideoCore firmware commands */ int rpi3_vc_hardware_get_board_revision(uint32_t *revision); diff --git a/plat/rpi/rpi3/rpi3_rng.c b/plat/rpi/rpi3/rpi3_rng.c deleted file mode 100644 index b6bf005..0000000 --- a/plat/rpi/rpi3/rpi3_rng.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include - -/* Initial amount of values to discard */ -#define RNG_WARMUP_COUNT U(0x40000) - -static void rpi3_rng_initialize(void) -{ - uint32_t int_mask, ctrl; - - /* Return if it is already enabled */ - ctrl = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET); - if ((ctrl & RPI3_RNG_CTRL_ENABLE) != 0U) { - return; - } - - /* Mask interrupts */ - int_mask = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET); - int_mask |= RPI3_RNG_INT_MASK_DISABLE; - mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET, int_mask); - - /* Discard several values when initializing to give it time to warmup */ - mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET, RNG_WARMUP_COUNT); - - mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET, - RPI3_RNG_CTRL_ENABLE); -} - -static uint32_t rpi3_rng_get_word(void) -{ - size_t nwords; - - do { - /* Get number of available words to read */ - nwords = (mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET) - >> RPI3_RNG_STATUS_NUM_WORDS_SHIFT) - & RPI3_RNG_STATUS_NUM_WORDS_MASK; - } while (nwords == 0U); - - return mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_DATA_OFFSET); -} - -void rpi3_rng_read(void *buf, size_t len) -{ - uint32_t data; - size_t left = len; - uint32_t *dst = buf; - - assert(buf != NULL); - assert(len != 0U); - assert(check_uptr_overflow((uintptr_t) buf, (uintptr_t) len) == 0); - - rpi3_rng_initialize(); - - while (left >= sizeof(uint32_t)) { - data = rpi3_rng_get_word(); - *dst++ = data; - left -= sizeof(uint32_t); - } - - if (left > 0U) { - data = rpi3_rng_get_word(); - memcpy(dst, &data, left); - } -}