components/os: add config option to choose system check intterupt level.

This commit is contained in:
baohongde 2021-09-02 21:10:29 +08:00 committed by bot
parent 8a4696d25a
commit 6d63fe06fa
4 changed files with 169 additions and 58 deletions

View File

@ -462,5 +462,21 @@ menu "ESP System Settings"
Debug stubs are used by OpenOCD to execute pre-compiled onboard code
which does some useful debugging stuff, e.g. GCOV data dump.
choice ESP_SYSTEM_CHECK_INT_LEVEL
prompt "Interrupt level to use for Interrupt Watchdog and other system checks"
default ESP_SYSTEM_CHECK_INT_LEVEL_5
help
Interrupt level to use for Interrupt Watchdog and other system checks.
config ESP_SYSTEM_CHECK_INT_LEVEL_5
bool "Level 5 interrupt"
help
Using level 5 interrupt for Interrupt Watchdog and other system checks.
config ESP_SYSTEM_CHECK_INT_LEVEL_4
bool "Level 4 interrupt"
help
Using level 4 interrupt for Interrupt Watchdog and other system checks.
endchoice
endmenu # ESP System Settings

View File

@ -51,7 +51,7 @@ static wdt_hal_context_t iwdt_context;
*/
#define IWDT_LIVELOCK_TIMEOUT_MS (20)
extern uint32_t _l5_intr_livelock_counter, _l5_intr_livelock_max;
extern uint32_t _lx_intr_livelock_counter, _lx_intr_livelock_max;
#endif
//Take care: the tick hook can also be called before esp_int_wdt_init() is called.
@ -70,9 +70,9 @@ static void IRAM_ATTR tick_hook(void)
wdt_hal_write_protect_disable(&iwdt_context);
//Reconfigure stage timeouts
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX
_l5_intr_livelock_counter = 0;
_lx_intr_livelock_counter = 0;
wdt_hal_config_stage(&iwdt_context, WDT_STAGE0,
CONFIG_ESP_INT_WDT_TIMEOUT_MS * 1000 / IWDT_TICKS_PER_US / (_l5_intr_livelock_max + 1), WDT_STAGE_ACTION_INT); //Set timeout before interrupt
CONFIG_ESP_INT_WDT_TIMEOUT_MS * 1000 / IWDT_TICKS_PER_US / (_lx_intr_livelock_max + 1), WDT_STAGE_ACTION_INT); //Set timeout before interrupt
#else
wdt_hal_config_stage(&iwdt_context, WDT_STAGE0, CONFIG_ESP_INT_WDT_TIMEOUT_MS * 1000 / IWDT_TICKS_PER_US, WDT_STAGE_ACTION_INT); //Set timeout before interrupt
#endif
@ -168,11 +168,11 @@ void esp_int_wdt_cpu_init(void)
* This is a workaround for issue 3.15 in "ESP32 ECO and workarounds for
* Bugs" document.
*/
_l5_intr_livelock_counter = 0;
_lx_intr_livelock_counter = 0;
if (soc_has_cache_lock_bug()) {
assert((portTICK_PERIOD_MS << 1) <= IWDT_LIVELOCK_TIMEOUT_MS);
assert(CONFIG_ESP_INT_WDT_TIMEOUT_MS >= (IWDT_LIVELOCK_TIMEOUT_MS * 3));
_l5_intr_livelock_max = CONFIG_ESP_INT_WDT_TIMEOUT_MS / IWDT_LIVELOCK_TIMEOUT_MS - 1;
_lx_intr_livelock_max = CONFIG_ESP_INT_WDT_TIMEOUT_MS / IWDT_LIVELOCK_TIMEOUT_MS - 1;
}
#endif

View File

@ -33,10 +33,29 @@ Interrupt , a high-priority interrupt, is used for several things:
*/
#define L5_INTR_STACK_SIZE 12
#define L5_INTR_A2_OFFSET 0
#define L5_INTR_A3_OFFSET 4
#define L5_INTR_A4_OFFSET 8
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
#define LX_INTR_STACK_SIZE 12
#define LX_INTR_A2_OFFSET 0
#define LX_INTR_A3_OFFSET 4
#define LX_INTR_A4_OFFSET 8
#define EPC_X EPC_5
#define EXCSAVE_X EXCSAVE_5
#define RFI_X 5
#define xt_highintx xt_highint5
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
#define LX_INTR_STACK_SIZE 12
#define LX_INTR_A2_OFFSET 0
#define LX_INTR_A3_OFFSET 4
#define LX_INTR_A4_OFFSET 8
#define EPC_X EPC_4
#define EXCSAVE_X EXCSAVE_4
#define RFI_X 4
#define xt_highintx xt_highint4
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
/*
--------------------------------------------------------------------------------
@ -79,7 +98,7 @@ Interrupt , a high-priority interrupt, is used for several things:
movi a3, TIMG_WDT_WKEY_VALUE
s32i a3, a2, TIMG1_WDTWPROTECT_OFFSET /* disable write protect */
memw
movi a4, _l5_intr_livelock_max
movi a4, _lx_intr_livelock_max
l32i a4, a4, 0
memw
addi a4, a4, 1
@ -123,30 +142,30 @@ Interrupt , a high-priority interrupt, is used for several things:
.endm
.data
_l5_intr_stack:
.space L5_INTR_STACK_SIZE*portNUM_PROCESSORS /* This allocates stacks for each individual CPU. */
_lx_intr_stack:
.space LX_INTR_STACK_SIZE*portNUM_PROCESSORS /* This allocates stacks for each individual CPU. */
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT
.global _l5_intr_livelock_counter
.global _l5_intr_livelock_max
.global _lx_intr_livelock_counter
.global _lx_intr_livelock_max
.align 16
_l5_intr_livelock_counter:
_lx_intr_livelock_counter:
.word 0
_l5_intr_livelock_max:
_lx_intr_livelock_max:
.word 0
_l5_intr_livelock_sync:
_lx_intr_livelock_sync:
.word 0, 0
_l5_intr_livelock_app:
_lx_intr_livelock_app:
.word 0
_l5_intr_livelock_pro:
_lx_intr_livelock_pro:
.word 0
#endif
.section .iram1,"ax"
.global xt_highint5
.type xt_highint5,@function
.global xt_highintx
.type xt_highintx,@function
.align 4
xt_highint5:
xt_highintx:
#ifndef CONFIG_FREERTOS_UNICORE
/* See if we're here for the IPC_ISR interrupt */
@ -166,15 +185,21 @@ xt_highint5:
extui a0, a0, 16, 1
bnez a0, .handle_multicore_debug_int
1:
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
get_int_status_tg1wdt a0
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
/* See if we're here for the tg1 watchdog interrupt */
rsr a0, INTERRUPT
extui a0, a0, ETS_T1_WDT_INUM, 1
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
beqz a0, 1f
wsr a5, depc /* use DEPC as temp storage */
movi a0, _l5_intr_livelock_counter
movi a0, _lx_intr_livelock_counter
l32i a0, a0, 0
movi a5, _l5_intr_livelock_max
movi a5, _lx_intr_livelock_max
l32i a5, a5, 0
bltu a0, a5, .handle_livelock_int /* _l5_intr_livelock_counter < _l5_intr_livelock_max */
bltu a0, a5, .handle_livelock_int /* _lx_intr_livelock_counter < _lx_intr_livelock_max */
rsr a5, depc /* restore a5 */
#endif
@ -189,7 +214,7 @@ xt_highint5:
#endif
rsr a0, PS /* save interruptee's PS */
s32i a0, sp, XT_STK_PS
rsr a0, EPC_5 /* save interruptee's PC */
rsr a0, EPC_X /* save interruptee's PC */
s32i a0, sp, XT_STK_PC
#if XCHAL_HAVE_WINDOWED
s32e a0, sp, -16 /* for debug backtrace */
@ -203,11 +228,16 @@ xt_highint5:
s32i a0, sp, XT_STK_EXCVADDR
/* Figure out reason, save into EXCCAUSE reg */
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
get_int_status_tg1wdt a0
bnez a0, 1f
/* TODO: Clear the MEMACCESS_ERR interrupt status. */
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
rsr a0, INTERRUPT
extui a0, a0, ETS_MEMACCESS_ERR_INUM, 1 /* get cacheerr int bit */
beqz a0, 1f
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
/* Kill this interrupt; we cannot reset it. */
rsr a0, INTENABLE
@ -217,8 +247,10 @@ xt_highint5:
movi a0, PANIC_RSN_CACHEERR
j 9f
1:
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
/* Clear the WDT interrupt status. */
wdt_clr_intr_status TIMERG1
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
#if CONFIG_ESP_INT_WDT_CHECK_CPU1
/* Check if the cause is the app cpu failing to tick.*/
movi a0, int_wdt_app_cpu_ticked
@ -236,7 +268,7 @@ xt_highint5:
s32i a0, sp, XT_STK_EXCCAUSE
/* _xt_context_save seems to save the current a0, but we need the interuptees a0. Fix this. */
rsr a0, EXCSAVE_5 /* save interruptee's a0 */
rsr a0, EXCSAVE_X /* save interruptee's a0 */
s32i a0, sp, XT_STK_A0
@ -252,13 +284,13 @@ xt_highint5:
l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
wsr a0, PS
l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
wsr a0, EPC_5
wsr a0, EPC_X
l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
l32i sp, sp, XT_STK_A1 /* remove exception frame */
rsync /* ensure PS and EPC written */
rsr a0, EXCSAVE_5 /* restore a0 */
rfi 5
rsr a0, EXCSAVE_X /* restore a0 */
rfi RFI_X
#if CONFIG_ESP32_ECO3_CACHE_LOCK_FIX && CONFIG_ESP_INT_WDT
@ -304,7 +336,7 @@ xt_highint5:
rsr a2, depc
rsr a0, EXCSAVE_5 /* restore a0 */
rsr a0, EXCSAVE_X /* restore a0 */
rfi 5
/*
@ -334,13 +366,13 @@ xt_highint5:
getcoreid a5
/* Save A2, A3, A4 so we can use those registers */
movi a0, L5_INTR_STACK_SIZE
movi a0, LX_INTR_STACK_SIZE
mull a5, a5, a0
movi a0, _l5_intr_stack
movi a0, _lx_intr_stack
add a0, a0, a5
s32i a2, a0, L5_INTR_A2_OFFSET
s32i a3, a0, L5_INTR_A3_OFFSET
s32i a4, a0, L5_INTR_A4_OFFSET
s32i a2, a0, LX_INTR_A2_OFFSET
s32i a3, a0, LX_INTR_A3_OFFSET
s32i a4, a0, LX_INTR_A4_OFFSET
/* Here, we can use a0, a2, a3, a4, a5 registers */
getcoreid a5
@ -348,18 +380,18 @@ xt_highint5:
rsil a0, CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL /* disable nested interrupt */
beqz a5, 1f
movi a2, _l5_intr_livelock_app
movi a2, _lx_intr_livelock_app
l32i a3, a2, 0
addi a3, a3, 1
s32i a3, a2, 0
/* Dual core synchronization, ensuring that both cores enter interrupts */
1: movi a4, 0x1
movi a2, _l5_intr_livelock_sync
movi a2, _lx_intr_livelock_sync
addx4 a3, a5, a2
s32i a4, a3, 0
1: movi a2, _l5_intr_livelock_sync
1: movi a2, _lx_intr_livelock_sync
movi a3, 1
addx4 a3, a3, a2
l32i a2, a2, 0
@ -369,10 +401,10 @@ xt_highint5:
beqz a5, 1f /* Pro cpu (Core 0) jump bypass */
movi a2, _l5_intr_livelock_app
movi a2, _lx_intr_livelock_app
l32i a2, a2, 0
bnei a2, 2, 1f
movi a2, _l5_intr_livelock_counter /* _l5_intr_livelock_counter++ */
movi a2, _lx_intr_livelock_counter /* _lx_intr_livelock_counter++ */
l32i a3, a2, 0
addi a3, a3, 1
s32i a3, a2, 0
@ -421,17 +453,17 @@ xt_highint5:
bltu a4, a3, 2b
beqz a5, 2f
movi a2, _l5_intr_livelock_app
movi a2, _lx_intr_livelock_app
l32i a2, a2, 0
beqi a2, 2, 8f
j 3f
2: movi a2, _l5_intr_livelock_pro
2: movi a2, _lx_intr_livelock_pro
l32i a4, a2, 0
addi a4, a4, 1
s32i a4, a2, 0
movi a2, _l5_intr_livelock_sync
movi a2, _lx_intr_livelock_sync
movi a3, 1
addx4 a3, a3, a2
l32i a2, a2, 0
@ -445,7 +477,7 @@ xt_highint5:
/*
Pro cpu (Core 0) jump bypass, continue waiting, App cpu (Core 1)
can execute to here, unmap itself tg1 1st stage timeout interrupt
then restore registers and exit highint5.
then restore registers and exit highint5/4.
*/
3: intr_matrix_map DPORT_APP_MAC_INTR_MAP_REG, ETS_TG1_WDT_LEVEL_INTR_SOURCE, 16
j 9f
@ -456,13 +488,13 @@ xt_highint5:
*/
4: intr_matrix_map DPORT_APP_MAC_INTR_MAP_REG, ETS_TG1_WDT_LEVEL_INTR_SOURCE, ETS_T1_WDT_INUM
1: movi a2, _l5_intr_livelock_sync
1: movi a2, _lx_intr_livelock_sync
movi a4, 1
addx4 a3, a4, a2
l32i a2, a2, 0
l32i a3, a3, 0
and a2, a2, a3
beqz a2, 1b /* Wait for App cpu to enter highint5 again */
beqz a2, 1b /* Wait for App cpu to enter highint5/4 again */
wdt_clr_intr_status TIMERG1
j 9f
@ -474,32 +506,32 @@ xt_highint5:
movi a0, 0
beqz a5, 1f
movi a2, _l5_intr_livelock_app
movi a2, _lx_intr_livelock_app
l32i a3, a2, 0
bnei a3, 2, 1f
s32i a0, a2, 0
1: bnez a5, 2f
movi a2, _l5_intr_livelock_pro
movi a2, _lx_intr_livelock_pro
s32i a0, a2, 0
2: movi a2, _l5_intr_livelock_sync
2: movi a2, _lx_intr_livelock_sync
addx4 a2, a5, a2
s32i a0, a2, 0
/* Done. Restore registers and return. */
movi a0, L5_INTR_STACK_SIZE
movi a0, LX_INTR_STACK_SIZE
mull a5, a5, a0
movi a0, _l5_intr_stack
movi a0, _lx_intr_stack
add a0, a0, a5
l32i a2, a0, L5_INTR_A2_OFFSET
l32i a3, a0, L5_INTR_A3_OFFSET
l32i a4, a0, L5_INTR_A4_OFFSET
l32i a2, a0, LX_INTR_A2_OFFSET
l32i a3, a0, LX_INTR_A3_OFFSET
l32i a4, a0, LX_INTR_A4_OFFSET
rsync /* ensure register restored */
rsr a5, depc
rsr a0, EXCSAVE_5 /* restore a0 */
rfi 5
rsr a0, EXCSAVE_X /* restore a0 */
rfi RFI_X
#endif

View File

@ -351,6 +351,7 @@
#define ETS_CACHE_IA_INTR_SOURCE 68/**< interrupt of Cache Invalied Access, LEVEL*/
#define ETS_MAX_INTR_SOURCE 69/**< total number of interrupt sources*/
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
//interrupt cpu using table, Please see the core-isa.h
/*************************************************************************************************************
* Intr num Level Type PRO CPU usage APP CPU uasge
@ -410,3 +411,65 @@
//Invalid interrupt for number interrupt matrix
#define ETS_INVALID_INUM 6
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
//interrupt cpu using table, Please see the core-isa.h
/*************************************************************************************************************
* Intr num Level Type PRO CPU usage APP CPU uasge
* 0 1 extern level WMAC Reserved
* 1 1 extern level BT/BLE Host HCI DMA BT/BLE Host HCI DMA
* 2 1 extern level
* 3 1 extern level
* 4 1 extern level WBB
* 5 1 extern level BT/BLE Controller BT/BLE Controller
* 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1)
* 7 1 software BT/BLE VHCI BT/BLE VHCI
* 8 1 extern level BT/BLE BB(RX/TX) BT/BLE BB(RX/TX)
* 9 1 extern level
* 10 1 extern edge
* 11 3 profiling
* 12 1 extern level
* 13 1 extern level
* 14 7 nmi Reserved Reserved
* 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3)
* 16 5 timer
* 17 1 extern level
* 18 1 extern level
* 19 2 extern level
* 20 2 extern level
* 21 2 extern level
* 22 3 extern edge
* 23 3 extern level
* 24 4 extern level TG1_WDT
* 25 4 extern level CACHEERR
* 26 5 extern level
* 27 3 extern level Reserved Reserved
* 28 4 extern edge IPC_ISR IPC_ISR
* 29 3 software Reserved Reserved
* 30 4 extern edge Reserved Reserved
* 31 5 extern level
*************************************************************************************************************
*/
//CPU0 Interrupt number reserved, not touch this.
#define ETS_WMAC_INUM 0
#define ETS_BT_HOST_INUM 1
#define ETS_WBB_INUM 4
#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/
#define ETS_FRC1_INUM 22
#define ETS_T1_WDT_INUM 24
#define ETS_MEMACCESS_ERR_INUM 25
/* backwards compatibility only, use ETS_MEMACCESS_ERR_INUM instead*/
#define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM
#define ETS_IPC_ISR_INUM 28
//CPU0 Interrupt number used in ROM, should be cancelled in SDK
#define ETS_SLC_INUM 1
#define ETS_UART0_INUM 5
#define ETS_UART1_INUM 5
//Other interrupt number should be managed by the user
//Invalid interrupt for number interrupt matrix
#define ETS_INVALID_INUM 6
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */