drivers: entropy: esp32: update register call

Update entropy driver to use proper registers

Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
This commit is contained in:
Sylvio Alves 2020-08-20 06:52:42 -03:00 committed by Anas Nashif
commit 57c7dfbbc3
5 changed files with 55 additions and 35 deletions

View file

@ -20,6 +20,7 @@
#include <drivers/clock_control.h>
#include <sys/util.h>
#include "clock_control_esp32.h"
#include "driver/periph_ctrl.h"
struct esp32_clock_config {
uint32_t clk_src_sel;
@ -176,6 +177,16 @@ static inline uint32_t clk_val_to_reg_val(uint32_t val)
return (val & UINT16_MAX) | ((val & UINT16_MAX) << 16);
}
int IRAM_ATTR esp_clk_cpu_freq(void)
{
return MHZ(esp32_rom_g_ticks_per_us_pro);
}
int IRAM_ATTR esp_clk_apb_freq(void)
{
return MHZ(MIN(esp32_rom_g_ticks_per_us_pro, 80));
}
void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us)
{
/* Update scale factors used by ets_delay_us */
@ -326,6 +337,9 @@ static int clock_control_esp32_init(const struct device *dev)
return -EINVAL;
}
/* Enable RNG clock. */
periph_module_enable(PERIPH_RNG_MODULE);
/* Re-calculate the CCOUNT register value to make time calculation correct.
* This should be updated on each frequency change
* New CCOUNT = Current CCOUNT * (new freq / old freq)

View file

@ -18,15 +18,6 @@
#define I2C_READREG_RTC(block, reg_add) \
esp32_rom_i2c_readReg(block, block##_HOSTID, reg_add)
# define XTHAL_GET_CCOUNT() ({ int __ccount; \
__asm__ __volatile__ ("rsr.ccount %0" : "=a" (__ccount)); \
__ccount; })
# define XTHAL_SET_CCOUNT(v) do { int __ccount = (int)(v); \
__asm__ __volatile__ ("wsr.ccount %0" : : "a" (__ccount) : "memory"); \
} while (0)
/*
* Get voltage level for CPU to run at 240 MHz, or for flash/PSRAM to run at 80 MHz.
* 0x0: level 7; 0x1: level 6; 0x2: level 5; 0x3: level 4. (RO)

View file

@ -7,6 +7,7 @@ config ENTROPY_ESP32_RNG
bool "ESP32 entropy number generator driver"
depends on SOC_ESP32
select ENTROPY_HAS_DRIVER
default y
help
This option enables the entropy number generator for ESP32 SoCs.

View file

@ -8,41 +8,53 @@
#include <string.h>
#include <drivers/entropy.h>
#include <soc/dport_reg.h>
#include <soc/rtc.h>
#include <soc/wdev_reg.h>
#include <soc/rtc_cntl_reg.h>
#include <soc/apb_ctrl_reg.h>
#include <esp_system.h>
#include <soc.h>
extern int esp_clk_cpu_freq(void);
extern int esp_clk_apb_freq(void);
static inline uint32_t entropy_esp32_get_u32(void)
{
/*
* APB Address: 0x60035144 (Safe,slower writes)
* DPORT Address: 0x3ff75144 (write bug, fast writes)
* In this case it won't make a difference because it is read only
* More info available at:
* https://www.esp32.com/viewtopic.php?f=2&t=3033&p=14227
* also check: ECO and Workarounds for Bugs Document, point 3.3
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
* of extra entropy from a hardware randomness source every APB clock cycle
* (provided WiFi or BT are enabled). To make sure entropy is not drained
* faster than it is added, this function needs to wait for at least 16 APB
* clock cycles after reading previous word. This implementation may actually
* wait a bit longer due to extra time spent in arithmetic and branch statements.
*/
volatile uint32_t *rng_data_reg = (uint32_t *)DT_INST_REG_ADDR(0);
/* Read just once. This is not optimal as the generator has
* limited throughput due to scarce sources of entropy, specially
* with the radios turned off. Might want to revisit this.
*/
return *rng_data_reg;
uint32_t cpu_to_apb_freq_ratio =
esp_clk_cpu_freq() / esp_clk_apb_freq();
static uint32_t last_ccount;
uint32_t ccount;
do {
ccount = XTHAL_GET_CCOUNT();
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16);
last_ccount = ccount;
return REG_READ(WDEV_RND_REG);
}
static int entropy_esp32_get_entropy(const struct device *device,
uint8_t *buf, uint16_t len)
static int entropy_esp32_get_entropy(const struct device *device, uint8_t *buf,
uint16_t len)
{
while (len) {
uint32_t v = entropy_esp32_get_u32();
assert(buf != NULL);
uint8_t *buf_bytes = (uint8_t *)buf;
if (len >= sizeof(v)) {
memcpy(buf, &v, sizeof(v));
while (len > 0) {
uint32_t word = entropy_esp32_get_u32();
uint32_t to_copy = MIN(sizeof(word), len);
buf += sizeof(v);
len -= sizeof(v);
} else {
memcpy(buf, &v, len);
break;
}
memcpy(buf_bytes, &word, to_copy);
buf_bytes += to_copy;
len -= to_copy;
}
return 0;
@ -50,10 +62,11 @@ static int entropy_esp32_get_entropy(const struct device *device,
static int entropy_esp32_init(const struct device *device)
{
/* clock initialization handled by clock manager */
return 0;
}
static struct entropy_driver_api entropy_esp32_api_funcs = {
static const struct entropy_driver_api entropy_esp32_api_funcs = {
.get_entropy = entropy_esp32_get_entropy
};

View file

@ -7,6 +7,7 @@
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_API_H_
#include <xtensa/hal.h>
#include <xtensa/core-macros.h>
#include "xtensa_rtos.h"
#include "xtensa_context.h"