mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-24 17:27:21 +00:00
feat(esp_system): implement hw stack guard for riscv chips
- add hardware stack guard based on assist-debug module - enable hardware stack guard by default - disable hardware stack guard for freertos ci.release test - refactor rtos_int_enter/rtos_int_exit to change SP register inside them - fix panic_reason.h header for RISC-V - update docs to include information about the new feature
This commit is contained in:
@@ -35,9 +35,17 @@
|
||||
#ifndef PORTMACRO_H
|
||||
#define PORTMACRO_H
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* Macros used instead ofsetoff() for better performance of interrupt handler */
|
||||
#define PORT_OFFSET_PX_STACK 0x30
|
||||
#define PORT_OFFSET_PX_END_OF_STACK (PORT_OFFSET_PX_STACK + \
|
||||
/* void * pxDummy6 */ 4 + \
|
||||
/* uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ] */ CONFIG_FREERTOS_MAX_TASK_NAME_LEN + \
|
||||
/* BaseType_t xDummyCoreID */ 4)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
@@ -58,6 +58,17 @@
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
_Static_assert(portBYTE_ALIGNMENT == 16, "portBYTE_ALIGNMENT must be set to 16");
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/**
|
||||
* offsetof() can not be used in asm code. Then we need make sure that
|
||||
* PORT_OFFSET_PX_STACK and PORT_OFFSET_PX_END_OF_STACK have expected values.
|
||||
* Macro used in the portasm.S instead of variables to save at least 4 instruction calls
|
||||
* which accessing DRAM memory. This optimization saves CPU time in the interrupt handling.
|
||||
*/
|
||||
|
||||
_Static_assert(offsetof( StaticTask_t, pxDummy6 ) == PORT_OFFSET_PX_STACK);
|
||||
_Static_assert(offsetof( StaticTask_t, pxDummy8 ) == PORT_OFFSET_PX_END_OF_STACK);
|
||||
#endif // CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
|
||||
/* ---------------------------------------------------- Variables ------------------------------------------------------
|
||||
*
|
||||
@@ -74,7 +85,7 @@ static UBaseType_t uxSavedInterruptState = 0;
|
||||
BaseType_t uxSchedulerRunning = 0; // Duplicate of xSchedulerRunning, accessible to port files
|
||||
UBaseType_t uxInterruptNesting = 0;
|
||||
BaseType_t xPortSwitchFlag = 0;
|
||||
__attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE];
|
||||
__attribute__((aligned(16))) StackType_t xIsrStack[configISR_STACK_SIZE];
|
||||
StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK)));
|
||||
|
||||
|
||||
|
@@ -3,6 +3,11 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "portmacro.h"
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
#include "esp_private/hw_stack_guard.h"
|
||||
#endif
|
||||
|
||||
.global uxInterruptNesting
|
||||
.global uxSchedulerRunning
|
||||
@@ -10,23 +15,26 @@
|
||||
.global pxCurrentTCB
|
||||
.global vTaskSwitchContext
|
||||
.global xPortSwitchFlag
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
.global xIsrStack
|
||||
.global port_offset_pxStack
|
||||
.global port_offset_pxEndOfStack
|
||||
.global esp_hw_stack_guard_monitor_stop
|
||||
.global esp_hw_stack_guard_monitor_start
|
||||
.global esp_hw_stack_guard_set_bounds
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
.section .text
|
||||
|
||||
/**
|
||||
* This function makes the RTOS aware about a ISR entering, it takes the
|
||||
* current task stack saved, places into the TCB, loads the ISR stack
|
||||
* the interrupted stack must be passed in a0. It needs to receive the
|
||||
* ISR nesting code improvements
|
||||
* current task stack saved, places into the TCB, loads the ISR stack.
|
||||
* TODO: ISR nesting code improvements ?
|
||||
*/
|
||||
|
||||
.global rtos_int_enter
|
||||
.type rtos_int_enter, @function
|
||||
rtos_int_enter:
|
||||
/* preserve the return address */
|
||||
mv t1, ra
|
||||
mv t2, a0
|
||||
|
||||
/* scheduler not enabled, jump directly to ISR handler */
|
||||
lw t0, uxSchedulerRunning
|
||||
beq t0,zero, rtos_enter_end
|
||||
@@ -40,19 +48,29 @@ rtos_int_enter:
|
||||
/* If reached here from another low-prio ISR, skip stack pushing to TCB */
|
||||
bne t4,zero, rtos_enter_end
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* esp_hw_stack_guard_monitor_stop(); */
|
||||
ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
/* Save current TCB and load the ISR stack */
|
||||
lw t0, pxCurrentTCB
|
||||
sw t2, 0x0(t0)
|
||||
sw sp, 0x0(t0)
|
||||
lw sp, xIsrStackTop
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* esp_hw_stack_guard_set_bounds(xIsrStack, xIsrStackTop); */
|
||||
la a0, xIsrStack
|
||||
mv a1, sp
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CPU0
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
rtos_enter_end:
|
||||
mv ra, t1
|
||||
ret
|
||||
|
||||
/**
|
||||
* Recovers the next task to run stack pointer and place it into
|
||||
* a0, then the interrupt handler can restore the context of
|
||||
* the next task
|
||||
* Recovers the next task to run stack pointer.
|
||||
*/
|
||||
.global rtos_int_exit
|
||||
.type rtos_int_exit, @function
|
||||
@@ -94,9 +112,26 @@ isr_skip_decrement:
|
||||
sw t2, 0x0(t0)
|
||||
|
||||
no_switch:
|
||||
/* Recover the stack of next task and prepare to exit : */
|
||||
lw a0, pxCurrentTCB
|
||||
lw a0, 0x0(a0)
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* esp_hw_stack_guard_monitor_stop(); */
|
||||
ESP_HW_STACK_GUARD_MONITOR_STOP_CPU0
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
/* Recover the stack of next task */
|
||||
lw t0, pxCurrentTCB
|
||||
lw sp, 0x0(t0)
|
||||
|
||||
#if CONFIG_ESP_SYSTEM_HW_STACK_GUARD
|
||||
/* esp_hw_stack_guard_set_bounds(pxCurrentTCB[0]->pxStack,
|
||||
* pxCurrentTCB[0]->pxEndOfStack);
|
||||
*/
|
||||
lw a0, PORT_OFFSET_PX_STACK(t0)
|
||||
lw a1, PORT_OFFSET_PX_END_OF_STACK(t0)
|
||||
ESP_HW_STACK_GUARD_SET_BOUNDS_CPU0
|
||||
/* esp_hw_stack_guard_monitor_start(); */
|
||||
ESP_HW_STACK_GUARD_MONITOR_START_CPU0
|
||||
#endif /* CONFIG_ESP_SYSTEM_HW_STACK_GUARD */
|
||||
|
||||
rtos_exit_end:
|
||||
ret
|
||||
|
Reference in New Issue
Block a user