drivers: add CC13xx / CC26xx entropy driver
Add driver for the TRNG entropy source on the TI CC13xx / CC26xx series SoCs. Signed-off-by: Brett Witherspoon <spoonb@cdspooner.com>
This commit is contained in:
parent
3bcd188068
commit
2bee500f06
8 changed files with 278 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
zephyr_library()
|
zephyr_library()
|
||||||
|
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_ENTROPY_CC13XX_CC26XX_RNG entropy_cc13xx_cc26xx.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_ENTROPY_ESP32_RNG entropy_esp32.c)
|
zephyr_library_sources_ifdef(CONFIG_ENTROPY_ESP32_RNG entropy_esp32.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_RNGA entropy_mcux_rnga.c)
|
zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_RNGA entropy_mcux_rnga.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_TRNG entropy_mcux_trng.c)
|
zephyr_library_sources_ifdef(CONFIG_ENTROPY_MCUX_TRNG entropy_mcux_trng.c)
|
||||||
|
|
|
@ -13,6 +13,7 @@ menuconfig ENTROPY_GENERATOR
|
||||||
|
|
||||||
if ENTROPY_GENERATOR
|
if ENTROPY_GENERATOR
|
||||||
|
|
||||||
|
source "drivers/entropy/Kconfig.cc13xx_cc26xx"
|
||||||
source "drivers/entropy/Kconfig.mcux"
|
source "drivers/entropy/Kconfig.mcux"
|
||||||
source "drivers/entropy/Kconfig.stm32"
|
source "drivers/entropy/Kconfig.stm32"
|
||||||
source "drivers/entropy/Kconfig.esp32"
|
source "drivers/entropy/Kconfig.esp32"
|
||||||
|
|
51
drivers/entropy/Kconfig.cc13xx_cc26xx
Normal file
51
drivers/entropy/Kconfig.cc13xx_cc26xx
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# Kconfig.cc13xx_cc26xx - TI CC13xx / CC26xx entropy driver configuration
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 Brett Witherspoon
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config ENTROPY_CC13XX_CC26XX_RNG
|
||||||
|
bool "TI SimpleLink CC13xx / CC26xx True Random Number Generator (TRNG)"
|
||||||
|
depends on SOC_SERIES_CC13X2_CC26X2
|
||||||
|
select ENTROPY_HAS_DRIVER
|
||||||
|
select HAS_DTS_ENTROPY
|
||||||
|
select RING_BUFFER
|
||||||
|
help
|
||||||
|
This option enables the driver for the True Random Number Generator (TRNG)
|
||||||
|
for TI SimpleLink CC13xx / CC26xx SoCs.
|
||||||
|
|
||||||
|
if ENTROPY_CC13XX_CC26XX_RNG
|
||||||
|
|
||||||
|
config ENTROPY_CC13XX_CC26XX_POOL_SIZE
|
||||||
|
int "Number of bytes in the entropy pool"
|
||||||
|
default 512
|
||||||
|
help
|
||||||
|
The size in bytes of the buffer used to store entropy generated by the
|
||||||
|
hardware. Should be a power of two for high performance.
|
||||||
|
|
||||||
|
config ENTROPY_CC13XX_CC26XX_SAMPLES_PER_CYCLE
|
||||||
|
int "Number of samples to generate entropy"
|
||||||
|
range 256 16777216
|
||||||
|
default 240000
|
||||||
|
help
|
||||||
|
The number of samples used to generate entropy. The time required to
|
||||||
|
generate 64 bits of entropy is determined by the number of FROs enabled,
|
||||||
|
the sampling (system) clock frequency, and this value.
|
||||||
|
|
||||||
|
config ENTROPY_CC13XX_CC26XX_ALARM_THRESHOLD
|
||||||
|
int "Threshold for detected repeated patterns"
|
||||||
|
range 0 255
|
||||||
|
default 255
|
||||||
|
help
|
||||||
|
The number of samples detected with repeating patterns before an alarm
|
||||||
|
event is triggered. The associated FRO is automatically shut down.
|
||||||
|
|
||||||
|
config ENTROPY_CC13XX_CC26XX_SHUTDOWN_THRESHOLD
|
||||||
|
int "Threshold for the number of FROs automatically shut down"
|
||||||
|
range 0 24
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
The number of FROs allowed to be shutdown before the driver attempts to
|
||||||
|
take corrective action.
|
||||||
|
|
||||||
|
endif # ENTROPY_CC13XX_CC26XX_RNG
|
170
drivers/entropy/entropy_cc13xx_cc26xx.c
Normal file
170
drivers/entropy/entropy_cc13xx_cc26xx.c
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Brett Witherspoon
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <entropy.h>
|
||||||
|
#include <irq.h>
|
||||||
|
#include <ring_buffer.h>
|
||||||
|
#include <sys_io.h>
|
||||||
|
|
||||||
|
#include <driverlib/prcm.h>
|
||||||
|
#include <driverlib/trng.h>
|
||||||
|
|
||||||
|
struct entropy_cc13xx_cc26xx_data {
|
||||||
|
struct k_sem lock;
|
||||||
|
struct k_sem sync;
|
||||||
|
struct ring_buf pool;
|
||||||
|
u8_t data[CONFIG_ENTROPY_CC13XX_CC26XX_POOL_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE_DECLARE(entropy_cc13xx_cc26xx);
|
||||||
|
|
||||||
|
static inline struct entropy_cc13xx_cc26xx_data *
|
||||||
|
get_dev_data(struct device *dev)
|
||||||
|
{
|
||||||
|
return dev->driver_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entropy_cc13xx_cc26xx_get_entropy(struct device *dev, u8_t *buf,
|
||||||
|
u16_t len)
|
||||||
|
{
|
||||||
|
struct entropy_cc13xx_cc26xx_data *data = get_dev_data(dev);
|
||||||
|
u32_t cnt;
|
||||||
|
|
||||||
|
TRNGIntEnable(TRNG_NUMBER_READY);
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
k_sem_take(&data->lock, K_FOREVER);
|
||||||
|
cnt = ring_buf_get(&data->pool, buf, len);
|
||||||
|
k_sem_give(&data->lock);
|
||||||
|
|
||||||
|
if (cnt) {
|
||||||
|
buf += cnt;
|
||||||
|
len -= cnt;
|
||||||
|
} else {
|
||||||
|
k_sem_take(&data->sync, K_FOREVER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void entropy_cc13xx_cc26xx_isr(void *arg)
|
||||||
|
{
|
||||||
|
struct entropy_cc13xx_cc26xx_data *data = get_dev_data(arg);
|
||||||
|
u32_t src, cnt, off;
|
||||||
|
u32_t num[2];
|
||||||
|
|
||||||
|
/* Interrupt service routine as described in TRM section 18.6.1.3.2 */
|
||||||
|
src = TRNGStatusGet();
|
||||||
|
|
||||||
|
if (src & TRNG_NUMBER_READY) {
|
||||||
|
/* This function acknowledges the ready status */
|
||||||
|
num[1] = TRNGNumberGet(TRNG_HI_WORD);
|
||||||
|
num[0] = TRNGNumberGet(TRNG_LOW_WORD);
|
||||||
|
|
||||||
|
cnt = ring_buf_put(&data->pool, (u8_t *)num, sizeof(num));
|
||||||
|
|
||||||
|
/* When pool is full disable interrupt and stop reading numbers */
|
||||||
|
if (cnt != sizeof(num)) {
|
||||||
|
TRNGIntDisable(TRNG_NUMBER_READY);
|
||||||
|
}
|
||||||
|
|
||||||
|
k_sem_give(&data->sync);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the shutdown FROs' oscillating frequncy in an attempt to
|
||||||
|
* prevent further locking on to the sampling clock frequncy.
|
||||||
|
*/
|
||||||
|
if (src & TRNG_FRO_SHUTDOWN) {
|
||||||
|
/* Clear shutdown */
|
||||||
|
TRNGIntClear(TRNG_FRO_SHUTDOWN);
|
||||||
|
/* Disabled FROs */
|
||||||
|
off = sys_read32(TRNG_BASE + TRNG_O_ALARMSTOP);
|
||||||
|
/* Clear alarms */
|
||||||
|
sys_write32(0, TRNG_BASE + TRNG_O_ALARMMASK);
|
||||||
|
sys_write32(0, TRNG_BASE + TRNG_O_ALARMSTOP);
|
||||||
|
/* De-tune FROs */
|
||||||
|
sys_write32(off, TRNG_BASE + TRNG_O_FRODETUNE);
|
||||||
|
/* Re-enable FROs */
|
||||||
|
sys_write32(off, TRNG_BASE + TRNG_O_FROEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entropy_cc13xx_cc26xx_init(struct device *dev)
|
||||||
|
{
|
||||||
|
struct entropy_cc13xx_cc26xx_data *data = get_dev_data(dev);
|
||||||
|
|
||||||
|
/* Power TRNG domain */
|
||||||
|
PRCMPowerDomainOn(PRCM_DOMAIN_PERIPH);
|
||||||
|
|
||||||
|
/* Enable TRNG peripheral clocks */
|
||||||
|
PRCMPeripheralRunEnable(PRCM_PERIPH_TRNG);
|
||||||
|
/* Enabled the TRNG while in sleep mode to keep the entropy pool full. After
|
||||||
|
* the pool is full the TRNG will enter idle mode when random numbers are no
|
||||||
|
* longer being read. */
|
||||||
|
PRCMPeripheralSleepEnable(PRCM_PERIPH_TRNG);
|
||||||
|
PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_TRNG);
|
||||||
|
|
||||||
|
|
||||||
|
/* Load PRCM settings */
|
||||||
|
PRCMLoadSet();
|
||||||
|
while (!PRCMLoadGet()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Peripherals should not be accessed until power domain is on. */
|
||||||
|
while (PRCMPowerDomainStatus(PRCM_DOMAIN_PERIPH) !=
|
||||||
|
PRCM_DOMAIN_POWER_ON) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize driver data */
|
||||||
|
ring_buf_init(&data->pool, sizeof(data->data), data->data);
|
||||||
|
|
||||||
|
/* Initialization as described in TRM section 18.6.1.2 */
|
||||||
|
TRNGReset();
|
||||||
|
while (sys_read32(TRNG_BASE + TRNG_O_SWRESET)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set samples per cycle */
|
||||||
|
TRNGConfigure(0, CONFIG_ENTROPY_CC13XX_CC26XX_SAMPLES_PER_CYCLE, 0);
|
||||||
|
/* De-tune FROs */
|
||||||
|
sys_write32(TRNG_FRODETUNE_FRO_MASK_M, TRNG_BASE + TRNG_O_FRODETUNE);
|
||||||
|
/* Enable FROs */
|
||||||
|
sys_write32(TRNG_FROEN_FRO_MASK_M, TRNG_BASE + TRNG_O_FROEN);
|
||||||
|
/* Set shutdown and alarm thresholds */
|
||||||
|
sys_write32((CONFIG_ENTROPY_CC13XX_CC26XX_SHUTDOWN_THRESHOLD << 16) |
|
||||||
|
CONFIG_ENTROPY_CC13XX_CC26XX_ALARM_THRESHOLD,
|
||||||
|
TRNG_BASE + TRNG_O_ALARMCNT);
|
||||||
|
|
||||||
|
TRNGEnable();
|
||||||
|
TRNGIntEnable(TRNG_NUMBER_READY | TRNG_FRO_SHUTDOWN);
|
||||||
|
|
||||||
|
IRQ_CONNECT(DT_TI_CC13XX_CC26XX_TRNG_0_IRQ_0,
|
||||||
|
DT_TI_CC13XX_CC26XX_TRNG_0_IRQ_0_PRIORITY,
|
||||||
|
entropy_cc13xx_cc26xx_isr,
|
||||||
|
DEVICE_GET(entropy_cc13xx_cc26xx), 0);
|
||||||
|
irq_enable(DT_TI_CC13XX_CC26XX_TRNG_0_IRQ_0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct entropy_driver_api entropy_cc13xx_cc26xx_driver_api = {
|
||||||
|
.get_entropy = entropy_cc13xx_cc26xx_get_entropy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct entropy_cc13xx_cc26xx_data entropy_cc13xx_cc26xx_data = {
|
||||||
|
.lock = Z_SEM_INITIALIZER(entropy_cc13xx_cc26xx_data.lock, 1, 1),
|
||||||
|
.sync = Z_SEM_INITIALIZER(entropy_cc13xx_cc26xx_data.sync, 0, 1),
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE_AND_API_INIT(entropy_cc13xx_cc26xx, DT_TI_CC13XX_CC26XX_TRNG_0_LABEL,
|
||||||
|
entropy_cc13xx_cc26xx_init, &entropy_cc13xx_cc26xx_data,
|
||||||
|
NULL, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||||
|
&entropy_cc13xx_cc26xx_driver_api);
|
|
@ -52,6 +52,14 @@
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
trng: random@40028000 {
|
||||||
|
compatible = "ti,cc13xx-cc26xx-trng";
|
||||||
|
reg = <0x40028000 0x2000>;
|
||||||
|
interrupts = <33 0>;
|
||||||
|
status = "disabled";
|
||||||
|
label = "TRNG";
|
||||||
|
};
|
||||||
|
|
||||||
uart0: uart@40001000 {
|
uart0: uart@40001000 {
|
||||||
compatible = "ti,cc13xx-cc26xx-uart";
|
compatible = "ti,cc13xx-cc26xx-uart";
|
||||||
reg = <0x40001000 0x1000>;
|
reg = <0x40001000 0x1000>;
|
||||||
|
|
39
dts/bindings/rng/ti,cc13xx-cc26xx-trng.yaml
Normal file
39
dts/bindings/rng/ti,cc13xx-cc26xx-trng.yaml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 Brett Witherspoon
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
---
|
||||||
|
title: TI SimpleLink CC13xx / CC26xx True Random Number Generator (TRNG)
|
||||||
|
version: 0.1
|
||||||
|
|
||||||
|
description: >
|
||||||
|
This is a representation of the TI SimpleLink CC13xx / CC26xx TRNG node
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
type: string
|
||||||
|
category: required
|
||||||
|
description: compatible strings
|
||||||
|
constraint: "ti,cc13xx-cc26xx-trng"
|
||||||
|
generation: define
|
||||||
|
|
||||||
|
reg:
|
||||||
|
type: int
|
||||||
|
description: mmio register space
|
||||||
|
generation: define
|
||||||
|
category: required
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
type: compound
|
||||||
|
category: required
|
||||||
|
description: required interrupts
|
||||||
|
generation: define
|
||||||
|
|
||||||
|
label:
|
||||||
|
type: string
|
||||||
|
category: required
|
||||||
|
description: Human readable string describing the device (used by Zephyr for API name)
|
||||||
|
generation: define
|
||||||
|
|
||||||
|
...
|
|
@ -39,6 +39,13 @@ config GPIO_CC13XX_CC26XX
|
||||||
|
|
||||||
endif # GPIO
|
endif # GPIO
|
||||||
|
|
||||||
|
if ENTROPY_GENERATOR
|
||||||
|
|
||||||
|
config ENTROPY_CC13XX_CC26XX_RNG
|
||||||
|
default y
|
||||||
|
|
||||||
|
endif # ENTROPY_GENERATOR
|
||||||
|
|
||||||
if SERIAL
|
if SERIAL
|
||||||
|
|
||||||
config UART_CC13XX_CC26XX
|
config UART_CC13XX_CC26XX
|
||||||
|
|
|
@ -7,5 +7,6 @@
|
||||||
/* SoC level DTS fixup file */
|
/* SoC level DTS fixup file */
|
||||||
|
|
||||||
#define DT_NUM_IRQ_PRIO_BITS DT_ARM_V7M_NVIC_E000E100_ARM_NUM_IRQ_PRIORITY_BITS
|
#define DT_NUM_IRQ_PRIO_BITS DT_ARM_V7M_NVIC_E000E100_ARM_NUM_IRQ_PRIORITY_BITS
|
||||||
|
#define CONFIG_ENTROPY_NAME DT_TI_CC13XX_CC26XX_TRNG_0_LABEL
|
||||||
|
|
||||||
/* End of SoC Level DTS fixup file */
|
/* End of SoC Level DTS fixup file */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue