Skip to content

Commit

Permalink
plat-rockchip: rk3588: add TRNG support
Browse files Browse the repository at this point in the history
Add TRNG support for Rockchip rk3588

Signed-off-by: Ed Tubbs <ectubbs@gmail.com>
Acked-by: Etienne Carriere <etienne.carriere@foss.st.com>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
edtubbs authored and jforissier committed Jan 14, 2025
1 parent 703ebb7 commit b8a9277
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 6 deletions.
3 changes: 3 additions & 0 deletions core/arch/arm/plat-rockchip/platform_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@
#define FIREWALL_DSU_BASE 0xfe010000
#define FIREWALL_DSU_SIZE SIZE_K(32)

#define TRNG_S_BASE 0xfe398000
#define TRNG_S_SIZE SIZE_K(32)

#else
#error "Unknown platform flavor"
#endif
Expand Down
109 changes: 103 additions & 6 deletions core/arch/arm/plat-rockchip/platform_rk3588.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,50 @@
#include <common.h>
#include <io.h>
#include <kernel/panic.h>
#include <kernel/mutex.h>
#include <mm/core_memprot.h>
#include <platform.h>
#include <platform_config.h>
#include <rng_support.h>
#include <string.h>

#define FIREWALL_DDR_RGN(i) ((i) * 0x4)
#define FIREWALL_DDR_CON 0xf0
#define FIREWALL_DSU_RGN(i) ((i) * 0x4)
#define FIREWALL_DSU_CON(i) (0xf0 + ((i) * 0x4))
#define FIREWALL_DDR_RGN(i) ((i) * 0x4)
#define FIREWALL_DDR_CON 0xf0
#define FIREWALL_DSU_RGN(i) ((i) * 0x4)
#define FIREWALL_DSU_CON(i) (0xf0 + ((i) * 0x4))

#define RG_MAP_SECURE(top, base) \
#define RG_MAP_SECURE(top, base) \
(((((top) - 1) & 0x7fff) << 16) | ((base) & 0x7fff))

#define DDR_CHN_CNT 4
#define DDR_CHN_CNT 4

#define TRNG_S_CTRL 0x0000
#define TRNG_S_STAT 0x0004
#define TRNG_S_MODE 0x0008
#define TRNG_S_IE 0x0010
#define TRNG_S_ISTAT 0x0014
#define TRNG_S_RAND 0x0020
#define TRNG_S_AUTO_RQSTS 0x0060

#define CMD_NOP 0
#define CMD_RAND 1
#define CMD_SEED 2

#define LEN_128BIT 0
#define LEN_256BIT 3

#define TRNG_S_SEEDED_BIT BIT32(9)
#define TRNG_S_SEED_DONE_BIT BIT32(1)
#define TRNG_S_RAND_RDY_BIT BIT32(0)

#define TRNG_POLL_PERIOD_US 0
#define TRNG_POLL_TIMEOUT_US 1000

register_phys_mem_pgdir(MEM_AREA_IO_SEC, FIREWALL_DDR_BASE, FIREWALL_DDR_SIZE);
register_phys_mem_pgdir(MEM_AREA_IO_SEC, FIREWALL_DSU_BASE, FIREWALL_DSU_SIZE);
register_phys_mem_pgdir(MEM_AREA_IO_SEC, TRNG_S_BASE, TRNG_S_SIZE);

static struct mutex trng_mutex = MUTEX_INITIALIZER;

int platform_secure_ddr_region(int rgn, paddr_t st, size_t sz)
{
Expand Down Expand Up @@ -63,3 +91,72 @@ int platform_secure_ddr_region(int rgn, paddr_t st, size_t sz)

return 0;
}

TEE_Result hw_get_random_bytes(void *buf, size_t blen)
{
vaddr_t trng_s_base = (vaddr_t)phys_to_virt_io(TRNG_S_BASE,
TRNG_S_SIZE);
size_t remaining = blen;
size_t copy_len = 0;
uint32_t val = 0;
uint32_t rnd = 0;

mutex_lock(&trng_mutex);

if (!trng_s_base)
panic("TRNG_S base not mapped");

/* Ensure TRNG is seeded and ready */
val = io_read32(trng_s_base + TRNG_S_STAT);
if (!(val & TRNG_S_SEEDED_BIT)) {
/* TRNG not seeded, issue SEED command */
io_write32(trng_s_base + TRNG_S_CTRL, CMD_SEED);

/* Wait for SEED_DONE flag with timeout */
if (IO_READ32_POLL_TIMEOUT(trng_s_base + TRNG_S_ISTAT, val,
val & TRNG_S_SEED_DONE_BIT,
TRNG_POLL_PERIOD_US,
TRNG_POLL_TIMEOUT_US)) {
mutex_unlock(&trng_mutex);
return TEE_ERROR_BUSY;
}

/* SEED_DONE flag set, clear SEED_DONE */
io_write32(trng_s_base + TRNG_S_ISTAT, TRNG_S_SEED_DONE_BIT);
}

/* Set RNG length to 256 bits */
io_write32(trng_s_base + TRNG_S_MODE, LEN_256BIT);

while (remaining > 0) {
/* Set RAND command to generate random numbers */
io_write32(trng_s_base + TRNG_S_CTRL, CMD_RAND);

/* Wait for RAND_RDY flag with timeout */
if (IO_READ32_POLL_TIMEOUT(trng_s_base + TRNG_S_ISTAT, val,
val & TRNG_S_RAND_RDY_BIT,
TRNG_POLL_PERIOD_US,
TRNG_POLL_TIMEOUT_US)) {
mutex_unlock(&trng_mutex);
return TEE_ERROR_BUSY;
}

/* Read random data from RAND register */
rnd = io_read32(trng_s_base + TRNG_S_RAND);

/* Copy as many bytes as required */
copy_len = MIN(remaining, sizeof(uint32_t));
memcpy((uint8_t *)buf + (blen - remaining), &rnd, copy_len);
remaining -= copy_len;

/* Clear RAND_RDY flag */
io_write32(trng_s_base + TRNG_S_ISTAT, TRNG_S_RAND_RDY_BIT);
}

/* Reset RNG mode to NOP */
io_write32(trng_s_base + TRNG_S_CTRL, CMD_NOP);

mutex_unlock(&trng_mutex);

return TEE_SUCCESS;
}

0 comments on commit b8a9277

Please sign in to comment.