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 <[email protected]>
  • Loading branch information
edtubbs committed Jan 3, 2025
1 parent 8796ab4 commit a42d956
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 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
75 changes: 75 additions & 0 deletions core/arch/arm/plat-rockchip/platform_rk3588.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <mm/core_memprot.h>
#include <platform.h>
#include <platform_config.h>
#include <rng_support.h>

#define FIREWALL_DDR_RGN(i) ((i) * 0x4)
#define FIREWALL_DDR_CON 0xf0
Expand All @@ -21,8 +22,25 @@

#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 TRNG_S_WORDS 4

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);

int platform_secure_ddr_region(int rgn, paddr_t st, size_t sz)
{
Expand Down Expand Up @@ -63,3 +81,60 @@ 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);
uint32_t *rand_buf = (uint32_t *)buf;
size_t remaining = blen;
uint32_t val;

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

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

/* Wait for SEED_DONE flag in ISTAT register */
do {
val = io_read32(trng_s_base + TRNG_S_ISTAT);
} while (!(val & (1 << 1)));

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

/* Set RNG length to 128 bits and disable interrupts */
io_write32(trng_s_base + TRNG_S_MODE, LEN_128BIT);
io_write32(trng_s_base + TRNG_S_IE, 0);

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

/* Wait for the RAND_RDY flag in the ISTAT register */
do {
val = io_read32(trng_s_base + TRNG_S_ISTAT);
} while (!(val & 1));

/* Read random data from RAND register */
for (size_t i = 0; i < TRNG_S_WORDS && remaining > 0; i++) {
uint32_t rnd = io_read32(trng_s_base + TRNG_S_RAND + i
* sizeof(uint32_t));

rand_buf[(blen - remaining) / sizeof(uint32_t)] = rnd;
remaining -= sizeof(uint32_t);
}

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

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

return TEE_SUCCESS;
}

0 comments on commit a42d956

Please sign in to comment.