mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-23 01:05:14 +00:00
component/esp32 : fix dualcore bug
1. When dual core cpu run access DPORT register, must do protection. 2. If access DPORT register, must use DPORT_REG_READ/DPORT_REG_WRITE and DPORT_XXX register operation macro.
This commit is contained in:
@@ -149,6 +149,7 @@
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "esp_app_trace.h"
|
||||
#include "esp_dport_access.h"
|
||||
|
||||
#if CONFIG_ESP32_APPTRACE_ENABLE
|
||||
#define ESP_APPTRACE_DEBUG_STATS_ENABLE 0
|
||||
@@ -594,7 +595,7 @@ static esp_err_t esp_apptrace_trax_block_switch()
|
||||
// switch to new block
|
||||
s_trace_buf.trax.state.in_block++;
|
||||
|
||||
WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, new_block_num ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY);
|
||||
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, new_block_num ? TRACEMEM_MUX_BLK0_ONLY : TRACEMEM_MUX_BLK1_ONLY);
|
||||
eri_write(ESP_APPTRACE_TRAX_CTRL_REG, ESP_APPTRACE_TRAX_BLOCK_ID(s_trace_buf.trax.state.in_block) |
|
||||
host_connected | ESP_APPTRACE_TRAX_BLOCK_LEN(s_trace_buf.trax.state.markers[prev_block_num]));
|
||||
|
||||
@@ -736,12 +737,12 @@ static esp_err_t esp_apptrace_trax_dest_init()
|
||||
}
|
||||
s_trace_buf.trax.state.in_block = ESP_APPTRACE_TRAX_INBLOCK_START;
|
||||
|
||||
WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, DPORT_PRO_TRACEMEM_ENA_M);
|
||||
DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, DPORT_PRO_TRACEMEM_ENA_M);
|
||||
#if CONFIG_FREERTOS_UNICORE == 0
|
||||
WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_M);
|
||||
DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_M);
|
||||
#endif
|
||||
// Expose block 1 to host, block 0 is current trace input buffer
|
||||
WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK1_ONLY);
|
||||
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK1_ONLY);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_dport_access.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@@ -51,7 +52,7 @@ void esp_cache_err_int_init()
|
||||
// CPU.
|
||||
|
||||
if (core_id == PRO_CPU_NUM) {
|
||||
SET_PERI_REG_MASK(DPORT_CACHE_IA_INT_EN_REG,
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_CACHE_IA_INT_EN_REG,
|
||||
DPORT_CACHE_IA_INT_PRO_OPPOSITE |
|
||||
DPORT_CACHE_IA_INT_PRO_DRAM1 |
|
||||
DPORT_CACHE_IA_INT_PRO_DROM0 |
|
||||
@@ -59,7 +60,7 @@ void esp_cache_err_int_init()
|
||||
DPORT_CACHE_IA_INT_PRO_IRAM0 |
|
||||
DPORT_CACHE_IA_INT_PRO_IRAM1);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(DPORT_CACHE_IA_INT_EN_REG,
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_CACHE_IA_INT_EN_REG,
|
||||
DPORT_CACHE_IA_INT_APP_OPPOSITE |
|
||||
DPORT_CACHE_IA_INT_APP_DRAM1 |
|
||||
DPORT_CACHE_IA_INT_APP_DROM0 |
|
||||
@@ -80,7 +81,7 @@ int IRAM_ATTR esp_cache_err_get_cpuid()
|
||||
DPORT_PRO_CPU_DISABLED_CACHE_IA_IRAM1 |
|
||||
DPORT_APP_CPU_DISABLED_CACHE_IA_OPPOSITE;
|
||||
|
||||
if (GET_PERI_REG_MASK(DPORT_PRO_DCACHE_DBUG3_REG, pro_mask)) {
|
||||
if (DPORT_GET_PERI_REG_MASK(DPORT_PRO_DCACHE_DBUG3_REG, pro_mask)) {
|
||||
return PRO_CPU_NUM;
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ int IRAM_ATTR esp_cache_err_get_cpuid()
|
||||
DPORT_APP_CPU_DISABLED_CACHE_IA_IRAM1 |
|
||||
DPORT_PRO_CPU_DISABLED_CACHE_IA_OPPOSITE;
|
||||
|
||||
if (GET_PERI_REG_MASK(DPORT_APP_DCACHE_DBUG3_REG, app_mask)) {
|
||||
if (DPORT_GET_PERI_REG_MASK(DPORT_APP_DCACHE_DBUG3_REG, app_mask)) {
|
||||
return APP_CPU_NUM;
|
||||
}
|
||||
return -1;
|
||||
|
@@ -2,6 +2,10 @@
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
#ifdef IS_BOOTLOADER_BUILD
|
||||
CFLAGS += -DBOOTLOADER_BUILD
|
||||
#endif
|
||||
|
||||
COMPONENT_SRCDIRS := . hwcrypto
|
||||
LIBS := core rtc
|
||||
ifdef CONFIG_PHY_ENABLED # BT || WIFI
|
||||
|
@@ -49,6 +49,7 @@
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "esp_crosscore_int.h"
|
||||
#include "esp_dport_access.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "esp_newlib.h"
|
||||
@@ -142,10 +143,10 @@ void IRAM_ATTR call_start_cpu0()
|
||||
Cache_Read_Enable(1);
|
||||
esp_cpu_unstall(1);
|
||||
//Enable clock gating and reset the app cpu.
|
||||
SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL);
|
||||
SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
|
||||
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
|
||||
ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1);
|
||||
|
||||
while (!app_cpu_started) {
|
||||
@@ -153,7 +154,7 @@ void IRAM_ATTR call_start_cpu0()
|
||||
}
|
||||
#else
|
||||
ESP_EARLY_LOGI(TAG, "Single core mode");
|
||||
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
|
||||
#endif
|
||||
|
||||
/* Initialize heap allocator. WARNING: This *needs* to happen *after* the app cpu has booted.
|
||||
@@ -242,6 +243,9 @@ void start_cpu0_default(void)
|
||||
esp_cache_err_int_init();
|
||||
esp_crosscore_int_init();
|
||||
esp_ipc_init();
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
esp_dport_access_int_init();
|
||||
#endif
|
||||
spi_flash_init();
|
||||
/* init default OS-aware flash access critical section */
|
||||
spi_flash_guard_set(&g_flash_guard_default_ops);
|
||||
@@ -277,6 +281,7 @@ void start_cpu1_default(void)
|
||||
//has started, but it isn't active *on this CPU* yet.
|
||||
esp_cache_err_int_init();
|
||||
esp_crosscore_int_init();
|
||||
esp_dport_access_int_init();
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "Starting scheduler on APP CPU.");
|
||||
xPortStartScheduler();
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_dport_access.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/uart.h"
|
||||
@@ -51,9 +52,9 @@ static void IRAM_ATTR esp_crosscore_isr(void *arg) {
|
||||
|
||||
//Clear the interrupt first.
|
||||
if (xPortGetCoreID()==0) {
|
||||
WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
|
||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
|
||||
} else {
|
||||
WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
|
||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
|
||||
}
|
||||
//Grab the reason and clear it.
|
||||
portENTER_CRITICAL(&reasonSpinlock);
|
||||
@@ -90,9 +91,9 @@ void IRAM_ATTR esp_crosscore_int_send_yield(int coreId) {
|
||||
portEXIT_CRITICAL(&reasonSpinlock);
|
||||
//Poke the other CPU.
|
||||
if (coreId==0) {
|
||||
WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
|
||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
|
||||
} else {
|
||||
WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
|
||||
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include <sys/lock.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp_deep_sleep.h"
|
||||
#include "esp_dport_access.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_clk.h"
|
||||
#include "rom/cache.h"
|
||||
@@ -90,8 +91,8 @@ void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
|
||||
|
||||
void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) {
|
||||
/* Clear MMU for CPU 0 */
|
||||
REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
DPORT_REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
#if CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY > 0
|
||||
// ROM code has not started yet, so we need to set delay factor
|
||||
// used by ets_delay_us first.
|
||||
|
182
components/esp32/dport_access.c
Normal file
182
components/esp32/dport_access.c
Normal file
@@ -0,0 +1,182 @@
|
||||
// Copyright 2010-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
* DPORT access is used for do protection when dual core access DPORT internal register and APB register via DPORT simultaneously
|
||||
* This function will be initialize after FreeRTOS startup.
|
||||
* When cpu0 want to access DPORT register, it should notify cpu1 enter in high-priority interrupt for be mute. When cpu1 already in high-priority interrupt,
|
||||
* cpu0 can access DPORT register. Currently, cpu1 will wait for cpu0 finish access and exit high-priority interrupt.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr.h"
|
||||
#include "esp_dport_access.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/uart.h"
|
||||
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/spi_reg.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
#include "xtensa/core-macros.h"
|
||||
|
||||
static portMUX_TYPE g_dport_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
#define DPORT_CORE_STATE_IDLE 0
|
||||
#define DPORT_CORE_STATE_RUNNING 1
|
||||
static uint32_t volatile dport_core_state[portNUM_PROCESSORS]; //cpu is already run
|
||||
|
||||
/* these global variables are accessed from interrupt vector, hence not declared as static */
|
||||
uint32_t volatile dport_access_start[portNUM_PROCESSORS]; //dport register could be accessed
|
||||
uint32_t volatile dport_access_end[portNUM_PROCESSORS]; //dport register is accessed over
|
||||
|
||||
static uint32_t volatile dport_access_ref[portNUM_PROCESSORS]; //dport access reference
|
||||
|
||||
#ifdef DPORT_ACCESS_BENCHMARK
|
||||
#define DPORT_ACCESS_BENCHMARK_STORE_NUM
|
||||
static uint32_t ccount_start[portNUM_PROCESSORS];
|
||||
static uint32_t ccount_end[portNUM_PROCESSORS];
|
||||
static uint32_t ccount_margin[portNUM_PROCESSORS][DPORT_ACCESS_BENCHMARK_STORE_NUM];
|
||||
static uint32_t ccount_margin_cnt;
|
||||
#endif
|
||||
|
||||
/* stall other cpu that this cpu is pending to access dport register start */
|
||||
void IRAM_ATTR esp_dport_access_stall_other_cpu_start(void)
|
||||
{
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
int cpu_id = xPortGetCoreID();
|
||||
|
||||
if (dport_core_state[0] == DPORT_CORE_STATE_IDLE
|
||||
|| dport_core_state[1] == DPORT_CORE_STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DPORT_ACCESS_BENCHMARK
|
||||
ccount_start[cpu_id] = XTHAL_GET_CCOUNT();
|
||||
#endif
|
||||
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
if (dport_access_ref[cpu_id] == 0) {
|
||||
portENTER_CRITICAL_ISR(&g_dport_mux);
|
||||
|
||||
dport_access_start[cpu_id] = 0;
|
||||
dport_access_end[cpu_id] = 0;
|
||||
|
||||
if (cpu_id == 0) {
|
||||
WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_3_REG, DPORT_CPU_INTR_FROM_CPU_3); //interrupt on cpu1
|
||||
} else {
|
||||
WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_2_REG, DPORT_CPU_INTR_FROM_CPU_2); //interrupt on cpu0
|
||||
}
|
||||
|
||||
while (!dport_access_start[cpu_id]) {};
|
||||
|
||||
REG_READ(SPI_DATE_REG(3)); //just read a APB register sure that the APB-bus is idle
|
||||
}
|
||||
|
||||
dport_access_ref[cpu_id]++;
|
||||
#endif /* CONFIG_FREERTOS_UNICORE */
|
||||
}
|
||||
|
||||
/* stall other cpu that this cpu is pending to access dport register end */
|
||||
void IRAM_ATTR esp_dport_access_stall_other_cpu_end(void)
|
||||
{
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
int cpu_id = xPortGetCoreID();
|
||||
|
||||
if (dport_core_state[0] == DPORT_CORE_STATE_IDLE
|
||||
|| dport_core_state[1] == DPORT_CORE_STATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dport_access_ref[cpu_id] == 0) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
dport_access_ref[cpu_id]--;
|
||||
|
||||
if (dport_access_ref[cpu_id] == 0) {
|
||||
dport_access_end[cpu_id] = 1;
|
||||
|
||||
portEXIT_CRITICAL_ISR(&g_dport_mux);
|
||||
}
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
#ifdef DPORT_ACCESS_BENCHMARK
|
||||
ccount_end[cpu_id] = XTHAL_GET_CCOUNT();
|
||||
ccount_margin[cpu_id][ccount_margin_cnt] = ccount_end[cpu_id] - ccount_start[cpu_id];
|
||||
ccount_margin_cnt = (ccount_margin_cnt + 1)&(DPORT_ACCESS_BENCHMARK_STORE_NUM - 1);
|
||||
#endif
|
||||
#endif /* CONFIG_FREERTOS_UNICORE */
|
||||
}
|
||||
|
||||
static void dport_access_init_core0(void *arg)
|
||||
{
|
||||
int core_id = xPortGetCoreID();
|
||||
|
||||
assert(core_id == 0);
|
||||
|
||||
vPortCPUInitializeMutex(&g_dport_mux);
|
||||
|
||||
ESP_INTR_DISABLE(ETS_DPORT_INUM);
|
||||
intr_matrix_set(core_id, ETS_FROM_CPU_INTR2_SOURCE, ETS_DPORT_INUM);
|
||||
ESP_INTR_ENABLE(ETS_DPORT_INUM);
|
||||
|
||||
dport_access_ref[core_id] = 0;
|
||||
dport_access_start[core_id] = 0;
|
||||
dport_access_end[core_id] = 0;
|
||||
dport_core_state[core_id] = DPORT_CORE_STATE_RUNNING;
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void dport_access_init_core1(void *arg)
|
||||
{
|
||||
int core_id = xPortGetCoreID();
|
||||
|
||||
assert(core_id == 1);
|
||||
|
||||
ESP_INTR_DISABLE(ETS_DPORT_INUM);
|
||||
intr_matrix_set(core_id, ETS_FROM_CPU_INTR3_SOURCE, ETS_DPORT_INUM);
|
||||
ESP_INTR_ENABLE(ETS_DPORT_INUM);
|
||||
|
||||
dport_access_ref[core_id] = 0;
|
||||
dport_access_start[core_id] = 0;
|
||||
dport_access_end[core_id] = 0;
|
||||
dport_core_state[core_id] = DPORT_CORE_STATE_RUNNING;
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
/* This initialise should be really effective after vTaskStartScheduler */
|
||||
void esp_dport_access_int_init(void)
|
||||
{
|
||||
if (xPortGetCoreID() == 0) {
|
||||
xTaskCreatePinnedToCore(&dport_access_init_core0, "dport0", 512, NULL, 5, NULL, 0);
|
||||
} else {
|
||||
xTaskCreatePinnedToCore(&dport_access_init_core1, "dport1", 512, NULL, 5, NULL, 1);
|
||||
}
|
||||
}
|
@@ -29,6 +29,7 @@
|
||||
#include "hwcrypto/aes.h"
|
||||
#include "rom/aes.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp_dport_access.h"
|
||||
#include <sys/lock.h>
|
||||
|
||||
static _lock_t aes_lock;
|
||||
@@ -38,10 +39,10 @@ void esp_aes_acquire_hardware( void )
|
||||
/* newlib locks lazy initialize on ESP-IDF */
|
||||
_lock_acquire(&aes_lock);
|
||||
/* Enable AES hardware */
|
||||
REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
/* Clear reset on digital signature & secure boot units,
|
||||
otherwise AES unit is held in reset also. */
|
||||
REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||
DPORT_PERI_EN_AES
|
||||
| DPORT_PERI_EN_DIGITAL_SIGNATURE
|
||||
| DPORT_PERI_EN_SECUREBOOT);
|
||||
@@ -50,10 +51,10 @@ void esp_aes_acquire_hardware( void )
|
||||
void esp_aes_release_hardware( void )
|
||||
{
|
||||
/* Disable AES hardware */
|
||||
REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES);
|
||||
DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES);
|
||||
/* Don't return other units to reset, as this pulls
|
||||
reset on RSA & SHA units, respectively. */
|
||||
REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
_lock_release(&aes_lock);
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "rom/ets_sys.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "esp_dport_access.h"
|
||||
|
||||
inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) {
|
||||
return SHA_1_LOAD_REG + sha_type * 0x10;
|
||||
@@ -160,9 +161,9 @@ static void esp_sha_lock_engine_inner(sha_engine_state *engine)
|
||||
|
||||
if (sha_engines_all_idle()) {
|
||||
/* Enable SHA hardware */
|
||||
REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
/* also clear reset on secure boot, otherwise SHA is held in reset */
|
||||
REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||
DPORT_REG_CLR_BIT(DPORT_PERI_RST_EN_REG,
|
||||
DPORT_PERI_EN_SHA
|
||||
| DPORT_PERI_EN_SECUREBOOT);
|
||||
ets_sha_enable();
|
||||
@@ -187,8 +188,8 @@ void esp_sha_unlock_engine(esp_sha_type sha_type)
|
||||
if (sha_engines_all_idle()) {
|
||||
/* Disable SHA hardware */
|
||||
/* Don't assert reset on secure boot, otherwise AES is held in reset */
|
||||
REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
|
||||
REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
DPORT_REG_SET_BIT(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
|
||||
DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
}
|
||||
|
||||
_lock_release(&state_change_lock);
|
||||
|
109
components/esp32/include/esp_dport_access.h
Normal file
109
components/esp32/include/esp_dport_access.h
Normal file
@@ -0,0 +1,109 @@
|
||||
// Copyright 2010-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESP_DPORT_ACCESS_H_
|
||||
#define _ESP_DPORT_ACCESS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void esp_dport_access_stall_other_cpu_start(void);
|
||||
void esp_dport_access_stall_other_cpu_end(void);
|
||||
void esp_dport_access_int_init(void);
|
||||
|
||||
#if defined(BOOTLOADER_BUILD) || defined(CONFIG_FREERTOS_UNICORE)
|
||||
#define DPORT_STAL_OTHER_CPU_START()
|
||||
#define DPORT_STAL_OTHER_CPU_END()
|
||||
#else
|
||||
#define DPORT_STAL_OTHER_CPU_START() esp_dport_access_stall_other_cpu_start()
|
||||
#define DPORT_STAL_OTHER_CPU_END() esp_dport_access_stall_other_cpu_end()
|
||||
#endif
|
||||
|
||||
#define IS_DPORT_REG(_r) (((_r) >= DR_REG_DPORT_BASE) && (_r) <= DPORT_DATE_REG)
|
||||
|
||||
//Registers Operation {{
|
||||
|
||||
#define _REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v)
|
||||
#define _REG_READ(_r) (*(volatile uint32_t *)(_r))
|
||||
//write value to register
|
||||
#define DPORT_REG_WRITE(_r, _v) {DPORT_STAL_OTHER_CPU_START(); (*(volatile uint32_t *)(_r)) = (_v); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//read value from register
|
||||
#define DPORT_REG_READ(_r) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (*(volatile uint32_t *)(_r)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//get bit or get bits from register
|
||||
#define DPORT_REG_GET_BIT(_r, _b) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (*(volatile uint32_t*)(_r) & (_b)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//set bit or set bits to register
|
||||
#define DPORT_REG_SET_BIT(_r, _b) {DPORT_STAL_OTHER_CPU_START(); (*(volatile uint32_t*)(_r) |= (_b)); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//clear bit or clear bits of register
|
||||
#define DPORT_REG_CLR_BIT(_r, _b) {DPORT_STAL_OTHER_CPU_START(); (*(volatile uint32_t*)(_r) &= ~(_b)); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//set bits of register controlled by mask
|
||||
#define DPORT_REG_SET_BITS(_r, _b, _m) {DPORT_STAL_OTHER_CPU_START(); (*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m))); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//get field from register, uses field _S & _V to determine mask
|
||||
#define DPORT_REG_GET_FIELD(_r, _f) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = ((_REG_READ(_r) >> (_f##_S)) & (_f##_V)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//set field to register, used when _f is not left shifted by _f##_S
|
||||
#define DPORT_REG_SET_FIELD(_r, _f, _v) {DPORT_STAL_OTHER_CPU_START(); (_REG_WRITE((_r),((_REG_READ(_r) & ~((_f) << (_f##_S)))|(((_v) & (_f))<<(_f##_S))))); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//get field value from a variable, used when _f is not left shifted by _f##_S
|
||||
#define DPORT_VALUE_GET_FIELD(_r, _f) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (((_r) >> (_f##_S)) & (_f)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//get field value from a variable, used when _f is left shifted by _f##_S
|
||||
#define DPORT_VALUE_GET_FIELD2(_r, _f) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (((_r) & (_f))>> (_f##_S)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//set field value to a variable, used when _f is not left shifted by _f##_S
|
||||
#define DPORT_VALUE_SET_FIELD(_r, _f, _v) {DPORT_STAL_OTHER_CPU_START(); ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S)))); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//set field value to a variable, used when _f is left shifted by _f##_S
|
||||
#define DPORT_VALUE_SET_FIELD2(_r, _f, _v) {DPORT_STAL_OTHER_CPU_START(); ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S)))); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//generate a value from a field value, used when _f is not left shifted by _f##_S
|
||||
#define DPORT_FIELD_TO_VALUE(_f, _v) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (((_v)&(_f))<<_f##_S); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//generate a value from a field value, used when _f is left shifted by _f##_S
|
||||
#define DPORT_FIELD_TO_VALUE2(_f, _v) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (((_v)<<_f##_S) & (_f)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
#define _READ_PERI_REG(addr) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr)))
|
||||
#define _WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val)
|
||||
|
||||
//read value from register
|
||||
#define DPORT_READ_PERI_REG(addr) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//write value to register
|
||||
#define DPORT_WRITE_PERI_REG(addr, val) {DPORT_STAL_OTHER_CPU_START(); (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//clear bits of register controlled by mask
|
||||
#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) {DPORT_STAL_OTHER_CPU_START(); _WRITE_PERI_REG((reg), (_READ_PERI_REG(reg)&(~(mask)))); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//set bits of register controlled by mask
|
||||
#define DPORT_SET_PERI_REG_MASK(reg, mask) {DPORT_STAL_OTHER_CPU_START(); _WRITE_PERI_REG((reg), (_READ_PERI_REG(reg)|(mask))); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//get bits of register controlled by mask
|
||||
#define DPORT_GET_PERI_REG_MASK(reg, mask) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = (_READ_PERI_REG(reg) & (mask)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//get bits of register controlled by highest bit and lowest bit
|
||||
#define DPORT_GET_PERI_REG_BITS(reg, hipos,lowpos) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = ((_READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
|
||||
//set bits of register controlled by mask and shift
|
||||
#define DPORT_SET_PERI_REG_BITS(reg,bit_map,value,shift) {DPORT_STAL_OTHER_CPU_START(); (_WRITE_PERI_REG((reg),(_READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & bit_map)<<(shift)) )); DPORT_STAL_OTHER_CPU_END();}
|
||||
|
||||
//get field of register
|
||||
#define DPORT_GET_PERI_REG_BITS2(reg, mask,shift) ({uint32_t val; DPORT_STAL_OTHER_CPU_START(); val = ((_READ_PERI_REG(reg)>>(shift))&(mask)); DPORT_STAL_OTHER_CPU_END(); val;})
|
||||
//}}
|
||||
|
||||
|
||||
#endif /* _ESP_DPORT_ACCESS_H_ */
|
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_phy_init.h"
|
||||
#include "esp_dport_access.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs.h"
|
||||
@@ -52,7 +53,7 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data,
|
||||
_lock_acquire(&s_phy_rf_init_lock);
|
||||
if (s_phy_rf_init_count == 0) {
|
||||
// Enable WiFi peripheral clock
|
||||
SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN | DPORT_WIFI_CLK_RNG_EN);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN | DPORT_WIFI_CLK_RNG_EN);
|
||||
ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d",
|
||||
init_data, calibration_data, mode);
|
||||
phy_set_wifi_mode_only(0);
|
||||
@@ -77,7 +78,7 @@ esp_err_t esp_phy_rf_deinit(void)
|
||||
// Disable PHY and RF.
|
||||
phy_close_rf();
|
||||
// Disable WiFi peripheral clock. Do not disable clock for hardware RNG
|
||||
CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN);
|
||||
} else {
|
||||
#if CONFIG_SW_COEXIST_ENABLE
|
||||
coex_deinit();
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_wifi_internal.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_dport_access.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "rom/cache.h"
|
||||
@@ -270,17 +271,17 @@ void IRAM_ATTR esp_restart_noos()
|
||||
uart_tx_wait_idle(2);
|
||||
|
||||
// Reset wifi/bluetooth/ethernet/sdio (bb/mac)
|
||||
SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG,
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG,
|
||||
DPORT_BB_RST | DPORT_FE_RST | DPORT_MAC_RST |
|
||||
DPORT_BT_RST | DPORT_BTMAC_RST | DPORT_SDIO_RST |
|
||||
DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST |
|
||||
DPORT_RW_BTMAC_RST | DPORT_RW_BTLP_RST);
|
||||
REG_WRITE(DPORT_CORE_RST_EN_REG, 0);
|
||||
DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0);
|
||||
|
||||
// Reset timer/spi/uart
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,
|
||||
DPORT_TIMERS_RST | DPORT_SPI_RST_1 | DPORT_UART_RST);
|
||||
REG_WRITE(DPORT_PERIP_RST_EN_REG, 0);
|
||||
DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0);
|
||||
|
||||
// Set CPU back to XTAL source, no PLL, same as hard reset
|
||||
rtc_clk_cpu_freq_set(RTC_CPU_FREQ_XTAL);
|
||||
|
@@ -21,6 +21,8 @@
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
|
||||
#include "esp_dport_access.h"
|
||||
|
||||
|
||||
#define DPORT_I2S0_CLK_EN (BIT(4))
|
||||
#define DPORT_I2S0_RST (BIT(4))
|
||||
@@ -34,8 +36,8 @@ the point where they happened to do what I want.
|
||||
|
||||
static void lcdIfaceInit()
|
||||
{
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
|
||||
//Init pins to i2s functions
|
||||
SET_PERI_REG_MASK(GPIO_ENABLE_W1TS_REG, (1 << 11) | (1 << 3) | (1 << 0) | (1 << 2) | (1 << 5) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); //ENABLE GPIO oe_enable
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
|
||||
#include "esp_dport_access.h"
|
||||
|
||||
#define DPORT_I2S0_CLK_EN (BIT(4))
|
||||
#define DPORT_I2S0_RST (BIT(4))
|
||||
@@ -32,8 +33,8 @@ static volatile lldesc_t dmaDesc[2];
|
||||
static void dmaMemcpy(void *in, void *out, int len)
|
||||
{
|
||||
volatile int i;
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
|
||||
//Init pins to i2s functions
|
||||
SET_PERI_REG_MASK(GPIO_ENABLE_W1TS_REG, (1 << 11) | (1 << 3) | (1 << 0) | (1 << 2) | (1 << 5) | (1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); //ENABLE GPIO oe_enable
|
||||
|
Reference in New Issue
Block a user