diff --git a/sys/arm64/qoriq/caam/caam.c b/sys/arm64/qoriq/caam/caam.c --- a/sys/arm64/qoriq/caam/caam.c +++ b/sys/arm64/qoriq/caam/caam.c @@ -32,6 +32,7 @@ #include "caam_debug.h" #include "caam_internal.h" #include "caam_test.h" +#include "caam_trng.h" #include "jr/caam_jobdesc.h" #include "jr/caam_jr.h" #include "jr/caam_jr_hw.h" @@ -420,21 +421,30 @@ goto cleanup_rman; } + /* After CAAM is ready, initialize the RNG drivers */ + rv = caam_trng_attach(dev); + if (rv != 0) { + CAAM_LOG_ERROR("caam_trng_attach failed rv=(%d)\n", rv); + goto cleanup_jobrings; + } + #ifdef CAAM_DEBUG /* Add the caam test device for development */ rv = caam_test_attach(dev); if (rv != 0) { CAAM_LOG_ERROR("caam_test_attach failed rv=(%d)\n", rv); - goto cleanup_jobrings; + goto cleanup_trng; } #endif return (0); #ifdef CAAM_DEBUG +cleanup_trng: + caam_trng_detach(dev); +#endif cleanup_jobrings: - caam_jobrings_detach(dev); -#endif + caam_jobrings_detach(dev); cleanup_rman: rman_fini(&sc->mem_rman); cleanup_resource: @@ -495,6 +505,8 @@ { struct caam_softc *sc = device_get_softc(dev); + /* Remove TRNG drivers */ + caam_trng_detach(dev); #ifdef CAAM_DEBUG /* Remove the caam test device */ caam_test_detach(dev); diff --git a/sys/arm64/qoriq/caam/caam_trng.h b/sys/arm64/qoriq/caam/caam_trng.h new file mode 100644 --- /dev/null +++ b/sys/arm64/qoriq/caam/caam_trng.h @@ -0,0 +1,40 @@ +/* + * Copyright 2023 Alstom Group + * Copyright 2023 Sii Poland + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef CAAM_RNG_H +#define CAAM_RNG_H + +#include +#include +#include + +/* + * @brief Initialize CAAM TRNG module. + * + * Setup random harvester cache and refill. + * Register as a random source. + * Make TRNG side access /dev/random_caam character device. + * + * @param [in] dev caam device handle + * + * @retval :: 0 is returned on success + * @retval :: errno is returned on internal error + */ +int caam_trng_attach(device_t dev); + +/* + * @brief Uninitialize CAAM TRNG module and unregister our random source. + * + * @param [in] dev caam device handle + * + * @retval :: 0 is returned on success + * @retval :: errno is returned on internal error + */ +int caam_trng_detach(device_t dev); + +#endif /* CAAM_RNG_H */ \ No newline at end of file diff --git a/sys/arm64/qoriq/caam/caam_trng.c b/sys/arm64/qoriq/caam/caam_trng.c new file mode 100644 --- /dev/null +++ b/sys/arm64/qoriq/caam/caam_trng.c @@ -0,0 +1,702 @@ +/* + * Copyright 2021 NXP + * Copyright 2023 Alstom Group + * Copyright 2023 Sii Poland + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#include + +#include +#include +#include /* cdevsw struct */ +#include +#include +#include +#include +#include +#include /* uio struct */ + +#include +#include + +#include + +#include "caam.h" +#include "caam_debug.h" +#include "caam_internal.h" +#include "caam_trng.h" +#include "jr/caam_jobdesc.h" +#include "jr/caam_jr_hw.h" + +MALLOC_DEFINE(M_TRNG, "CAAMTRNG", "CAAM TRNG malloc"); + +#define NEXT_BUF_NUM(num) (((num) + 1) % (TRNG_CACHE_COUNT)); +#define TRNG_CACHE_SIZE 8192 +#define TRNG_CACHE_COUNT 2 +_Static_assert(TRNG_CACHE_COUNT >= 2, + "Need at least 2 buffers to function properly"); + +struct trng_cache; + +/* Taskqueue responsible for maintaining proper levels of TRNG cache */ +struct trng_tq { + struct taskqueue *tq; + struct task task; + struct trng_cache *c; + device_t dev; +}; + +/* + * NOTE: Currently there is only one cache consumer so atomic r/w + * on data_left ensures that data is either non-empty and read or + * empty and pending refill. + * If there will be more concurrent consumers, we need to add locks. + */ +struct cache_buf { + uint8_t *data; + uint32_t data_left; +}; + +/* Precached random data for fast access by harvester callback */ +struct trng_cache { + int current_buf; + struct cache_buf buf[TRNG_CACHE_COUNT]; + + struct trng_tq *refill_tq; +}; +static struct trng_cache g_cache; + +/* Workaround for API limitations of random(4). */ +static device_t g_caam_dev; + +int caam_trng_get_bytes(device_t dev, uint8_t *bytes, int byte_len); + +/* + * Wrapper for reading from random cache. + * Reads len bytes or up to bytes available in current buffer. + * If the current one has become exhausted gets a new buffer and + * enqueues a refill job. + */ +static uint32_t +trng_cache_buf_read(struct trng_cache *c, uint8_t *buf, uint32_t len) +{ + struct cache_buf *cur; + uint32_t read_len; + + cur = &c->buf[c->current_buf]; + + read_len = MIN(len, atomic_load_int(&cur->data_left)); + memcpy(buf, &cur->data[TRNG_CACHE_SIZE - cur->data_left], read_len); + + atomic_subtract_int(&cur->data_left, read_len); + + if (atomic_load_int(&cur->data_left) == 0) { + c->current_buf = NEXT_BUF_NUM(c->current_buf); + taskqueue_enqueue(c->refill_tq->tq, &c->refill_tq->task); + } + + return (read_len); +} + +/* Run RNG job with cache buffer as data destination */ +static int +trng_cache_refill(device_t dev, struct trng_cache *c, int buf_num) +{ + int ret = 0; + + ret = caam_trng_get_bytes(dev, c->buf[buf_num].data, TRNG_CACHE_SIZE); + if (ret != 0) { + CAAM_LOG_ERROR("caam_trng_get_bytes failed\n"); + } else { + atomic_store_int(&c->buf[buf_num].data_left, TRNG_CACHE_SIZE); + } + + return (ret); +} + +/* Traverse random cache buffers array and run refill jobs on empty ones */ +static void +trng_cache_refill_worker(void *context, int pending) +{ + struct trng_tq *tq = context; + struct trng_cache *c = tq->c; + int buf_num = c->current_buf; + + /* Refill empty buffers starting with the next one to be used */ + for (int i = 0; i < TRNG_CACHE_COUNT - 1; ++i) { + buf_num = NEXT_BUF_NUM(buf_num); + if (atomic_load_int(&c->buf[buf_num].data_left) == 0) { + trng_cache_refill(tq->dev, c, buf_num); + } + } +} + +/* Setup random cache refill task */ +static struct trng_tq * +trng_cache_refill_setup(device_t dev, struct trng_cache *c) +{ + struct trng_tq *trng_tq; + + trng_tq = malloc(sizeof(*trng_tq), M_TRNG, M_WAITOK | M_ZERO); + if (trng_tq == NULL) { + CAAM_LOG_ERROR("Could not allocate trng_tq\n"); + return (NULL); + } + trng_tq->c = c; + trng_tq->dev = dev; + + TASK_INIT(&trng_tq->task, 0, trng_cache_refill_worker, trng_tq); + trng_tq->tq = taskqueue_create_fast("caam_trng_tq", M_WAITOK | M_ZERO, + taskqueue_thread_enqueue, &trng_tq->tq); + taskqueue_start_threads(&trng_tq->tq, 1, PI_SOFT, "caam_trng_th"); + + return (trng_tq); +} + +/* Stop and teardown random cache refill task */ +static void +trng_cache_refill_teardown(struct trng_tq *tq) +{ + taskqueue_free(tq->tq); + free(tq, M_TRNG); +} + +/* + * Allocate cache buffers and setup refill task. + * Deinit with trng_cache_deinit(). + */ +static int +trng_cache_init(device_t dev, struct trng_cache *c, size_t cache_size) +{ + int i; + int ret = 0; + + c->current_buf = 0; + + /* + * Contigmalloc will actively reclaim memory until it can make + * a contiguous buffer. This can take a varying amount of time so + * we'll allocate only once at attach while memory is not (that) + * fragmented. + */ + for (i = 0; i < TRNG_CACHE_COUNT; ++i) { + c->buf[i].data_left = 0; + c->buf[i].data = contigmalloc(TRNG_CACHE_SIZE, M_TRNG, M_WAITOK, + 0, ~(vm_paddr_t)0, PAGE_SIZE, 0); + if (!c->buf[i].data) { + CAAM_LOG_ERROR( + "Could not allocate trng_tq->contig_buf\n"); + ret = ENOMEM; + goto free_bufs; + } + } + + c->refill_tq = trng_cache_refill_setup(dev, c); + if (!c->refill_tq) { + CAAM_LOG_ERROR("trng_cache_init failed\n"); + ret = ENOMEM; + goto free_bufs; + } + + return (0); + +free_bufs: + for (i -= 1; i >= 0; --i) + contigfree(c->buf[i].data, TRNG_CACHE_SIZE, M_TRNG); + + return (ret); +} + +/* + * Free cache buffers and teardown refill task. + */ +static void +trng_cache_deinit(struct trng_cache *c) +{ + trng_cache_refill_teardown(c->refill_tq); + + for (int i = 0; i < TRNG_CACHE_COUNT; ++i) + contigfree(c->buf[i].data, TRNG_CACHE_SIZE, M_TRNG); +} + +/*----------------------- RNG initialization functions ----------------------*/ +/* Is the HW RNG instantiated? + * Return code: + * 0 - Not in the instantiated state + * 1 - In the instantiated state + * state_handle - 0 for SH0, 1 for SH1 + */ +static int +is_trng_instantiated(device_t dev, uint32_t *state_handle) +{ + int ret_code = 0; + uint32_t rdsta; + + rdsta = caam_reg_read(dev, RNG_REG_RDSTA_OFFSET); + + /*Check if either of the two state handles has been instantiated */ + if (rdsta & RNG_STATE0_HANDLE_INSTANTIATED) { + *state_handle = 0; + ret_code = 1; + } else if (rdsta & RNG_STATE1_HANDLE_INSTANTIATED) { + *state_handle = 1; + ret_code = 1; + } + + return ret_code; +} + +/* Construct descriptor to instantiate RNG */ +static int +cnstr_trng_instantiate_jobdesc(uint32_t *desc) +{ + caam_jobdesc_init(desc); + caam_jobdesc_add_word(desc, 0xb0800000u); + /* Class1 Alg Operation,RNG Optype, Instantiate */ + caam_jobdesc_add_word(desc, 0x82500004u); + /* Wait for done */ + caam_jobdesc_add_word(desc, 0xa2000001u); + /*Load to clear written */ + caam_jobdesc_add_word(desc, 0x10880004u); + /*Pri Mode Reg clear */ + caam_jobdesc_add_word(desc, 0x00000001u); + /* Generate secure keys */ + caam_jobdesc_add_word(desc, 0x82501000u); + + return 0; +} + +/* @brief Submit descriptor to instantiate the RNG + * @retval 0 on success + * @retval other on error + */ +static int +run_trng_instantiate_job(device_t dev) +{ + int ret = 0; + struct job_descriptor desc; + struct job_descriptor *jobdesc = &desc; + jobdesc->arg = NULL; + jobdesc->callback = NULL; + + /* create the hw_rng descriptor */ + cnstr_trng_instantiate_jobdesc(jobdesc->desc); + + /* Finally, generate the requested random data bytes */ + ret = caam_run_descriptor_jr_blocking(dev, jobdesc, NULL); + if (ret != 0) { + CAAM_LOG_WARN("Error in running descriptor\n"); + ret = EIO; + } + + return ret; +} + +/* @brief Kick the TRNG block of the RNG HW Engine + * @param [in] ent_delay Entropy delay to be used + * By default, the TRNG runs for 200 clocks per sample; + * 1200 clocks per sample generates better entropy. + */ +static void +kick_trng(device_t dev, int ent_delay) +{ + uint32_t val; + + /* put RNG4 into program mode */ + val = caam_reg_read(dev, RNG_REG_RTMCTL_OFFSET); + val = val | RTMCTL_PRGM; + caam_reg_write(dev, RNG_REG_RTMCTL_OFFSET, val); + + /* rtsdctl bits 0-15 contain "Entropy Delay, which defines the + * length (in system clocks) of each Entropy sample taken + */ + val = caam_reg_read(dev, RNG_REG_RTSDCTL_OFFSET); + val = (val & ~RTSDCTL_ENT_DLY_MASK) | + (ent_delay << RTSDCTL_ENT_DLY_SHIFT); + caam_reg_write(dev, RNG_REG_RTSDCTL_OFFSET, val); + /* min. freq. count, equal to 1/4 of the entropy sample length */ + caam_reg_write(dev, RNG_REG_RTFRQMIN_OFFSET, ent_delay >> 2); + /* disable maximum frequency count */ + caam_reg_write(dev, RNG_REG_RTFRQMAX_OFFSET, RTFRQMAX_DISABLE); + + /* select raw sampling in both entropy shifter + * and statistical checker + */ + val = caam_reg_read(dev, RNG_REG_RTMCTL_OFFSET); + val = val | RTMCTL_SAMP_MODE_RAW_ES_SC; + caam_reg_write(dev, RNG_REG_RTMCTL_OFFSET, val); + + /* put RNG4 into run mode */ + val = caam_reg_read(dev, RNG_REG_RTMCTL_OFFSET); + val = val & ~RTMCTL_PRGM; + caam_reg_write(dev, RNG_REG_RTMCTL_OFFSET, val); +} + +/* This function instantiates the rng + * + * Return code: + * 0 - All is well + * <0 - Error occurred somewhere + */ +static int +instantiate_trng(device_t dev) +{ + int ret = 0; + int ent_delay = RTSDCTL_ENT_DLY_MIN; + uint32_t state_handle; + + ret = is_trng_instantiated(dev, &state_handle); + if (ret != 0) { + CAAM_LOG_NOTICE( + "RNG already instantiated, make sure it is running\n"); + + /* put RNG4 into run mode */ + uint32_t val = caam_reg_read(dev, RNG_REG_RTMCTL_OFFSET); + val = val & ~RTMCTL_PRGM; + caam_reg_write(dev, RNG_REG_RTMCTL_OFFSET, val); + + return 0; + } + + do { + kick_trng(dev, ent_delay); + ent_delay += 400; + /*if instantiate_rng(...) fails, the loop will rerun + *and the kick_trng(...) function will modify the + *upper and lower limits of the entropy sampling + *interval, leading to a sucessful initialization + */ + ret = run_trng_instantiate_job(dev); + } while ((ret != 0) && (ent_delay < RTSDCTL_ENT_DLY_MAX)); + + if (ret != 0) { + CAAM_LOG_ERROR("RNG: Failed to instantiate RNG\n"); + return ret; + } + + CAAM_LOG_INFO("RNG: Instantiated\n"); + + return ret; +} + +/*------------------ Functions to generate the RNG numbers ------------------*/ +/* Construct descriptor to generate Random words */ +static int +cnstr_trng_jobdesc(uint32_t *desc, uint32_t state_handle, uint32_t *add_inp, + uint32_t add_ip_len, caam_jr_dma_map_t *out_data_map, bool little_endian) +{ + bus_addr_t phys_addr_out = out_data_map->bus_addr; + + /* Current descriptor support only 64K length */ + if (out_data_map->buflen > 0xffffu) + return EINVAL; + /* Additional Input not supported by current descriptor */ + if (add_ip_len > 0U) + return EINVAL; + + CAAM_LOG_DEBUG("Constructing descriptor\n"); + caam_jobdesc_init(desc); + /* Class1 Alg Operation,RNG Optype, Generate */ + caam_jobdesc_add_word(desc, 0xb0800000u); + caam_jobdesc_add_word(desc, + 0x82500000u | (state_handle << ALG_AAI_SH_SHIFT)); + caam_jobdesc_add_word(desc, 0x60340000u | out_data_map->buflen); + caam_jobdesc_add_ptr(desc, phys_addr_out, little_endian); + + return 0; +} + +/* Generate Random Data using HW RNG + * Parameters: + * uint8_t* add_input - user specified optional input byte array + * uint32_t add_input_len - number of bytes of additional input + * uint8_t* out - user specified output byte array + * uint32_t out_len - number of bytes to store in output byte array + * Return code: + * 0 - SUCCESS + * !0 - ERROR + */ +static int +run_trng_generate_job(device_t dev, uint32_t *add_input, uint32_t add_input_len, + uint8_t *out, uint32_t out_len, uint32_t state_handle) +{ + int ret = 0; + struct job_descriptor desc; + struct job_descriptor *jobdesc = &desc; + caam_jr_dma_map_t out_data_map; + struct caam_softc *sc; + device_t jr_dev; + + sc = device_get_softc(dev); + + jobdesc->arg = NULL; + jobdesc->callback = NULL; + + jr_dev = jr_pool_acquire(&sc->jr_pool); + if (jr_dev == NULL) { + CAAM_LOG_ERROR("Failed to acquire JR\n"); + goto exit; + } + + /* Map the output buffer to the DMA memory */ + ret = caam_jr_dma_map(jr_dev, &out_data_map, out, out_len, 0, + BUS_DMA_NOWAIT, JR_MAP_SYNC); + if (ret != 0) { + CAAM_LOG_ERROR("DMA mapping failed\n"); + goto jr_free; + } + + /* create the hw_rng descriptor */ + ret = cnstr_trng_jobdesc(jobdesc->desc, state_handle, add_input, + add_input_len, &out_data_map, sc->little_endian); + if (ret != 0) { + CAAM_LOG_ERROR("Descriptor construction failed\n"); + goto dma_unmap; + } + + /* Finally, generate the requested random data bytes */ + ret = caam_run_descriptor_jr_blocking(dev, jobdesc, jr_dev); + if (ret != 0) { + CAAM_LOG_ERROR("Error in running descriptor\n"); + goto dma_unmap; + } + +dma_unmap: + caam_jr_dma_unmap(jr_dev, &out_data_map, JR_MAP_SYNC); + +jr_free: + jr_pool_release(&sc->jr_pool, jr_dev); + +exit: + return ret; +} + +/* Generate random bytes, and stuff them into the bytes buffer + * + * If the HW RNG has not already been instantiated, + * it will be instantiated before data is generated. + * + * Parameters: + * uint8_t* bytes - byte buffer large enough to hold the requested random date + * int byte_len - number of random bytes to generate + * + * Return code: + * 0 - All is well + * ~0 - Error occurred somewhere + */ +int +caam_trng_get_bytes(device_t dev, uint8_t *bytes, int byte_len) +{ + int ret_code = 0; + int init_ret_code = 0; + uint32_t state_handle = 0; + + /* If this is the first time this routine is called, + * then the rng will not already be instantiated. + * Therefore, before generating data, instantiate the rng + */ + init_ret_code = is_trng_instantiated(dev, &state_handle); + if (init_ret_code == 0) { + CAAM_LOG_INFO("Instantiating the HW RNG\n"); + + /* Instantiate the hw RNG */ + ret_code = instantiate_trng(dev); + if (ret_code != 0) { + CAAM_LOG_ERROR("HW RNG Instantiate failed\n"); + } + } + + if (ret_code == 0) { + ret_code = run_trng_generate_job(dev, 0, 0, bytes, byte_len, + state_handle); + if (ret_code != 0) { + CAAM_LOG_ERROR("HW RNG Generate failed\n"); + } + } + + return ret_code; +} + +/*------------ Random harvester (random_caam) interface functions -----------*/ +static u_int random_caam_read(void *, u_int); + +static struct random_source random_caam = { + .rs_ident = "NXP QorIQ platforms CAAM TRNG", + .rs_source = RANDOM_PURE_CAAMTRNG, + .rs_read = random_caam_read +}; + +/* Blocking read function will return prebuffered data */ +static u_int +random_caam_read(void *buf, u_int c) +{ + struct trng_cache *cache = &g_cache; + + c = trng_cache_buf_read(cache, buf, c); + + CAAM_LOG_DEBUG("Read out %iB\n", c); + + return c; +} + +/*------ Random character device (random_caam_cdev) interface functions -----*/ +#define BUFFERSIZE 256 + +/* Function prototypes */ +static d_open_t random_caam_cdev_open; +static d_close_t random_caam_cdev_close; +static d_read_t random_caam_cdev_read; + +/* Character device entry points */ +static struct cdevsw random_caam_cdevsw = { + .d_version = D_VERSION, + .d_open = random_caam_cdev_open, + .d_close = random_caam_cdev_close, + .d_read = random_caam_cdev_read, + .d_name = "random_caam_cdev", +}; + +/* vars */ +static struct cdev *random_caam_cdev; + +static int +random_caam_cdev_open(struct cdev *dev __unused, int oflags __unused, + int devtype __unused, struct thread *td __unused) +{ + device_t caam_dev = g_caam_dev; + + if (caam_dev == NULL) { + CAAM_LOG_ERROR("No CAAM module available!\n"); + return (ENXIO); + } + + CAAM_LOG_DEBUG("Opened CAAM TRNG character device successfully.\n"); + return (0); +} + +static int +random_caam_cdev_close(struct cdev *dev __unused, int fflag __unused, + int devtype __unused, struct thread *td __unused) +{ + CAAM_LOG_DEBUG("Closing CAAM TRNG character device.\n"); + return (0); +} + +/* + * The read function reads from random device and set it to userland for + * accessing. + */ +static int +random_caam_cdev_read(struct cdev *dev __unused, struct uio *uio, + int ioflag __unused) +{ + size_t read_len; + int error = 0; + uint8_t random_buf[BUFFERSIZE]; + device_t caam_dev = g_caam_dev; + + while (uio->uio_resid > 0) { + /* Maximum data to read is either local buff or user request */ + read_len = MIN((size_t)uio->uio_resid, sizeof(random_buf)); + + error = caam_trng_get_bytes(caam_dev, random_buf, read_len); + if (error != 0) { + CAAM_LOG_ERROR("RNG generation failed!\n"); + break; + } + + /* + * uiomove() may yield the CPU before each 'read_len' bytes (up + * to bufsize) are copied out. + */ + if ((error = uiomove(random_buf, read_len, uio)) != 0) { + CAAM_LOG_ERROR("uiomove failed!\n"); + break; + } + } + + explicit_bzero(random_buf, sizeof(random_buf)); + + return (error); +} + +/*--------------------- CAAM device management functions --------------------*/ +int +caam_trng_attach(device_t dev) +{ + int error = 0; + struct make_dev_args args; + struct trng_cache *c = &g_cache; + + /* Add the random source and the character device only on the first CAAM + * device.*/ + if (g_caam_dev == NULL) { + g_caam_dev = dev; + + error = trng_cache_init(dev, c, TRNG_CACHE_SIZE); + if (error) { + CAAM_LOG_ERROR("Failed to init TRNG cache ret=%d\n", + error); + goto exit; + } + + /* Initial fill before harvester can read from our buffers */ + for (int i = 0; i < TRNG_CACHE_COUNT; ++i) { + error = trng_cache_refill(dev, c, i); + if (error) { + trng_cache_deinit(c); + goto exit; + } + } + + random_source_register(&random_caam); + CAAM_LOG_INFO("CAAM TRNG registering fast provider: \"%s\"\n", + random_caam.rs_ident); + + /* Register the device as read only */ + make_dev_args_init(&args); + args.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK; + args.mda_devsw = &random_caam_cdevsw; + args.mda_cr = 0; + args.mda_uid = UID_ROOT; + args.mda_gid = GID_WHEEL; + args.mda_mode = 0400; + + error = make_dev_s(&args, &random_caam_cdev, "random_caam"); + + CAAM_LOG_INFO( + "CAAM TRNG /dev/random_caam character device loaded.\n"); + } + +exit: + return error; +} + +int +caam_trng_detach(device_t dev) +{ + struct trng_cache *c = &g_cache; + + /* Deregister rng source and rmove character device only if correct CAAM + * device is detached */ + if (dev == g_caam_dev) { + CAAM_LOG_INFO( + "CAAM TRNG /dev/random_caam character device removed.\n"); + destroy_dev(random_caam_cdev); + + CAAM_LOG_INFO("CAAM TRNG deregistering fast provider: \"%s\"\n", + random_caam.rs_ident); + random_source_deregister(&random_caam); + + trng_cache_deinit(c); + + /* at this time no clients should exist that can use the + * g_caam_dev */ + g_caam_dev = NULL; + } + + return 0; +} diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -687,6 +687,7 @@ arm64/qoriq/clk/qoriq_clk_pll.c optional clk soc_nxp_ls arm64/qoriq/clk/qoriq_clkgen.c optional clk soc_nxp_ls fdt arm64/qoriq/caam/caam.c optional caam soc_nxp_ls +arm64/qoriq/caam/caam_trng.c optional caam soc_nxp_ls arm64/qoriq/caam/caam_test.c optional caam caam_debug soc_nxp_ls arm64/qoriq/caam/jr/caam_jr.c optional caam soc_nxp_ls arm64/qoriq/caam/jr/caam_jr_pool.c optional caam soc_nxp_ls diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -385,6 +385,7 @@ [RANDOM_PURE_VMGENID] = "PURE_VMGENID", [RANDOM_PURE_QUALCOMM] = "PURE_QUALCOMM", [RANDOM_PURE_ARMV8] = "PURE_ARMV8", + [RANDOM_PURE_CAAMTRNG] = "PURE_CAAMTRNG", /* "ENTROPYSOURCE" */ }; diff --git a/sys/sys/random.h b/sys/sys/random.h --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -103,6 +103,7 @@ RANDOM_PURE_VMGENID, RANDOM_PURE_QUALCOMM, RANDOM_PURE_ARMV8, + RANDOM_PURE_CAAMTRNG, ENTROPYSOURCE }; _Static_assert(ENTROPYSOURCE <= 32,