feat(esp_hw_support): brought up RNG on ESP32-P4

This commit is contained in:
Jakob Hasse 2024-01-19 09:53:56 +08:00 committed by Aditya Patwardhan
parent f5ee19f01e
commit 9c108f2da6
No known key found for this signature in database
GPG Key ID: E628B2648FBF0DD8
9 changed files with 140 additions and 41 deletions

View File

@ -28,6 +28,9 @@
#if (defined CONFIG_IDF_TARGET_ESP32C6 || defined CONFIG_IDF_TARGET_ESP32H2)
#define RNG_CPU_WAIT_CYCLE_NUM (80 * 16) // Keep the byte sampling frequency in the ~62KHz range which has been
// tested.
#elif CONFIG_IDF_TARGET_ESP32P4
// bootloader tested with around 63 KHz bytes reading frequency
#define RNG_CPU_WAIT_CYCLE_NUM (CPU_CLK_FREQ_MHZ_BTLD * 16)
#else
#define RNG_CPU_WAIT_CYCLE_NUM (80 * 32 * 2) /* extra factor of 2 is precautionary */
#endif

View File

@ -1,22 +1,101 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "sdkconfig.h"
#include "bootloader_random.h"
#include "esp_log.h"
#include "soc/soc.h"
#include "soc/adc_reg.h"
#include "soc/pmu_reg.h"
#include "soc/regi2c_saradc.h"
#include "soc/hp_sys_clkrst_reg.h"
#include "soc/rtcadc_reg.h"
#include "esp_private/regi2c_ctrl.h"
#include "esp_rom_regi2c.h"
static const char *TAG = "bootloader_random";
// TODO IDF-6497: once ADC API is supported, use the API instead of defining functions and constants here
#define I2C_SAR_ADC_INIT_CODE_VAL 2166
typedef struct {
int atten;
int channel;
} pattern_item;
typedef struct {
pattern_item item[4];
} pattern_table;
static void adc1_fix_initcode_set(uint32_t initcode_value)
{
uint32_t msb = initcode_value >> 8;
uint32_t lsb = initcode_value & 0xff;
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_SAR1_INIT_CODE_MSB, msb);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_SAR1_INIT_CODE_LSB, lsb);
}
//total 4 tables
static void hpadc_sar1_pattern_table_cfg(unsigned int table_idx, pattern_table table)
{
uint32_t wdata = 0;
wdata = (table.item[0].channel << 20 | table.item[0].atten << 18 |
table.item[1].channel << 14|table.item[1].atten << 12 |
table.item[2].channel << 8 |table.item[2].atten << 6 |
table.item[3].channel << 2 |table.item[3].atten);
WRITE_PERI_REG(ADC_SAR1_PATT_TAB1_REG + table_idx * 4, wdata);
}
void bootloader_random_enable(void)
{
// TODO: IDF-6522
ESP_EARLY_LOGW(TAG, "bootloader_random_enable() has not been implemented yet");
pattern_table sar1_table[4] = {};
uint32_t pattern_len = 0;
SET_PERI_REG_MASK(HP_SYS_CLKRST_SOC_CLK_CTRL2_REG, HP_SYS_CLKRST_REG_ADC_APB_CLK_EN);
SET_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL23_REG, HP_SYS_CLKRST_REG_ADC_CLK_EN);
SET_PERI_REG_MASK(RTCADC_MEAS1_MUX_REG, RTCADC_SAR1_DIG_FORCE);
SET_PERI_REG_MASK(PMU_RF_PWC_REG,PMU_XPD_PERIF_I2C);
uint32_t sar1_clk_div_num = GET_PERI_REG_BITS2((HP_SYS_CLKRST_PERI_CLK_CTRL24_REG),
(HP_SYS_CLKRST_REG_ADC_SAR1_CLK_DIV_NUM_M),
(HP_SYS_CLKRST_REG_ADC_SAR1_CLK_DIV_NUM_S));
SET_PERI_REG_MASK(ADC_CTRL_REG_REG, ADC_START_FORCE); //start force 1
adc1_fix_initcode_set(I2C_SAR_ADC_INIT_CODE_VAL);
// cfg pattern table
sar1_table[0].item[0].channel = 10; //rand() % 6;
sar1_table[0].item[0].atten = 3;
sar1_table[0].item[1].channel = 10;
sar1_table[0].item[1].atten = 3;
sar1_table[0].item[2].channel = 10;
sar1_table[0].item[2].atten = 3;
sar1_table[0].item[3].channel = 10;
sar1_table[0].item[3].atten = 3;
hpadc_sar1_pattern_table_cfg(0, sar1_table[0]);
SET_PERI_REG_BITS(ADC_CTRL_REG_REG, ADC_SAR1_PATT_LEN, pattern_len, ADC_SAR1_PATT_LEN_S);
SET_PERI_REG_BITS(ADC_CTRL_REG_REG, ADC_XPD_SAR1_FORCE, 3, ADC_XPD_SAR1_FORCE_S);
SET_PERI_REG_BITS(ADC_CTRL_REG_REG, ADC_XPD_SAR2_FORCE, 3, ADC_XPD_SAR2_FORCE_S);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_ENT_VDD_GRP1, 1);
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_DTEST_VDD_GRP1, 0);
SET_PERI_REG_BITS(RTCADC_READER1_CTRL_REG, RTCADC_SAR1_EN_PAD_FORCE_ENABLE, 3, RTCADC_SAR1_EN_PAD_FORCE_ENABLE_S);
CLEAR_PERI_REG_MASK(ADC_CTRL_REG_REG, ADC_START_FORCE);
SET_PERI_REG_MASK(ADC_CTRL2_REG, ADC_TIMER_EN);
SET_PERI_REG_BITS(ADC_CTRL2_REG, ADC_TIMER_TARGET, sar1_clk_div_num * 25, ADC_TIMER_TARGET_S);
while (GET_PERI_REG_MASK(ADC_INT_RAW_REG, ADC_SAR1_DONE_INT_RAW) == 0) { }
SET_PERI_REG_MASK(ADC_INT_CLR_REG, ADC_APB_SARADC1_DONE_INT_CLR);
}
void bootloader_random_disable(void)
{
// TODO: IDF-6522
ESP_EARLY_LOGW(TAG, "bootloader_random_enable() has not been implemented yet");
// No-op for now TODO IDF-6497
// ADC should be set to defaults here, once ADC API is implemented
// OR just keep this empty and let application continue to use RNG initialized by the bootloader
}

View File

@ -36,22 +36,13 @@
#elif defined CONFIG_IDF_TARGET_ESP32H2
#define APB_CYCLE_WAIT_NUM (96 * 16) /* Same reasoning as for ESP32C6, but the CPU frequency on ESP32H2 is
* 96MHz instead of 160 MHz */
#elif defined CONFIG_IDF_TARGET_ESP32P4
/* On ESP32P4, the RNG has been tested with around 75 KHz bytes reading frequency */
#define APB_CYCLE_WAIT_NUM (CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ * 14)
#else
#define APB_CYCLE_WAIT_NUM (16)
#endif
#if CONFIG_IDF_TARGET_ESP32P4
#include "esp_log.h"
static const char *TAG = "hw_random";
uint32_t IRAM_ATTR esp_random(void)
{
// TODO: IDF-6522
ESP_EARLY_LOGW(TAG, "esp_random() has not been implemented yet");
return 0xDEADBEEF;
}
#else // !CONFIG_IDF_TARGET_ESP32P4
uint32_t IRAM_ATTR esp_random(void)
{
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
@ -61,7 +52,7 @@ uint32_t IRAM_ATTR esp_random(void)
* clock cycles after reading previous word. This implementation may actually
* wait a bit longer due to extra time spent in arithmetic and branch statements.
*
* As a (probably unncessary) precaution to avoid returning the
* As a (probably unnecessary) precaution to avoid returning the
* RNG state as-is, the result is XORed with additional
* WDEV_RND_REG reads while waiting.
*/
@ -95,7 +86,6 @@ uint32_t IRAM_ATTR esp_random(void)
last_ccount = ccount;
return result ^ REG_READ(WDEV_RND_REG);
}
#endif //!CONFIG_IDF_TARGET_ESP32P4
void esp_fill_random(void *buf, size_t len)
{

View File

@ -461,11 +461,19 @@ void IRAM_ATTR call_start_cpu0(void)
#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
#endif //#if CONFIG_APP_BUILD_TYPE_RAM
#if CONFIG_IDF_TARGET_ESP32P4
#define RWDT_RESET RESET_REASON_CORE_RWDT
#define MWDT_RESET RESET_REASON_CORE_MWDT
#else
#define RWDT_RESET RESET_REASON_CORE_RTC_WDT
#define MWDT_RESET RESET_REASON_CORE_MWDT0
#endif
#ifndef CONFIG_BOOTLOADER_WDT_ENABLE
// from panic handler we can be reset by RWDT or TG0WDT
if (rst_reas[0] == RESET_REASON_CORE_RTC_WDT || rst_reas[0] == RESET_REASON_CORE_MWDT0
if (rst_reas[0] == RWDT_RESET || rst_reas[0] == MWDT_RESET
#if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
|| rst_reas[1] == RESET_REASON_CORE_RTC_WDT || rst_reas[1] == RESET_REASON_CORE_MWDT0
|| rst_reas[1] == RWDT_RESET || rst_reas[1] == MWDT_RESET
#endif
) {
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
@ -595,7 +603,7 @@ void IRAM_ATTR call_start_cpu0(void)
#elif CONFIG_IDF_TARGET_ESP32S3
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_CLKGATE_EN);
#if SOC_APPCPU_HAS_CLOCK_GATING_BUG
/* The clock gating signal of the App core is invalid. We use RUNSTALL and RESETING
/* The clock gating signal of the App core is invalid. We use RUNSTALL and RESETTING
signals to ensure that the App core stops running in single-core mode. */
REG_SET_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RUNSTALL);
REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETING);

View File

@ -239,6 +239,10 @@ config SOC_SPI_FLASH_SUPPORTED
bool
default y
config SOC_RNG_SUPPORTED
bool
default y
config SOC_GP_LDO_SUPPORTED
bool
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -21,3 +21,19 @@
#define I2C_SARADC_TSENS_DAC 0x6
#define I2C_SARADC_TSENS_DAC_MSB 3
#define I2C_SARADC_TSENS_DAC_LSB 0
#define I2C_SAR_ADC_SAR1_INIT_CODE_LSB 0
#define I2C_SAR_ADC_SAR1_INIT_CODE_LSB_MSB 7
#define I2C_SAR_ADC_SAR1_INIT_CODE_LSB_LSB 0
#define I2C_SAR_ADC_SAR1_INIT_CODE_MSB 1
#define I2C_SAR_ADC_SAR1_INIT_CODE_MSB_MSB 3
#define I2C_SAR_ADC_SAR1_INIT_CODE_MSB_LSB 0
#define I2C_SAR_ADC_ENT_VDD_GRP1 9
#define I2C_SAR_ADC_ENT_VDD_GRP1_MSB 4
#define I2C_SAR_ADC_ENT_VDD_GRP1_LSB 4
#define I2C_SAR_ADC_DTEST_VDD_GRP1 9
#define I2C_SAR_ADC_DTEST_VDD_GRP1_MSB 3
#define I2C_SAR_ADC_DTEST_VDD_GRP1_LSB 0

View File

@ -306,14 +306,14 @@ extern "C" {
#define RTCADC_COCPU_SARADC2_INT_RAW_V 0x00000001U
#define RTCADC_COCPU_SARADC2_INT_RAW_S 1
/** RTCADC_COCPU_SARADC1_ERROR_INT_RAW : R/WTC/SS; bitpos: [2]; default: 0;
* An errro occurs from ADC1, int raw.
* An error occurs from ADC1, int raw.
*/
#define RTCADC_COCPU_SARADC1_ERROR_INT_RAW (BIT(2))
#define RTCADC_COCPU_SARADC1_ERROR_INT_RAW_M (RTCADC_COCPU_SARADC1_ERROR_INT_RAW_V << RTCADC_COCPU_SARADC1_ERROR_INT_RAW_S)
#define RTCADC_COCPU_SARADC1_ERROR_INT_RAW_V 0x00000001U
#define RTCADC_COCPU_SARADC1_ERROR_INT_RAW_S 2
/** RTCADC_COCPU_SARADC2_ERROR_INT_RAW : R/WTC/SS; bitpos: [3]; default: 0;
* An errro occurs from ADC2, int raw.
* An error occurs from ADC2, int raw.
*/
#define RTCADC_COCPU_SARADC2_ERROR_INT_RAW (BIT(3))
#define RTCADC_COCPU_SARADC2_ERROR_INT_RAW_M (RTCADC_COCPU_SARADC2_ERROR_INT_RAW_V << RTCADC_COCPU_SARADC2_ERROR_INT_RAW_S)
@ -353,14 +353,14 @@ extern "C" {
#define RTCADC_COCPU_SARADC2_INT_ENA_V 0x00000001U
#define RTCADC_COCPU_SARADC2_INT_ENA_S 1
/** RTCADC_COCPU_SARADC1_ERROR_INT_ENA : R/WTC; bitpos: [2]; default: 0;
* An errro occurs from ADC1, int enable.
* An error occurs from ADC1, int enable.
*/
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA (BIT(2))
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_M (RTCADC_COCPU_SARADC1_ERROR_INT_ENA_V << RTCADC_COCPU_SARADC1_ERROR_INT_ENA_S)
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_V 0x00000001U
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_S 2
/** RTCADC_COCPU_SARADC2_ERROR_INT_ENA : R/WTC; bitpos: [3]; default: 0;
* An errro occurs from ADC2, int enable.
* An error occurs from ADC2, int enable.
*/
#define RTCADC_COCPU_SARADC2_ERROR_INT_ENA (BIT(3))
#define RTCADC_COCPU_SARADC2_ERROR_INT_ENA_M (RTCADC_COCPU_SARADC2_ERROR_INT_ENA_V << RTCADC_COCPU_SARADC2_ERROR_INT_ENA_S)
@ -400,14 +400,14 @@ extern "C" {
#define RTCADC_COCPU_SARADC2_INT_ST_V 0x00000001U
#define RTCADC_COCPU_SARADC2_INT_ST_S 1
/** RTCADC_COCPU_SARADC1_ERROR_INT_ST : RO; bitpos: [2]; default: 0;
* An errro occurs from ADC1, int status.
* An error occurs from ADC1, int status.
*/
#define RTCADC_COCPU_SARADC1_ERROR_INT_ST (BIT(2))
#define RTCADC_COCPU_SARADC1_ERROR_INT_ST_M (RTCADC_COCPU_SARADC1_ERROR_INT_ST_V << RTCADC_COCPU_SARADC1_ERROR_INT_ST_S)
#define RTCADC_COCPU_SARADC1_ERROR_INT_ST_V 0x00000001U
#define RTCADC_COCPU_SARADC1_ERROR_INT_ST_S 2
/** RTCADC_COCPU_SARADC2_ERROR_INT_ST : RO; bitpos: [3]; default: 0;
* An errro occurs from ADC2, int status.
* An error occurs from ADC2, int status.
*/
#define RTCADC_COCPU_SARADC2_ERROR_INT_ST (BIT(3))
#define RTCADC_COCPU_SARADC2_ERROR_INT_ST_M (RTCADC_COCPU_SARADC2_ERROR_INT_ST_V << RTCADC_COCPU_SARADC2_ERROR_INT_ST_S)
@ -447,14 +447,14 @@ extern "C" {
#define RTCADC_COCPU_SARADC2_INT_CLR_V 0x00000001U
#define RTCADC_COCPU_SARADC2_INT_CLR_S 1
/** RTCADC_COCPU_SARADC1_ERROR_INT_CLR : WT; bitpos: [2]; default: 0;
* An errro occurs from ADC1, int clear.
* An error occurs from ADC1, int clear.
*/
#define RTCADC_COCPU_SARADC1_ERROR_INT_CLR (BIT(2))
#define RTCADC_COCPU_SARADC1_ERROR_INT_CLR_M (RTCADC_COCPU_SARADC1_ERROR_INT_CLR_V << RTCADC_COCPU_SARADC1_ERROR_INT_CLR_S)
#define RTCADC_COCPU_SARADC1_ERROR_INT_CLR_V 0x00000001U
#define RTCADC_COCPU_SARADC1_ERROR_INT_CLR_S 2
/** RTCADC_COCPU_SARADC2_ERROR_INT_CLR : WT; bitpos: [3]; default: 0;
* An errro occurs from ADC2, int clear.
* An error occurs from ADC2, int clear.
*/
#define RTCADC_COCPU_SARADC2_ERROR_INT_CLR (BIT(3))
#define RTCADC_COCPU_SARADC2_ERROR_INT_CLR_M (RTCADC_COCPU_SARADC2_ERROR_INT_CLR_V << RTCADC_COCPU_SARADC2_ERROR_INT_CLR_S)
@ -494,14 +494,14 @@ extern "C" {
#define RTCADC_COCPU_SARADC2_INT_ENA_W1TS_V 0x00000001U
#define RTCADC_COCPU_SARADC2_INT_ENA_W1TS_S 1
/** RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TS : WT; bitpos: [2]; default: 0;
* An errro occurs from ADC1, write 1 to assert int enable.
* An error occurs from ADC1, write 1 to assert int enable.
*/
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TS (BIT(2))
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TS_M (RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TS_V << RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TS_S)
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TS_V 0x00000001U
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TS_S 2
/** RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TS : WT; bitpos: [3]; default: 0;
* An errro occurs from ADC2, write 1 to assert int enable.
* An error occurs from ADC2, write 1 to assert int enable.
*/
#define RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TS (BIT(3))
#define RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TS_M (RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TS_V << RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TS_S)
@ -541,14 +541,14 @@ extern "C" {
#define RTCADC_COCPU_SARADC2_INT_ENA_W1TC_V 0x00000001U
#define RTCADC_COCPU_SARADC2_INT_ENA_W1TC_S 1
/** RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TC : WT; bitpos: [2]; default: 0;
* An errro occurs from ADC1, write 1 to deassert int enable.
* An error occurs from ADC1, write 1 to deassert int enable.
*/
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TC (BIT(2))
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TC_M (RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TC_V << RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TC_S)
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TC_V 0x00000001U
#define RTCADC_COCPU_SARADC1_ERROR_INT_ENA_W1TC_S 2
/** RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TC : WT; bitpos: [3]; default: 0;
* An errro occurs from ADC2, write 1 to deassert int enable.
* An error occurs from ADC2, write 1 to deassert int enable.
*/
#define RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TC (BIT(3))
#define RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TC_M (RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TC_V << RTCADC_COCPU_SARADC2_ERROR_INT_ENA_W1TC_S)

View File

@ -85,7 +85,7 @@
#define SOC_WDT_SUPPORTED 1
#define SOC_SPI_FLASH_SUPPORTED 1
// #define SOC_TOUCH_SENSOR_SUPPORTED 1 //TODO: IDF-7477
// #define SOC_RNG_SUPPORTED 1 //TODO: IDF-6522
#define SOC_RNG_SUPPORTED 1
#define SOC_GP_LDO_SUPPORTED 1 // General purpose LDO
// #define SOC_PPA_SUPPORTED 1 //TODO: IDF-6878
#define SOC_LIGHT_SLEEP_SUPPORTED 1

View File

@ -9,6 +9,5 @@
#include "soc.h"
#include "soc/lpperi_reg.h"
//TODO: IDF-6522
/* Hardware random number generator register */
#define WDEV_RND_REG 0x600260b0
#define WDEV_RND_REG 0x501101a4