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:
parent
a5ddb72261
commit
57c7dfbbc3
5 changed files with 55 additions and 35 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue