|
|
|
@ -20,6 +20,26 @@
@@ -20,6 +20,26 @@
|
|
|
|
|
|
|
|
|
|
LOG_MODULE_REGISTER(entropy, CONFIG_ENTROPY_LOG_LEVEL); |
|
|
|
|
|
|
|
|
|
#if SOC_LP_TIMER_SUPPORTED |
|
|
|
|
#include "hal/lp_timer_hal.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined CONFIG_SOC_SERIES_ESP32S3 |
|
|
|
|
/* If APB clock is 80 MHz, the maximum sampling frequency is around 45 KHz */ |
|
|
|
|
/* 45 KHz reading frequency is the maximum we have tested so far on S3 */ |
|
|
|
|
#define APB_CYCLE_WAIT_NUM (1778) |
|
|
|
|
#elif defined CONFIG_SOC_SERIES_ESP32C6 |
|
|
|
|
/* On ESP32C6, we only read one byte at a time, then XOR the value with
|
|
|
|
|
* an asynchronous timer (see code below). |
|
|
|
|
* The current value translates to a sampling frequency of around 62.5 KHz |
|
|
|
|
* for reading 8 bit samples, which is the rate at which the RNG was tested, |
|
|
|
|
* plus additional overhead for the calculation, making it slower. |
|
|
|
|
*/ |
|
|
|
|
#define APB_CYCLE_WAIT_NUM (160 * 16) |
|
|
|
|
#else |
|
|
|
|
#define APB_CYCLE_WAIT_NUM (16) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static inline uint32_t entropy_esp32_get_u32(void) |
|
|
|
|
{ |
|
|
|
|
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
|
|
|
|
@ -30,18 +50,29 @@ static inline uint32_t entropy_esp32_get_u32(void)
@@ -30,18 +50,29 @@ static inline uint32_t entropy_esp32_get_u32(void)
|
|
|
|
|
* wait a bit longer due to extra time spent in arithmetic and branch statements. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
uint32_t cpu_to_apb_freq_ratio = |
|
|
|
|
esp_clk_cpu_freq() / esp_clk_apb_freq(); |
|
|
|
|
uint32_t cpu_to_apb_freq_ratio = esp_clk_cpu_freq() / esp_clk_apb_freq(); |
|
|
|
|
|
|
|
|
|
static uint32_t last_ccount; |
|
|
|
|
uint32_t ccount; |
|
|
|
|
|
|
|
|
|
uint32_t result = 0; |
|
|
|
|
#if SOC_LP_TIMER_SUPPORTED |
|
|
|
|
for (size_t i = 0; i < sizeof(result); i++) { |
|
|
|
|
do { |
|
|
|
|
ccount = esp_cpu_get_cycle_count(); |
|
|
|
|
result ^= REG_READ(WDEV_RND_REG); |
|
|
|
|
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * APB_CYCLE_WAIT_NUM); |
|
|
|
|
uint32_t current_rtc_timer_counter = (lp_timer_hal_get_cycle_count() & 0xFF); |
|
|
|
|
|
|
|
|
|
result ^= ((result ^ current_rtc_timer_counter) & 0xFF) << (i * 8); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
do { |
|
|
|
|
ccount = esp_cpu_get_cycle_count(); |
|
|
|
|
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16); |
|
|
|
|
result ^= REG_READ(WDEV_RND_REG); |
|
|
|
|
} while (ccount - last_ccount < cpu_to_apb_freq_ratio * APB_CYCLE_WAIT_NUM); |
|
|
|
|
#endif |
|
|
|
|
last_ccount = ccount; |
|
|
|
|
|
|
|
|
|
return REG_READ(WDEV_RND_REG); |
|
|
|
|
return result ^ REG_READ(WDEV_RND_REG); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int entropy_esp32_get_entropy(const struct device *dev, uint8_t *buf, |
|
|
|
|