System/Security: Memprot API unified (ESP32S3)

Unified Memory protection API for all PMS-aware chips - ESP32S3 port
pull/9328/head
Martin Vychodil 2021-12-22 07:25:59 +01:00 zatwierdzone przez BOT
rodzic d5a9f67ce9
commit 339fcbf14d
32 zmienionych plików z 3875 dodań i 874 usunięć

Wyświetl plik

@ -687,6 +687,12 @@ test_app_test_005:
- ESP32C3
- Example_GENERIC
test_app_test_006:
extends: .test_app_esp32s3_template
tags:
- ESP32S3
- Example_GENERIC
test_app_test_esp32_generic:
extends: .test_app_esp32_template
tags:

Wyświetl plik

@ -799,6 +799,9 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# endif
# ifdef ESP_ERR_MEMPROT_AREA_INVALID
ERR_TBL_IT(ESP_ERR_MEMPROT_AREA_INVALID), /* 53255 0xd007 */
# endif
# ifdef ESP_ERR_MEMPROT_CPUID_INVALID
ERR_TBL_IT(ESP_ERR_MEMPROT_CPUID_INVALID), /* 53256 0xd008 */
# endif
// components/tcp_transport/include/esp_transport.h
# ifdef ESP_ERR_TCP_TRANSPORT_BASE

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -11,6 +11,9 @@
#pragma once
#include "sdkconfig.h"
#if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST
#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"
@ -22,6 +25,7 @@
extern "C" {
#endif
#define DEFAULT_CPU_NUM -1
#define ESP_MEMPROT_ERR_CHECK(retval, fnc) if ((retval=fnc) != ESP_OK) { return retval; }
/**
@ -47,7 +51,7 @@ typedef struct {
* ESP_ERR_INVALID_ARG on passing invalid pointer
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, int const *const core);
esp_err_t esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, const int core);
/**
* @brief Checks whether any of the PMS settings is locked
@ -100,7 +104,7 @@ esp_err_t esp_mprot_get_active_intr(esp_memp_intr_source_t *active_memp_intr);
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
* ESP_ERR_INVALID_ARG on invalid fault_addr pointer
*/
esp_err_t esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, int const *const core);
esp_err_t esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, const int core);
/**
* @brief Returns PMS World identifier of the code causing the violation interrupt
@ -116,7 +120,7 @@ esp_err_t esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **faul
* ESP_ERR_INVALID_ARG on passing invalid pointer(s)
* ESP_ERR_MEMPROT_WORLD_INVALID on invalid World identifier fetched from the register
*/
esp_err_t esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, int const *const core);
esp_err_t esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, const int core);
/**
* @brief Returns an operation type which caused the violation interrupt
@ -132,7 +136,7 @@ esp_err_t esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
* ESP_ERR_INVALID_ARG on invalid oper pointer
*/
esp_err_t esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, int const *const core);
esp_err_t esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, const int core);
/**
* @brief Checks whether given memory type supports byte-enables info
@ -158,7 +162,7 @@ bool esp_mprot_has_byte_enables(const esp_mprot_mem_t mem_type);
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
* ESP_ERR_INVALID_ARGUMENT on invalid byte_en pointer
*/
esp_err_t esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, int const *const core);
esp_err_t esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, const int core);
/**
* @brief Convenient routine for setting the PMS defaults
@ -192,3 +196,5 @@ esp_err_t esp_mprot_dump_configuration(char **dump_info_string);
#ifdef __cplusplus
}
#endif
#endif //CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_MEMPROT_TEST

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -22,6 +22,7 @@ extern "C" {
#define ESP_ERR_MEMPROT_UNIMGMT_BLOCK_INVALID (ESP_ERR_MEMPROT_BASE + 5) /**< Required unified-management block is not valid */
#define ESP_ERR_MEMPROT_WORLD_INVALID (ESP_ERR_MEMPROT_BASE + 6) /**< Required World identifier is not valid */
#define ESP_ERR_MEMPROT_AREA_INVALID (ESP_ERR_MEMPROT_BASE + 7) /**< Required Area identifier is not valid */
#define ESP_ERR_MEMPROT_CPUID_INVALID (ESP_ERR_MEMPROT_BASE + 8) /**< Required CPU/Core identifier is not valid */
#ifdef __cplusplus
}

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -48,6 +48,7 @@ const char *esp_mprot_pms_world_to_str(const esp_mprot_pms_world_t world_type);
* @param mem_type memory type
* @param line_type split address type
* @param line_addr target address from a memory range relevant to given line_addr
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
@ -55,7 +56,7 @@ const char *esp_mprot_pms_world_to_str(const esp_mprot_pms_world_t world_type);
* ESP_ERR_MEMPROT_SPLIT_ADDR_OUT_OF_RANGE on splitting line out of given memory-type range
* ESP_ERR_MEMPROT_SPLIT_ADDR_UNALIGNED on splitting line not aligned to PMS-required boundaries
*/
esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, const void *line_addr);
esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, const void *line_addr, const int core);
/**
* @brief Gets PMS splitting address for given split_addr type
@ -65,13 +66,14 @@ esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mpr
* @param mem_type memory type
* @param line_type Split line type (see esp_mprot_split_addr_t enum)
* @param[out] line_addr Split line address from the configuration register
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG on line_addr is pointer
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
* ESP_ERR_MEMPROT_SPLIT_ADDR_INVALID on invalid line_type
*/
esp_err_t esp_mprot_get_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, void **line_addr);
esp_err_t esp_mprot_get_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, void **line_addr, const int core);
/**
* @brief Returns default main I/D splitting address for given Memory type
@ -90,69 +92,75 @@ esp_err_t esp_mprot_get_default_main_split_addr(const esp_mprot_mem_t mem_type,
* Locks can be unlocked only by digital system reset
*
* @param mem_type memory type
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_set_split_addr_lock(const esp_mprot_mem_t mem_type);
esp_err_t esp_mprot_set_split_addr_lock(const esp_mprot_mem_t mem_type, const int core);
/**
* @brief Gets a lock status for the splitting address configuration of given Memory type
*
* @param mem_type memory type
* @param[out] locked mem_type related lock status
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARGUMENT on invalid locked pointer
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_get_split_addr_lock(const esp_mprot_mem_t mem_type, bool *locked);
esp_err_t esp_mprot_get_split_addr_lock(const esp_mprot_mem_t mem_type, bool *locked, const int core);
/**
* @brief Sets a lock for PMS Area settings of required Memory type
* Locks can be unlocked only by digital system reset
*
* @param mem_type memory type
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_set_pms_lock(const esp_mprot_mem_t mem_type);
esp_err_t esp_mprot_set_pms_lock(const esp_mprot_mem_t mem_type, const int core);
/**
* @brief Gets a lock status for PMS Area settings of required Memory type
*
* @param mem_type memory type
* @param[out] locked mem_type related lock status
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
* ESP_ERR_INVALID_ARGUMENT on invalid locked pointer
*/
esp_err_t esp_mprot_get_pms_lock(const esp_mprot_mem_t mem_type, bool *locked);
esp_err_t esp_mprot_get_pms_lock(const esp_mprot_mem_t mem_type, bool *locked, const int core);
/**
* @brief Sets permissions for given PMS Area
*
* @param area_type PMS area type
* @param flags combination of MEMPROT_OP_* defines
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uint32_t flags);
esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uint32_t flags, const int core);
/**
* @brief Gets current permissions for given PMS Area
*
* @param area_type PMS area type
* @param[out] flags combination of MEMPROT_OP_* defines
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
* ESP_ERR_INVALID_ARG on invalid flags pointer
*/
esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t *flags);
esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t *flags, const int core);
/**
* @brief Sets a lock for PMS interrupt monitor settings of required Memory type
@ -160,34 +168,50 @@ esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t
* Locks can be unlocked only by digital system reset
*
* @param mem_type memory type (see esp_mprot_mem_t enum)
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_set_monitor_lock(const esp_mprot_mem_t mem_type);
esp_err_t esp_mprot_set_monitor_lock(const esp_mprot_mem_t mem_type, const int core);
/**
* @brief Gets a lock status for PMS interrupt monitor settings of required Memory type
*
* @param mem_type memory type
* @param[out] locked mem_type related lock status
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
* ESP_ERR_INVALID_ARG on invalid locked pointer
*/
esp_err_t esp_mprot_get_monitor_lock(const esp_mprot_mem_t mem_type, bool *locked);
esp_err_t esp_mprot_get_monitor_lock(const esp_mprot_mem_t mem_type, bool *locked, const int core);
/**
* @brief Enable PMS violation interrupt monitoring of required Memory type
*
* @param mem_type memory type
* @param enable enable/disable violation interrupt monitoring
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_set_monitor_en(const esp_mprot_mem_t mem_type, const bool enable);
esp_err_t esp_mprot_set_monitor_en(const esp_mprot_mem_t mem_type, const bool enable, const int core);
/**
* @brief Gets PMS violation-monitoring-enabled flag for required Memory type
*
* @param mem_type memory type
* @param[out] enabled violation interrupt monitoring enable flag
* @param core Target CPU/Core ID (see *_CPU_NUM defs in soc.h). Can be NULL on 1-CPU systems
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG on invalid enabled pointer
* ESP_ERR_MEMPROT_MEMORY_TYPE_INVALID on invalid mem_type
*/
esp_err_t esp_mprot_get_monitor_en(const esp_mprot_mem_t mem_type, bool* enabled, const int core);
#ifdef __cplusplus
}

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -54,7 +54,7 @@ typedef struct {
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
} esp_memp_config_t;
#define ESP_MEMPROT_DEFAULT_CONFIG() {\
#define ESP_MEMPROT_DEFAULT_CONFIG() { \
.invoke_panic_handler = true, \
.lock_feature = true, \
.split_addr = NULL, \

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -12,6 +12,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc.h"
#include "freertos/FreeRTOSConfig.h"
#ifdef __cplusplus
extern "C" {
@ -22,8 +24,12 @@ extern "C" {
*/
typedef enum {
MEMPROT_TYPE_NONE = 0x00000000,
MEMPROT_TYPE_IRAM0_SRAM = 0x00000001,
MEMPROT_TYPE_DRAM0_SRAM = 0x00000002,
MEMPROT_TYPE_IRAM0_RTCFAST = 0x00000004,
MEMPROT_TYPE_ALL = 0x7FFFFFFF,
MEMPROT_TYPE_INVALID = 0x80000000
MEMPROT_TYPE_INVALID = 0x80000000,
MEMPROT_TYPE_IRAM0_ANY = MEMPROT_TYPE_IRAM0_SRAM | MEMPROT_TYPE_IRAM0_RTCFAST
} esp_mprot_mem_t;
/**
@ -31,8 +37,14 @@ typedef enum {
*/
typedef enum {
MEMPROT_SPLIT_ADDR_NONE = 0x00000000,
MEMPROT_SPLIT_ADDR_IRAM0_DRAM0 = 0x00000001,
MEMPROT_SPLIT_ADDR_IRAM0_LINE_0 = 0x00000002,
MEMPROT_SPLIT_ADDR_IRAM0_LINE_1 = 0x00000004,
MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0 = 0x00000008,
MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1 = 0x00000010,
MEMPROT_SPLIT_ADDR_ALL = 0x7FFFFFFF,
MEMPROT_SPLIT_ADDR_INVALID = 0x80000000
MEMPROT_SPLIT_ADDR_INVALID = 0x80000000,
MEMPROT_SPLIT_ADDR_MAIN = MEMPROT_SPLIT_ADDR_IRAM0_DRAM0
} esp_mprot_split_addr_t;
/**
@ -40,6 +52,16 @@ typedef enum {
*/
typedef enum {
MEMPROT_PMS_AREA_NONE = 0x00000000,
MEMPROT_PMS_AREA_IRAM0_0 = 0x00000001,
MEMPROT_PMS_AREA_IRAM0_1 = 0x00000002,
MEMPROT_PMS_AREA_IRAM0_2 = 0x00000004,
MEMPROT_PMS_AREA_IRAM0_3 = 0x00000008,
MEMPROT_PMS_AREA_DRAM0_0 = 0x00000010,
MEMPROT_PMS_AREA_DRAM0_1 = 0x00000020,
MEMPROT_PMS_AREA_DRAM0_2 = 0x00000040,
MEMPROT_PMS_AREA_DRAM0_3 = 0x00000080,
MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO = 0x00000100,
MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI = 0x00000200,
MEMPROT_PMS_AREA_ALL = 0x7FFFFFFF,
MEMPROT_PMS_AREA_INVALID = 0x80000000
} esp_mprot_pms_area_t;
@ -48,20 +70,35 @@ typedef enum {
* @brief Memory protection configuration
*/
typedef struct {
bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
bool lock_feature; /*!< Lock all PMS settings */
void *split_addr; /*!< Main I/D splitting address */
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
int target_cpu[]; /*!< Array of CPU/core IDs required to receive given PMS protection */
bool invoke_panic_handler; /*!< Register PMS violation interrupt for panic-handling */
bool lock_feature; /*!< Lock all PMS settings */
void *split_addr; /*!< Main I/D splitting address */
uint32_t mem_type_mask; /*!< Memory types required to protect. See esp_mprot_mem_t enum */
size_t target_cpu_count; /*!< Real CPU/core count (max 2) */
int target_cpu[portNUM_PROCESSORS]; /*!< Array of CPU/core IDs required to receive given PMS protection */
} esp_memp_config_t;
#if portNUM_PROCESSORS > 1
#define ESP_MEMPROT_DEFAULT_CONFIG() { \
.invoke_panic_handler = true, \
.lock_feature = true, \
.split_addr = NULL, \
.mem_type_mask = MEMPROT_TYPE_ALL,\
.target_cpu[] = {PRO_CPU_NUM, APP_CPU_NUM} \
/* .mem_type_mask = MEMPROT_TYPE_ALL, \ - unless IDF-5208 gets merged */ \
.mem_type_mask = MEMPROT_TYPE_IRAM0_SRAM | MEMPROT_TYPE_DRAM0_SRAM, \
.target_cpu_count = portNUM_PROCESSORS, \
.target_cpu = {PRO_CPU_NUM, APP_CPU_NUM} \
}
#else
#define ESP_MEMPROT_DEFAULT_CONFIG() { \
.invoke_panic_handler = true, \
.lock_feature = true, \
.split_addr = NULL, \
/* .mem_type_mask = MEMPROT_TYPE_ALL, \ - unless IDF-5208 gets merged */ \
.mem_type_mask = MEMPROT_TYPE_IRAM0_SRAM | MEMPROT_TYPE_DRAM0_SRAM, \
.target_cpu_count = portNUM_PROCESSORS, \
.target_cpu = {PRO_CPU_NUM} \
}
#endif
/**
* @brief Converts Memory protection type to string
@ -72,11 +109,19 @@ static inline const char *esp_mprot_mem_type_to_str(const esp_mprot_mem_t mem_ty
{
switch (mem_type) {
case MEMPROT_TYPE_NONE:
return "MEMPROT_TYPE_NONE";
return "NONE";
case MEMPROT_TYPE_IRAM0_SRAM:
return "IRAM0_SRAM";
case MEMPROT_TYPE_DRAM0_SRAM:
return "DRAM0_SRAM";
case MEMPROT_TYPE_IRAM0_RTCFAST:
return "IRAM0_RTCFAST";
case MEMPROT_TYPE_IRAM0_ANY:
return "IRAM0_ANY";
case MEMPROT_TYPE_ALL:
return "MEMPROT_TYPE_ALL";
return "ALL";
default:
return "MEMPROT_TYPE_INVALID";
return "INVALID";
}
}
@ -89,11 +134,21 @@ static inline const char *esp_mprot_split_addr_to_str(const esp_mprot_split_addr
{
switch (line_type) {
case MEMPROT_SPLIT_ADDR_NONE:
return "MEMPROT_SPLIT_ADDR_NONE";
return "SPLIT_ADDR_NONE";
case MEMPROT_SPLIT_ADDR_IRAM0_DRAM0:
return "SPLIT_ADDR_IRAM0_DRAM0";
case MEMPROT_SPLIT_ADDR_IRAM0_LINE_0:
return "SPLIT_ADDR_IRAM0_LINE_0";
case MEMPROT_SPLIT_ADDR_IRAM0_LINE_1:
return "SPLIT_ADDR_IRAM0_LINE_1";
case MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0:
return "SPLIT_ADDR_DRAM0_DMA_LINE_0";
case MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1:
return "SPLIT_ADDR_DRAM0_DMA_LINE_1";
case MEMPROT_SPLIT_ADDR_ALL:
return "MEMPROT_SPLIT_ADDR_ALL";
return "SPLIT_ADDR_ALL";
default:
return "MEMPROT_SPLIT_ADDR_INVALID";
return "SPLIT_ADDR_INVALID";
}
}
@ -106,11 +161,31 @@ static inline const char *esp_mprot_pms_area_to_str(const esp_mprot_pms_area_t a
{
switch (area_type) {
case MEMPROT_PMS_AREA_NONE:
return "MEMPROT_PMS_AREA_NONE";
return "PMS_AREA_NONE";
case MEMPROT_PMS_AREA_IRAM0_0:
return "PMS_AREA_IRAM0_0";
case MEMPROT_PMS_AREA_IRAM0_1:
return "PMS_AREA_IRAM0_1";
case MEMPROT_PMS_AREA_IRAM0_2:
return "PMS_AREA_IRAM0_2";
case MEMPROT_PMS_AREA_IRAM0_3:
return "PMS_AREA_IRAM0_3";
case MEMPROT_PMS_AREA_DRAM0_0:
return "PMS_AREA_DRAM0_0";
case MEMPROT_PMS_AREA_DRAM0_1:
return "PMS_AREA_DRAM0_1";
case MEMPROT_PMS_AREA_DRAM0_2:
return "PMS_AREA_DRAM0_2";
case MEMPROT_PMS_AREA_DRAM0_3:
return "PMS_AREA_DRAM0_3";
case MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO:
return "PMS_AREA_IRAM0_RTCFAST_LO";
case MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI:
return "PMS_AREA_IRAM0_RTCFAST_HI";
case MEMPROT_PMS_AREA_ALL:
return "MEMPROT_PMS_AREA_ALL";
return "PMS_AREA_ALL";
default:
return "MEMPROT_PMS_AREA_INVALID";
return "PMS_AREA_INVALID";
}
}

Wyświetl plik

@ -11,9 +11,12 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "../async_memcpy_impl_gdma.c"
"esp_hmac.c"
"esp_crypto_lock.c"
"esp_ds.c"
"esp_memprot.c"
"../esp_memprot_conv.c")
"esp_ds.c")
if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE)
list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c")
endif()
endif()
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")

Wyświetl plik

@ -36,7 +36,7 @@ static void *esp_memprot_rtcfast_get_min_split_addr(void)
return &_rtc_text_end;
}
esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, const void *line_addr)
esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, const void *line_addr, const int core __attribute__((unused)))
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
@ -72,7 +72,7 @@ esp_err_t esp_mprot_set_split_addr(const esp_mprot_mem_t mem_type, const esp_mpr
}
}
esp_err_t esp_mprot_get_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, void **line_addr)
esp_err_t esp_mprot_get_split_addr(const esp_mprot_mem_t mem_type, const esp_mprot_split_addr_t line_type, void **line_addr, const int core __attribute__((unused)))
{
if (line_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@ -142,7 +142,7 @@ esp_err_t esp_mprot_get_default_main_split_addr(const esp_mprot_mem_t mem_type,
return ESP_OK;
}
esp_err_t esp_mprot_set_split_addr_lock(const esp_mprot_mem_t mem_type)
esp_err_t esp_mprot_set_split_addr_lock(const esp_mprot_mem_t mem_type, const int core __attribute__((unused)))
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
@ -160,7 +160,7 @@ esp_err_t esp_mprot_set_split_addr_lock(const esp_mprot_mem_t mem_type)
return ESP_OK;
}
esp_err_t esp_mprot_get_split_addr_lock(const esp_mprot_mem_t mem_type, bool *locked)
esp_err_t esp_mprot_get_split_addr_lock(const esp_mprot_mem_t mem_type, bool *locked, const int core __attribute__((unused)))
{
if (locked == NULL) {
return ESP_ERR_INVALID_ARG;
@ -181,7 +181,7 @@ esp_err_t esp_mprot_get_split_addr_lock(const esp_mprot_mem_t mem_type, bool *lo
return ESP_OK;
}
esp_err_t esp_mprot_set_pms_lock(const esp_mprot_mem_t mem_type)
esp_err_t esp_mprot_set_pms_lock(const esp_mprot_mem_t mem_type, const int core __attribute__((unused)))
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
@ -201,7 +201,7 @@ esp_err_t esp_mprot_set_pms_lock(const esp_mprot_mem_t mem_type)
return ESP_OK;
}
esp_err_t esp_mprot_get_pms_lock(const esp_mprot_mem_t mem_type, bool *locked)
esp_err_t esp_mprot_get_pms_lock(const esp_mprot_mem_t mem_type, bool *locked, const int core __attribute__((unused)))
{
if (locked == NULL) {
return ESP_ERR_INVALID_ARG;
@ -224,7 +224,7 @@ esp_err_t esp_mprot_get_pms_lock(const esp_mprot_mem_t mem_type, bool *locked)
return ESP_OK;
}
esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uint32_t flags)
esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uint32_t flags, const int core __attribute__((unused)))
{
bool r = flags & MEMPROT_OP_READ;
bool w = flags & MEMPROT_OP_WRITE;
@ -268,7 +268,7 @@ esp_err_t esp_mprot_set_pms_area(const esp_mprot_pms_area_t area_type, const uin
return ESP_OK;
}
esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t *flags)
esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t *flags, const int core __attribute__((unused)))
{
if (flags == NULL) {
return ESP_ERR_INVALID_ARG;
@ -327,7 +327,7 @@ esp_err_t esp_mprot_get_pms_area(const esp_mprot_pms_area_t area_type, uint32_t
return ESP_OK;
}
esp_err_t esp_mprot_set_monitor_lock(const esp_mprot_mem_t mem_type)
esp_err_t esp_mprot_set_monitor_lock(const esp_mprot_mem_t mem_type, const int core __attribute__((unused)))
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
@ -346,7 +346,7 @@ esp_err_t esp_mprot_set_monitor_lock(const esp_mprot_mem_t mem_type)
return ESP_OK;
}
esp_err_t esp_mprot_get_monitor_lock(const esp_mprot_mem_t mem_type, bool *locked)
esp_err_t esp_mprot_get_monitor_lock(const esp_mprot_mem_t mem_type, bool *locked, const int core __attribute__((unused)))
{
if (locked == NULL) {
return ESP_ERR_INVALID_ARG;
@ -369,7 +369,7 @@ esp_err_t esp_mprot_get_monitor_lock(const esp_mprot_mem_t mem_type, bool *locke
return ESP_OK;
}
esp_err_t esp_mprot_set_monitor_en(const esp_mprot_mem_t mem_type, const bool enable)
esp_err_t esp_mprot_set_monitor_en(const esp_mprot_mem_t mem_type, const bool enable, const int core __attribute__((unused)))
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
@ -388,7 +388,7 @@ esp_err_t esp_mprot_set_monitor_en(const esp_mprot_mem_t mem_type, const bool en
return ESP_OK;
}
esp_err_t esp_mprot_get_monitor_en(const esp_mprot_mem_t mem_type, bool *enabled)
esp_err_t esp_mprot_get_monitor_en(const esp_mprot_mem_t mem_type, bool *enabled, const int core __attribute__((unused)))
{
if (enabled == NULL) {
return ESP_ERR_INVALID_ARG;
@ -411,7 +411,7 @@ esp_err_t esp_mprot_get_monitor_en(const esp_mprot_mem_t mem_type, bool *enabled
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, const int core __attribute__((unused)))
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
@ -463,19 +463,19 @@ esp_err_t IRAM_ATTR esp_mprot_is_conf_locked_any(bool *locked)
bool lock_on = false;
esp_err_t res;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_split_addr_lock(MEMPROT_TYPE_IRAM0_SRAM, &lock_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_split_addr_lock(MEMPROT_TYPE_IRAM0_SRAM, &lock_on, DEFAULT_CPU_NUM))
*locked |= lock_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_split_addr_lock(MEMPROT_TYPE_DRAM0_SRAM, &lock_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_split_addr_lock(MEMPROT_TYPE_DRAM0_SRAM, &lock_on, DEFAULT_CPU_NUM))
*locked |= lock_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_pms_lock(MEMPROT_TYPE_IRAM0_SRAM, &lock_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_pms_lock(MEMPROT_TYPE_IRAM0_SRAM, &lock_on, DEFAULT_CPU_NUM))
*locked |= lock_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_pms_lock(MEMPROT_TYPE_DRAM0_SRAM, &lock_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_pms_lock(MEMPROT_TYPE_DRAM0_SRAM, &lock_on, DEFAULT_CPU_NUM))
*locked |= lock_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_lock(MEMPROT_TYPE_IRAM0_SRAM, &lock_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_lock(MEMPROT_TYPE_IRAM0_SRAM, &lock_on, DEFAULT_CPU_NUM))
*locked |= lock_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_lock(MEMPROT_TYPE_DRAM0_SRAM, &lock_on));
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_lock(MEMPROT_TYPE_DRAM0_SRAM, &lock_on, DEFAULT_CPU_NUM));
*locked |= lock_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_lock(MEMPROT_TYPE_IRAM0_RTCFAST, &lock_on));
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_lock(MEMPROT_TYPE_IRAM0_RTCFAST, &lock_on, DEFAULT_CPU_NUM));
*locked |= lock_on;
return ESP_OK;
@ -490,17 +490,17 @@ esp_err_t IRAM_ATTR esp_mprot_is_intr_ena_any(bool *enabled)
bool ena_on = false;
esp_err_t res;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_en(MEMPROT_TYPE_IRAM0_SRAM, &ena_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_en(MEMPROT_TYPE_IRAM0_SRAM, &ena_on, DEFAULT_CPU_NUM))
*enabled |= ena_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_en(MEMPROT_TYPE_DRAM0_SRAM, &ena_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_en(MEMPROT_TYPE_DRAM0_SRAM, &ena_on, DEFAULT_CPU_NUM))
*enabled |= ena_on;
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_en(MEMPROT_TYPE_IRAM0_RTCFAST, &ena_on))
ESP_MEMPROT_ERR_CHECK(res, esp_mprot_get_monitor_en(MEMPROT_TYPE_IRAM0_RTCFAST, &ena_on, DEFAULT_CPU_NUM))
*enabled |= ena_on;
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, const int core __attribute__((unused)))
{
if (fault_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@ -523,7 +523,7 @@ esp_err_t IRAM_ATTR esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, v
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, const int core __attribute__((unused)))
{
if (world == NULL) {
return ESP_ERR_INVALID_ARG;
@ -553,7 +553,7 @@ esp_err_t IRAM_ATTR esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type,
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, const int core __attribute__((unused)))
{
if (oper == NULL) {
return ESP_ERR_INVALID_ARG;
@ -592,7 +592,7 @@ bool IRAM_ATTR esp_mprot_has_byte_enables(const esp_mprot_mem_t mem_type)
return mem_type == MEMPROT_TYPE_DRAM0_SRAM;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, const int core __attribute__((unused)))
{
if (byte_en == NULL) {
return ESP_ERR_INVALID_ARG;
@ -661,13 +661,13 @@ esp_err_t esp_mprot_set_prot(const esp_memp_config_t *memp_config)
//disable protection (must be unlocked)
if (use_iram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_SRAM, false))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_SRAM, false, DEFAULT_CPU_NUM))
}
if (use_dram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_DRAM0_SRAM, false))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_DRAM0_SRAM, false, DEFAULT_CPU_NUM))
}
if (use_rtcfast) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_RTCFAST, false))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_RTCFAST, false, DEFAULT_CPU_NUM))
}
//panic handling
@ -689,64 +689,64 @@ esp_err_t esp_mprot_set_prot(const esp_memp_config_t *memp_config)
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_get_default_main_split_addr(MEMPROT_TYPE_IRAM0_SRAM, &line_addr))
}
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_SRAM, MEMPROT_SPLIT_ADDR_IRAM0_LINE_1, line_addr))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_SRAM, MEMPROT_SPLIT_ADDR_IRAM0_LINE_0, line_addr))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_SRAM, MEMPROT_SPLIT_ADDR_IRAM0_DRAM0, line_addr))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_DRAM0_SRAM, MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr))))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_DRAM0_SRAM, MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr))))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_SRAM, MEMPROT_SPLIT_ADDR_IRAM0_LINE_1, line_addr, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_SRAM, MEMPROT_SPLIT_ADDR_IRAM0_LINE_0, line_addr, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_SRAM, MEMPROT_SPLIT_ADDR_IRAM0_DRAM0, line_addr, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_DRAM0_SRAM, MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_0, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr)), DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_DRAM0_SRAM, MEMPROT_SPLIT_ADDR_DRAM0_DMA_LINE_1, (void *)(MAP_IRAM_TO_DRAM((uint32_t)line_addr)), DEFAULT_CPU_NUM))
//set permissions
if (use_iram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_0, MEMPROT_OP_READ | MEMPROT_OP_EXEC))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_1, MEMPROT_OP_READ | MEMPROT_OP_EXEC))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_2, MEMPROT_OP_READ | MEMPROT_OP_EXEC))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_3, MEMPROT_OP_NONE))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_0, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_1, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_2, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_3, MEMPROT_OP_NONE, DEFAULT_CPU_NUM))
}
if (use_dram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_0, MEMPROT_OP_NONE ))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_1, MEMPROT_OP_READ | MEMPROT_OP_WRITE))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_2, MEMPROT_OP_READ | MEMPROT_OP_WRITE))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_3, MEMPROT_OP_READ | MEMPROT_OP_WRITE))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_0, MEMPROT_OP_NONE, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_1, MEMPROT_OP_READ | MEMPROT_OP_WRITE, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_2, MEMPROT_OP_READ | MEMPROT_OP_WRITE, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_3, MEMPROT_OP_READ | MEMPROT_OP_WRITE, DEFAULT_CPU_NUM))
}
if (use_rtcfast) {
//RTCFAST split-line cannot be set manually - always use default
void *rtc_fast_line;
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_get_default_main_split_addr(MEMPROT_TYPE_IRAM0_RTCFAST, &rtc_fast_line));
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_RTCFAST, MEMPROT_SPLIT_ADDR_MAIN, rtc_fast_line))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO, MEMPROT_OP_READ | MEMPROT_OP_EXEC))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI, MEMPROT_OP_READ | MEMPROT_OP_WRITE))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr(MEMPROT_TYPE_IRAM0_RTCFAST, MEMPROT_SPLIT_ADDR_MAIN, rtc_fast_line, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO, MEMPROT_OP_READ | MEMPROT_OP_EXEC, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI, MEMPROT_OP_READ | MEMPROT_OP_WRITE, DEFAULT_CPU_NUM))
}
//reenable the protection
if (use_iram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_SRAM, NULL))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_SRAM, true))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_SRAM, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_SRAM, true, DEFAULT_CPU_NUM))
}
if (use_dram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_monitor_clear_intr(MEMPROT_TYPE_DRAM0_SRAM, NULL))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_DRAM0_SRAM, true))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_monitor_clear_intr(MEMPROT_TYPE_DRAM0_SRAM, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_DRAM0_SRAM, true, DEFAULT_CPU_NUM))
}
if (use_rtcfast) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_RTCFAST, NULL))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_RTCFAST, true))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_RTCFAST, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_en(MEMPROT_TYPE_IRAM0_RTCFAST, true, DEFAULT_CPU_NUM))
}
//lock if required
if (memp_config->lock_feature) {
if (use_iram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr_lock(MEMPROT_TYPE_IRAM0_SRAM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_lock(MEMPROT_TYPE_IRAM0_SRAM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_lock(MEMPROT_TYPE_IRAM0_SRAM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr_lock(MEMPROT_TYPE_IRAM0_SRAM, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_lock(MEMPROT_TYPE_IRAM0_SRAM, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_lock(MEMPROT_TYPE_IRAM0_SRAM, DEFAULT_CPU_NUM))
}
if (use_dram0) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr_lock(MEMPROT_TYPE_DRAM0_SRAM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_lock(MEMPROT_TYPE_DRAM0_SRAM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_lock(MEMPROT_TYPE_DRAM0_SRAM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr_lock(MEMPROT_TYPE_DRAM0_SRAM, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_lock(MEMPROT_TYPE_DRAM0_SRAM, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_lock(MEMPROT_TYPE_DRAM0_SRAM, DEFAULT_CPU_NUM))
}
if (use_rtcfast) {
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr_lock(MEMPROT_TYPE_IRAM0_RTCFAST))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_lock(MEMPROT_TYPE_IRAM0_RTCFAST))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_lock(MEMPROT_TYPE_IRAM0_RTCFAST))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_split_addr_lock(MEMPROT_TYPE_IRAM0_RTCFAST, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_pms_lock(MEMPROT_TYPE_IRAM0_RTCFAST, DEFAULT_CPU_NUM))
ESP_MEMPROT_ERR_CHECK(ret, esp_mprot_set_monitor_lock(MEMPROT_TYPE_IRAM0_RTCFAST, DEFAULT_CPU_NUM))
}
}

Wyświetl plik

@ -11,9 +11,12 @@ if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "../async_memcpy_impl_gdma.c"
"esp_hmac.c"
"esp_crypto_lock.c"
"esp_ds.c"
"esp_memprot.c"
"../esp_memprot_conv.c")
"esp_ds.c")
if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE)
list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c")
endif()
endif()
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")

Wyświetl plik

@ -121,7 +121,7 @@ esp_err_t esp_mprot_get_monitor_en(const esp_mprot_mem_t mem_type, bool *enabled
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_monitor_clear_intr(const esp_mprot_mem_t mem_type, const int core __attribute__((unused)))
{
return ESP_OK;
}
@ -160,7 +160,7 @@ esp_err_t IRAM_ATTR esp_mprot_is_intr_ena_any(bool *enabled)
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, void **fault_addr, const int core __attribute__((unused)))
{
if (fault_addr == NULL) {
return ESP_ERR_INVALID_ARG;
@ -171,7 +171,7 @@ esp_err_t IRAM_ATTR esp_mprot_get_violate_addr(const esp_mprot_mem_t mem_type, v
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type, esp_mprot_pms_world_t *world, const int core __attribute__((unused)))
{
if (world == NULL) {
return ESP_ERR_INVALID_ARG;
@ -182,7 +182,7 @@ esp_err_t IRAM_ATTR esp_mprot_get_violate_world(const esp_mprot_mem_t mem_type,
return ESP_OK;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_operation(const esp_mprot_mem_t mem_type, uint32_t *oper, const int core __attribute__((unused)))
{
if (oper == NULL) {
return ESP_ERR_INVALID_ARG;
@ -198,7 +198,7 @@ bool IRAM_ATTR esp_mprot_has_byte_enables(const esp_mprot_mem_t mem_type)
return false;
}
esp_err_t IRAM_ATTR esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, int const *const core __attribute__((unused)))
esp_err_t IRAM_ATTR esp_mprot_get_violate_byte_enables(const esp_mprot_mem_t mem_type, uint32_t *byte_en, const int core __attribute__((unused)))
{
if (byte_en == NULL) {
return ESP_ERR_INVALID_ARG;

Wyświetl plik

@ -16,6 +16,10 @@ if(NOT BOOTLOADER_BUILD)
"esp_hmac.c"
"esp_ds.c"
"esp_crypto_lock.c")
if(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE)
list(APPEND srcs "esp_memprot.c" "../esp_memprot_conv.c")
endif()
endif()
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")

Wyświetl plik

@ -133,7 +133,7 @@ menu "ESP System Settings"
bool
default y if IDF_TARGET_ESP32S2
default y if IDF_TARGET_ESP32C3
default y if IDF_TARGET_ESP32H2
default y if IDF_TARGET_ESP32S3
config ESP_SYSTEM_MEMPROT_FEATURE
bool "Enable memory protection"

Wyświetl plik

@ -100,11 +100,6 @@ MEMORY
*/
rtc_iram_seg(RWX) : org = 0x600fe000, len = 0x2000 - ESP_BOOTLOADER_RESERVE_RTC
/**
* RTC fast memory (same block as above), viewed from data bus
*/
rtc_data_seg(RW) : org = 0x600fe000, len = 0x2000 - ESP_BOOTLOADER_RESERVE_RTC
/**
* RTC slow memory (data accessible). Persists over deep sleep.
* Start of RTC slow memory is reserved for ULP co-processor code + data, if enabled.
@ -134,6 +129,10 @@ _heap_end = 0x40000000;
_data_seg_org = ORIGIN(rtc_data_seg);
/* RTC fast memory shares the same range for both data and instructions */
REGION_ALIAS("rtc_data_seg", rtc_iram_seg );
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
REGION_ALIAS("rtc_data_location", rtc_data_seg );
#else

Wyświetl plik

@ -18,27 +18,22 @@ SECTIONS
.rtc.text :
{
. = ALIGN(4);
_rtc_fast_start = ABSOLUTE(.);
_rtc_text_start = ABSOLUTE(.);
*(.rtc.entry.text)
mapping[rtc_text]
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
*(.rtc_text_end_test)
/* 16B padding for possible CPU prefetch and 4B alignment for PMS split lines */
. += _esp_memprot_prefetch_pad_size;
. = ALIGN(4);
_rtc_text_end = ABSOLUTE(.);
} > rtc_iram_seg
/**
* This section is required to skip rtc.text area because rtc_iram_seg and
* rtc_data_seg are reflect the same address space on different buses.
*/
.rtc.dummy :
{
_rtc_dummy_start = ABSOLUTE(.);
_rtc_fast_start = ABSOLUTE(.);
. = SIZEOF(.rtc.text);
_rtc_dummy_end = ABSOLUTE(.);
} > rtc_data_seg
/**
* This section located in RTC FAST Memory area.
* It holds data marked with RTC_FAST_ATTR attribute.
@ -402,11 +397,11 @@ SECTIONS
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
/* iram_end_test section exists for use by memprot unit tests only */
*(.iram_end_test)
/* ESP32-S3 memprot requires 16B padding for possible CPU prefetch and 256B alignment for PMS split lines */
. += _esp_memprot_prefetch_pad_size;
. = ALIGN(_esp_memprot_align_size);
/* iram_end_test section exists for use by memprot unit tests only */
*(.iram_end_test)
_iram_text_end = ABSOLUTE(.);
} > iram0_0_seg

Wyświetl plik

@ -161,7 +161,7 @@ static esp_memp_intr_source_t s_memp_intr = {MEMPROT_TYPE_INVALID, -1};
#define PRINT_MEMPROT_ERROR(err) \
panic_print_str("N/A (error "); \
panic_print_str(esp_err_to_name(err)); \
panic_print_str(")");
panic_print_str(")")
static inline void print_memprot_err_details(const void *frame __attribute__((unused)))
{
@ -176,40 +176,40 @@ static inline void print_memprot_err_details(const void *frame __attribute__((un
panic_print_str("\r\n faulting address: ");
void *faulting_addr;
esp_err_t res = esp_mprot_get_violate_addr(s_memp_intr.mem_type, &faulting_addr, &s_memp_intr.core);
esp_err_t res = esp_mprot_get_violate_addr(s_memp_intr.mem_type, &faulting_addr, s_memp_intr.core);
if (res == ESP_OK) {
panic_print_str("0x");
panic_print_hex((int)faulting_addr);
} else {
PRINT_MEMPROT_ERROR(res)
PRINT_MEMPROT_ERROR(res);
}
panic_print_str( "\r\n world: ");
esp_mprot_pms_world_t world;
res = esp_mprot_get_violate_world(s_memp_intr.mem_type, &world, &s_memp_intr.core);
res = esp_mprot_get_violate_world(s_memp_intr.mem_type, &world, s_memp_intr.core);
if (res == ESP_OK) {
panic_print_str(esp_mprot_pms_world_to_str(world));
} else {
PRINT_MEMPROT_ERROR(res)
PRINT_MEMPROT_ERROR(res);
}
panic_print_str( "\r\n operation type: ");
uint32_t operation;
res = esp_mprot_get_violate_operation(s_memp_intr.mem_type, &operation, &s_memp_intr.core);
res = esp_mprot_get_violate_operation(s_memp_intr.mem_type, &operation, s_memp_intr.core);
if (res == ESP_OK) {
panic_print_str(esp_mprot_oper_type_to_str(operation));
} else {
PRINT_MEMPROT_ERROR(res)
PRINT_MEMPROT_ERROR(res);
}
if (esp_mprot_has_byte_enables(s_memp_intr.mem_type)) {
panic_print_str("\r\n byte-enables: " );
uint32_t byte_enables;
res = esp_mprot_get_violate_byte_enables(s_memp_intr.mem_type, &byte_enables, &s_memp_intr.core);
res = esp_mprot_get_violate_byte_enables(s_memp_intr.mem_type, &byte_enables, s_memp_intr.core);
if (res == ESP_OK) {
panic_print_hex(byte_enables);
} else {
PRINT_MEMPROT_ERROR(res)
PRINT_MEMPROT_ERROR(res);
}
}

Wyświetl plik

@ -6,6 +6,9 @@
#pragma once
#include "soc/soc.h"
#include "soc/memprot_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -16,13 +19,14 @@ extern "C" {
*/
typedef enum {
MEMP_LL_OK = 0,
MEMP_LL_FAIL = 1,
MEMP_LL_ERR_SPLIT_ADDR_OUT_OF_RANGE = 2,
MEMP_LL_ERR_SPLIT_ADDR_INVALID = 2, /* temporary duplicate for S2 builds */
MEMP_LL_ERR_SPLIT_ADDR_UNALIGNED = 3,
MEMP_LL_ERR_UNI_BLOCK_INVALID = 4,
MEMP_LL_ERR_AREA_INVALID = 5,
MEMP_LL_ERR_WORLD_INVALID = 6
MEMP_LL_ERR_WORLD_INVALID = 6,
MEMP_LL_ERR_CORE_INVALID = 7,
MEMP_LL_FAIL = -1,
} memprot_ll_err_t;
/**
@ -45,6 +49,19 @@ typedef enum {
MEMP_LL_AREA_HIGH = 2
} memprot_ll_area_t;
//auxiliary macros & defines
#define SOC_I_D_OFFSET (SOC_DIRAM_IRAM_LOW - SOC_DIRAM_DRAM_LOW)
#define MAP_DRAM_TO_IRAM(addr) (addr + SOC_I_D_OFFSET)
#define MAP_IRAM_TO_DRAM(addr) (addr - SOC_I_D_OFFSET)
#define MEMP_LL_CHECK_IRAM_ADDR_IN_RANGE(x) if (x < SOC_DIRAM_IRAM_LOW || x >= SOC_DIRAM_IRAM_HIGH) { return MEMP_LL_ERR_SPLIT_ADDR_OUT_OF_RANGE; }
#define MEMP_LL_CHECK_DRAM_ADDR_IN_RANGE(x) if (x < SOC_DIRAM_DRAM_LOW || x >= SOC_DIRAM_DRAM_HIGH) { return MEMP_LL_ERR_SPLIT_ADDR_OUT_OF_RANGE; }
#define MEMP_LL_CHECK_SPLIT_ADDR_ALIGNED(x) if (x % I_D_SPLIT_LINE_ALIGN != 0) { return MEMP_LL_ERR_SPLIT_ADDR_UNALIGNED; }
#define MEMP_LL_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_BITS_BELOW_SA 0x0 //0b00
#define MEMP_LL_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_BITS_EQUAL_SA 0x2 //0b10
#define MEMP_LL_CORE_X_IRAM0_DRAM0_DMA_SRAM_CATEGORY_BITS_ABOVE_SA 0x3 //0b11
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -35,14 +35,6 @@ typedef union {
#define DRAM_SRAM_START 0x3FC7C000
#ifndef MAP_DRAM_TO_IRAM
#define MAP_DRAM_TO_IRAM(addr) (addr - DRAM_SRAM_START + SOC_IRAM_LOW)
#endif
#ifndef MAP_IRAM_TO_DRAM
#define MAP_IRAM_TO_DRAM(addr) (addr - SOC_IRAM_LOW + DRAM_SRAM_START)
#endif
//IRAM0
//16kB (ICACHE)

Wyświetl plik

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/sensitive_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef union {
struct {
uint32_t cat0 : 2;
uint32_t cat1 : 2;
uint32_t cat2 : 2;
uint32_t cat3 : 2;
uint32_t cat4 : 2;
uint32_t cat5 : 2;
uint32_t cat6 : 2;
uint32_t splitaddr : 8;
uint32_t reserved : 10;
};
uint32_t val;
} constrain_reg_fields_t;
#define I_D_SRAM_SEGMENT_SIZE 0x10000
#define I_D_SPLIT_LINE_ALIGN 0x100
#define I_D_SPLIT_LINE_SHIFT 0x8
#define I_D_FAULT_ADDR_SHIFT 0x2
//IRAM0
#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_R 0x1
#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_W 0x2
#define SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_F 0x4
//DRAM0
#define SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_R 0x1
#define SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_SRAM_WORLD_X_W 0x2
//RTC FAST
#define SENSITIVE_CORE_X_PIF_PMS_CONSTRAIN_RTCFAST_WORLD_X_W 0x1
#define SENSITIVE_CORE_X_PIF_PMS_CONSTRAIN_RTCFAST_WORLD_X_R 0x2
#define SENSITIVE_CORE_X_PIF_PMS_CONSTRAIN_RTCFAST_WORLD_X_F 0x4
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -266,7 +266,8 @@
#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/
#define ETS_FRC1_INUM 22
#define ETS_T1_WDT_INUM 24
#define ETS_CACHEERR_INUM 25
#define ETS_MEMACCESS_ERR_INUM 25
#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

Wyświetl plik

@ -822,7 +822,6 @@ components/hal/esp32s2/include/hal/trace_ll.h
components/hal/esp32s2/include/hal/usb_ll.h
components/hal/esp32s2/touch_sensor_hal.c
components/hal/esp32s3/include/hal/aes_ll.h
components/hal/esp32s3/include/hal/memprot_ll.h
components/hal/esp32s3/include/hal/mpu_ll.h
components/hal/esp32s3/include/hal/rwdt_ll.h
components/hal/esp32s3/include/hal/sha_ll.h

Wyświetl plik

@ -1,9 +1,12 @@
cmake_minimum_required(VERSION 3.16)
if((IDF_TARGET STREQUAL "esp32s2") OR (IDF_TARGET STREQUAL "esp32c3"))
if((IDF_TARGET STREQUAL "esp32s2") OR (IDF_TARGET STREQUAL "esp32c3") OR (IDF_TARGET STREQUAL "esp32s3"))
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(test_memprot)
target_link_libraries(${project_elf} PRIVATE "-Wl,--wrap=esp_panic_handler")
target_link_libraries(${project_elf} PRIVATE
"-Wl,--wrap=esp_panic_handler"
"-Wl,--wrap=esp_panic_handler_reconfigure_wdts"
"-Wl,--wrap=soc_hal_stall_core")
endif()

Wyświetl plik

@ -1,2 +1,2 @@
| Supported Targets | ESP32-C3 | ESP32-S2 |
| ----------------- | -------- | -------- |
| Supported Targets | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- |

Wyświetl plik

@ -16,11 +16,31 @@ MEM_TEST_S2 = [
MEM_TEST_C3 = [
['IRAM0_SRAM', 'WRX'],
['DRAM0_SRAM', 'WR'],
['IRAM0_RTCFAST', 'WRX'],
['IRAM0_RTCFAST', 'WRX']
]
MEM_TEST_S3_MULTI = [
# instruction execute test temporarily disabled
# ['IRAM0_SRAM (core 0)', 'WRX'],
['IRAM0_SRAM (core 0)', 'WR'],
['DRAM0_SRAM (core 0)', 'WR'],
# instruction execute test temporarily disabled
# ['IRAM0_SRAM (core 1)', 'WRX'],
['IRAM0_SRAM (core 1)', 'WR'],
['DRAM0_SRAM (core 1)', 'WR']
# temporarily disabled unless IDF-5208 gets merged
# ['IRAM0_RTCFAST', 'WR'],
]
MEM_TEST_S3_UNI = [
['IRAM0_SRAM (core 0)', 'WRX'],
['DRAM0_SRAM (core 0)', 'WR']
# temporarily disabled unless IDF-5208 gets merged
# ['IRAM0_RTCFAST', 'WR'],
]
@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', target=['esp32c3', 'esp32s2'], group='test-apps')
@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', target=['esp32c3', 'esp32s2', 'esp32s3'], group='test-apps')
def test_memprot(env, extra_data):
dut = env.get_dut('memprot', 'tools/test_apps/system/memprot')
@ -29,10 +49,17 @@ def test_memprot(env, extra_data):
mem_test_cfg = []
current_target = dut.app.get_sdkconfig()['CONFIG_IDF_TARGET'].replace('"','').lower()
try:
unicore = dut.app.get_sdkconfig()['CONFIG_FREERTOS_UNICORE']
except KeyError:
unicore = 'n'
if current_target == 'esp32c3':
mem_test_cfg = MEM_TEST_C3
elif current_target == 'esp32s2':
mem_test_cfg = MEM_TEST_S2
elif current_target == 'esp32s3':
mem_test_cfg = MEM_TEST_S3_UNI if unicore == 'y' else MEM_TEST_S3_MULTI
Utility.console_log('Test cfg: ' + current_target)

Wyświetl plik

@ -4,4 +4,7 @@ if( IDF_TARGET STREQUAL "esp32s2" )
elseif( IDF_TARGET STREQUAL "esp32c3" )
idf_component_register(SRCS "esp32c3/test_memprot_main.c" "esp32c3/test_panic.c" "esp32c3/return_from_panic.S"
INCLUDE_DIRS "")
elseif( IDF_TARGET STREQUAL "esp32s3" )
idf_component_register(SRCS "esp32s3/test_memprot_main.c" "esp32s3/test_panic.c"
INCLUDE_DIRS "")
endif()

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -115,7 +115,7 @@ static void __attribute__((unused)) test_mprot_dump_status_register(esp_mprot_me
esp_rom_printf("FAULT [");
void *addr;
esp_err_t err = esp_mprot_get_violate_addr(mem_type, &addr, NULL);
esp_err_t err = esp_mprot_get_violate_addr(mem_type, &addr, DEFAULT_CPU_NUM);
if (err == ESP_OK) {
esp_rom_printf("fault addr: 0x%08X,", (uint32_t)addr);
} else {
@ -123,7 +123,7 @@ static void __attribute__((unused)) test_mprot_dump_status_register(esp_mprot_me
}
esp_mprot_pms_world_t world;
err = esp_mprot_get_violate_world(mem_type, &world, NULL);
err = esp_mprot_get_violate_world(mem_type, &world, DEFAULT_CPU_NUM);
if (err == ESP_OK) {
esp_rom_printf(" world: %s,", esp_mprot_pms_world_to_str(world));
} else {
@ -131,7 +131,7 @@ static void __attribute__((unused)) test_mprot_dump_status_register(esp_mprot_me
}
uint32_t oper;
err = esp_mprot_get_violate_operation(mem_type, &oper, NULL);
err = esp_mprot_get_violate_operation(mem_type, &oper, DEFAULT_CPU_NUM);
if (err == ESP_OK) {
esp_rom_printf(" operation: %s", esp_mprot_oper_type_to_str(oper));
} else {
@ -141,7 +141,7 @@ static void __attribute__((unused)) test_mprot_dump_status_register(esp_mprot_me
// DRAM/DMA fault: check byte-enables
if (mem_type == MEMPROT_TYPE_DRAM0_SRAM) {
uint32_t byteen;
err = esp_mprot_get_violate_byte_enables(mem_type, &byteen, NULL);
err = esp_mprot_get_violate_byte_enables(mem_type, &byteen, DEFAULT_CPU_NUM);
if (err == ESP_OK) {
esp_rom_printf(", byte en: 0x%08X", byteen);
} else {
@ -173,15 +173,15 @@ static void test_mprot_check_test_result(esp_mprot_mem_t mem_type, bool expected
static void test_mprot_clear_all_interrupts(void)
{
esp_err_t err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_SRAM, NULL);
esp_err_t err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_SRAM, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_SRAM) failed (%s) - test_mprot_clear_all_interrupts\n", esp_err_to_name(err));
}
err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_DRAM0_SRAM, NULL);
err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_DRAM0_SRAM, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr(MEMPROT_TYPE_DRAM0_SRAM) failed (%s) - test_mprot_clear_all_interrupts\n", esp_err_to_name(err));
}
err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_RTCFAST, NULL);
err = esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_RTCFAST, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr(MEMPROT_TYPE_IRAM0_RTCFAST) failed (%s) - test_mprot_clear_all_interrupts\n", esp_err_to_name(err));
}
@ -206,7 +206,7 @@ static void test_mprot_get_permissions(bool low, esp_mprot_mem_t mem_type, bool
}
uint32_t flags;
esp_err_t err = esp_mprot_get_pms_area(area, &flags);
esp_err_t err = esp_mprot_get_pms_area(area, &flags, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_get_pms_area() failed (%s) - test_mprot_get_permissions\n", esp_err_to_name(err));
return;
@ -240,17 +240,17 @@ static void test_mprot_set_permissions(bool low, esp_mprot_mem_t mem_type, bool
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM: {
if (low) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_0, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_0, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_1, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_1, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_2, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_2, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
} else {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_3, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_3, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
}
@ -258,17 +258,17 @@ static void test_mprot_set_permissions(bool low, esp_mprot_mem_t mem_type, bool
break;
case MEMPROT_TYPE_DRAM0_SRAM: {
if (low) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_0, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_0, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
} else {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_1, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_1, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_2, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_2, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_3, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_3, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
}
@ -276,11 +276,11 @@ static void test_mprot_set_permissions(bool low, esp_mprot_mem_t mem_type, bool
break;
case MEMPROT_TYPE_IRAM0_RTCFAST: {
if (low) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
} else {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI, flags)) != ESP_OK) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI, flags, DEFAULT_CPU_NUM)) != ESP_OK) {
break;
}
}
@ -311,7 +311,7 @@ static void test_mprot_read(esp_mprot_mem_t mem_type)
const uint32_t test_val = 100;
//temporarily allow WRITE for setting the test values
esp_err_t err = esp_mprot_set_monitor_en(mem_type, false);
esp_err_t err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
return;
@ -329,7 +329,7 @@ static void test_mprot_read(esp_mprot_mem_t mem_type)
test_mprot_set_permissions(false, mem_type, read_perm_high, write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
//reenable monitoring
err = esp_mprot_set_monitor_en(mem_type, true);
err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
return;
@ -337,7 +337,7 @@ static void test_mprot_read(esp_mprot_mem_t mem_type)
//perform READ test in low region
esp_rom_printf("%s read low: ", esp_mprot_mem_type_to_str(mem_type));
err = esp_mprot_monitor_clear_intr(mem_type, NULL);
err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
return;
@ -354,7 +354,7 @@ static void test_mprot_read(esp_mprot_mem_t mem_type)
//perform READ in high region
esp_rom_printf("%s read high: ", esp_mprot_mem_type_to_str(mem_type));
err = esp_mprot_monitor_clear_intr(mem_type, NULL);
err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
return;
@ -381,7 +381,7 @@ static void test_mprot_write(esp_mprot_mem_t mem_type)
test_mprot_get_permissions(false, mem_type, &read_perm_high, &write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
//ensure READ enabled
esp_err_t err = esp_mprot_set_monitor_en(mem_type, false);
esp_err_t err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
@ -390,7 +390,7 @@ static void test_mprot_write(esp_mprot_mem_t mem_type)
test_mprot_set_permissions(true, mem_type, true, write_perm_low, is_exec_mem ? &exec_perm_low : NULL);
test_mprot_set_permissions(false, mem_type, true, write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
err = esp_mprot_set_monitor_en(mem_type, true);
err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
@ -402,7 +402,7 @@ static void test_mprot_write(esp_mprot_mem_t mem_type)
//perform WRITE in low region
esp_rom_printf("%s write low: ", esp_mprot_mem_type_to_str(mem_type));
err = esp_mprot_monitor_clear_intr(mem_type, NULL);
err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
@ -421,7 +421,7 @@ static void test_mprot_write(esp_mprot_mem_t mem_type)
//perform WRITE in high region
esp_rom_printf("%s write high: ", esp_mprot_mem_type_to_str(mem_type));
err = esp_mprot_monitor_clear_intr(mem_type, NULL);
err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
@ -439,7 +439,7 @@ static void test_mprot_write(esp_mprot_mem_t mem_type)
}
//restore original permissions
err = esp_mprot_set_monitor_en(mem_type, false);
err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
@ -448,7 +448,7 @@ static void test_mprot_write(esp_mprot_mem_t mem_type)
test_mprot_set_permissions(true, mem_type, read_perm_low, write_perm_low, is_exec_mem ? &exec_perm_low : NULL);
test_mprot_set_permissions(false, mem_type, read_perm_high, write_perm_high, is_exec_mem ? &exec_perm_high : NULL);
err = esp_mprot_set_monitor_en(mem_type, true);
err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
@ -469,14 +469,14 @@ static void test_mprot_exec(esp_mprot_mem_t mem_type)
//temporarily enable READ/WRITE
test_mprot_get_permissions(true, mem_type, &read_perm_low, &write_perm_low, &exec_perm_low);
test_mprot_get_permissions(false, mem_type, &read_perm_high, &write_perm_high, &exec_perm_high);
esp_err_t err = esp_mprot_set_monitor_en(mem_type, false);
esp_err_t err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
}
test_mprot_set_permissions(true, mem_type, true, true, &exec_perm_low);
test_mprot_set_permissions(false, mem_type, true, true, &exec_perm_high);
err = esp_mprot_set_monitor_en(mem_type, true);
err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
@ -496,7 +496,7 @@ static void test_mprot_exec(esp_mprot_mem_t mem_type)
//LOW REGION: clear the intr flag & try to execute the code injected
esp_rom_printf("%s exec low: ", esp_mprot_mem_type_to_str(mem_type));
err = esp_mprot_monitor_clear_intr(mem_type, NULL);
err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
@ -522,7 +522,7 @@ static void test_mprot_exec(esp_mprot_mem_t mem_type)
//HIGH REGION: clear the intr-on flag & try to execute the code injected
esp_rom_printf("%s exec high: ", esp_mprot_mem_type_to_str(mem_type));
err = esp_mprot_monitor_clear_intr(mem_type, NULL);
err = esp_mprot_monitor_clear_intr(mem_type, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
@ -546,14 +546,14 @@ static void test_mprot_exec(esp_mprot_mem_t mem_type)
}
//restore original permissions
err = esp_mprot_set_monitor_en(mem_type, false);
err = esp_mprot_set_monitor_en(mem_type, false, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
}
test_mprot_set_permissions(true, mem_type, read_perm_low, write_perm_low, &exec_perm_low);
test_mprot_set_permissions(false, mem_type, read_perm_high, write_perm_high, &exec_perm_high);
err = esp_mprot_set_monitor_en(mem_type, true);
err = esp_mprot_set_monitor_en(mem_type, true, DEFAULT_CPU_NUM);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;

Wyświetl plik

@ -0,0 +1,691 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "hal/memprot_types.h"
#include "soc/memprot_defs.h"
#include "esp_private/esp_memprot_internal.h"
#include "esp_memprot.h"
#include "esp_rom_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
/**
* ESP32S3 MEMORY PROTECTION MODULE TEST
* =====================================
*
* In order to safely test all the memprot features, this test application uses memprot default settings
* plus proprietary testing buffers:
* - s_iram_test_buffer (.iram_end_test, 1kB) - all IRAM/DRAM low region operations, test-only section
* - s_dram_test_buffer (.dram0.data, 1kB) - all IRAM/DRAM high region operations, standard section
* - s_rtc_text_test_buffer (.rtc_text_end_test, 1kB) - all RTCFAST low region operations, test-only section
* - s_rtc_data_test_buffer (.rtc.data, 1kB) - all RTCFAST high region operations, standard section
* Testing addresses are set to the middle of the testing buffers:
* - test_ptr_low = (s_iram_test_buffer | s_rtc_text_test_buffer) + 0x200
* - test_ptr_high = (s_dram_test_buffer | s_rtc_data_test_buffer) + 0x200
* Each operation is tested at both low & high region addresses.
* Each test result checked against expected status of PMS violation interrupt status and
* against expected value stored in the memory tested (where applicable)
*
* Testing scheme is depicted below:
*
* DRam0/DMA IRam0
* -----------------------------------------------
* | IRam0_PMS_0 = IRam0_PMS_1 = IRam0_PMS_2 |
* | DRam0_PMS_0 |
* | |
* | |
* | - - - - - - - s_iram_test_buffer - - - - - -| IRam0_line1_Split_addr
* DRam0_DMA_line0_Split_addr | -- test_ptr_low -- | =
* = =============================================== IRam0_line0_Split_addr
* DRam0_DMA_line1_Split_addr | | =
* | - - - - - - - s_dram_test_buffer - - - - - --| IRam0_DRam0_Split_addr (main I/D)
* | -- test_ptr_high -- |
* | - - - - - - - - - - - - - - - - - - - - - - |
* | |
* | DRam0_PMS_1 = DRam0_PMS_2 = DRam0_PMS_3 |
* | IRam0_PMS_3 |
* | |
* | ... |
* | |
* =============================================== SOC_RTC_IRAM_LOW (0x50000000)
* | -- test_ptr_low -- |
* | - - - - - - s_rtc_text_test_buffer - - - - -| RtcFast_Split_addr (_rtc_text_end)
* | -- .rtc.dummy -- | (UNUSED - PADDING)
* 8 kB | - - - - - - - - - - - - - - - - - - - - - - | [_rtc_dummy_end = _rtc_force_fast_start]
* | -- .rtc.force_fast -- | (NOT USED IN THIS TEST)
* | - - - - - - s_rtc_data_test_buffer - - - - -| [_rtc_force_fast_end = _rtc_data_start]
* | -- test_ptr_high -- |
* | - - - - - - - - - - - - - - - - - - - - - - |
* =============================================== SOC_RTC_IRAM_HIGH (0x50001FFF)
* | |
* -----------------------------------------------
*/
/* !!!IMPORTANT!!!
* a0 needs to be saved/restored manually (not clobbered) to avoid return address corruption
* caused by ASM block handling
*/
#define CODE_EXEC(code_buf, param, res) \
asm volatile ( \
"mov a3, a0\n\t" \
"movi a2," #param "\n\t" \
"callx0 %1\n\t" \
"mov %0,a2\n\t" \
"mov a0, a3\n\t" \
: "=r"(res) \
: "r"(code_buf) \
: "a2", "a3" );
/* Binary code for the following asm:
*
.type _testfunc,@function
.global _testfunc
.align 4
_testfunc:
slli a2, a2, 1
ret.n
*/
static uint8_t s_fnc_buff[] = {0xf0, 0x22, 0x11, 0x0d, 0xf0, 0x00, 0x00, 0x00};
typedef int (*fnc_ptr)(int);
//testing buffers
#define SRAM_TEST_BUFFER_SIZE 0x400
#define SRAM_TEST_OFFSET 0x200
static uint8_t __attribute__((section(".iram_end_test"))) s_iram_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
static uint8_t __attribute__((section(".rtc_text_end_test"))) s_rtc_text_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
static uint8_t RTC_DATA_ATTR s_rtc_data_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
static uint8_t s_dram_test_buffer[SRAM_TEST_BUFFER_SIZE] = {0};
//auxiliary defines
#define LOW_REGION true
#define HIGH_REGION false
#define READ_ENA true
#define READ_DIS false
#define WRITE_ENA true
#define WRITE_DIS false
#define EXEC_ENA true
#define EXEC_DIS false
volatile bool g_override_illegal_instruction;
static void *test_mprot_addr_low(esp_mprot_mem_t mem_type)
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
return (void *)((uint32_t)s_iram_test_buffer + SRAM_TEST_OFFSET);
case MEMPROT_TYPE_DRAM0_SRAM:
return (void *)MAP_IRAM_TO_DRAM((uint32_t)s_iram_test_buffer + SRAM_TEST_OFFSET);
case MEMPROT_TYPE_IRAM0_RTCFAST:
return (void *)((uint32_t)s_rtc_text_test_buffer + SRAM_TEST_OFFSET);
default:
abort();
}
}
static void *test_mprot_addr_high(esp_mprot_mem_t mem_type)
{
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
return (void *)MAP_DRAM_TO_IRAM((uint32_t)s_dram_test_buffer + SRAM_TEST_OFFSET);
case MEMPROT_TYPE_DRAM0_SRAM:
return (void *)((uint32_t)s_dram_test_buffer + SRAM_TEST_OFFSET);
case MEMPROT_TYPE_IRAM0_RTCFAST:
return (void *)((uint32_t)s_rtc_data_test_buffer + SRAM_TEST_OFFSET);
default:
abort();
}
}
static void __attribute__((unused)) test_mprot_dump_status_register(esp_mprot_mem_t mem_type, const int core)
{
esp_rom_printf("FAULT [");
esp_rom_printf("core 0 dram0: 0x%08X, core 1 dram0: 0x%08X, ", REG_READ(SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_2_REG), REG_READ(SENSITIVE_CORE_1_DRAM0_PMS_MONITOR_2_REG));
esp_rom_printf("core 0 iram0: 0x%08X, core 1 iram0: 0x%08X, ", REG_READ(SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_2_REG), REG_READ(SENSITIVE_CORE_1_IRAM0_PMS_MONITOR_2_REG));
void *addr;
esp_err_t err = esp_mprot_get_violate_addr(mem_type, &addr, core);
if (err == ESP_OK) {
esp_rom_printf("fault addr: 0x%08X,", (uint32_t)addr);
} else {
esp_rom_printf("fault addr: N/A (%s),", esp_err_to_name(err));
}
esp_mprot_pms_world_t world;
err = esp_mprot_get_violate_world(mem_type, &world, core);
if (err == ESP_OK) {
esp_rom_printf(" world: %s,", esp_mprot_pms_world_to_str(world));
} else {
esp_rom_printf(" world: N/A (%s),", esp_err_to_name(err));
}
uint32_t oper;
err = esp_mprot_get_violate_operation(mem_type, &oper, core);
if (err == ESP_OK) {
esp_rom_printf(" operation: %s", esp_mprot_oper_type_to_str(oper));
} else {
esp_rom_printf(" operation: N/A (%s)", esp_err_to_name(err));
}
// DRAM/DMA fault: check byte-enables
if (mem_type == MEMPROT_TYPE_DRAM0_SRAM) {
uint32_t byteen;
err = esp_mprot_get_violate_byte_enables(mem_type, &byteen, core);
if (err == ESP_OK) {
esp_rom_printf(", byte en: 0x%08X", byteen);
} else {
esp_rom_printf(", byte en: N/A (%s)", esp_err_to_name(err));
}
}
esp_rom_printf( "]\n" );
}
static void test_mprot_check_test_result(esp_mprot_mem_t mem_type, bool expected_status)
{
esp_memp_intr_source_t memp_intr;
esp_err_t err = esp_mprot_get_active_intr(&memp_intr);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_get_active_intr() failed (%s) - test_mprot_check_test_result\n", esp_err_to_name(err));
return;
}
bool intr_on = memp_intr.mem_type == mem_type && memp_intr.core > -1;
bool test_result = expected_status ? !intr_on : intr_on;
if (test_result) {
esp_rom_printf("OK\n");
} else {
test_mprot_dump_status_register(mem_type, memp_intr.core);
}
}
static void test_mprot_get_permissions(bool low, esp_mprot_mem_t mem_type, bool *read, bool *write, bool *exec, const int core)
{
esp_mprot_pms_area_t area;
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM:
area = low ? MEMPROT_PMS_AREA_IRAM0_2 : MEMPROT_PMS_AREA_IRAM0_3;
break;
case MEMPROT_TYPE_DRAM0_SRAM:
area = low ? MEMPROT_PMS_AREA_DRAM0_0 : MEMPROT_PMS_AREA_DRAM0_1;
break;
case MEMPROT_TYPE_IRAM0_RTCFAST:
area = low ? MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO : MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI;
break;
default:
abort();
}
uint32_t flags;
esp_err_t err = esp_mprot_get_pms_area(area, &flags, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_get_pms_area() failed (%s) - test_mprot_get_permissions\n", esp_err_to_name(err));
return;
}
if (read) {
*read = flags & MEMPROT_OP_READ;
}
if (write) {
*write = flags & MEMPROT_OP_WRITE;
}
if (exec) {
*exec = flags & MEMPROT_OP_EXEC;
}
}
static void test_mprot_set_permissions(bool low, esp_mprot_mem_t mem_type, bool read, bool write, bool *exec, const int core)
{
esp_err_t err;
uint32_t flags = 0;
if (read) {
flags |= MEMPROT_OP_READ;
}
if (write) {
flags |= MEMPROT_OP_WRITE;
}
if (exec && *exec) {
flags |= MEMPROT_OP_EXEC;
}
switch (mem_type) {
case MEMPROT_TYPE_IRAM0_SRAM: {
if (low) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_0, flags, core)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_1, flags, core)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_2, flags, core)) != ESP_OK) {
break;
}
} else {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_3, flags, core)) != ESP_OK) {
break;
}
}
}
break;
case MEMPROT_TYPE_DRAM0_SRAM: {
if (low) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_0, flags, core)) != ESP_OK) {
break;
}
} else {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_1, flags, core)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_2, flags, core)) != ESP_OK) {
break;
}
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_DRAM0_3, flags, core)) != ESP_OK) {
break;
}
}
}
break;
case MEMPROT_TYPE_IRAM0_RTCFAST: {
if (low) {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_LO, flags, core)) != ESP_OK) {
break;
}
} else {
if ((err = esp_mprot_set_pms_area(MEMPROT_PMS_AREA_IRAM0_RTCFAST_HI, flags, core)) != ESP_OK) {
break;
}
}
}
break;
default:
abort();
}
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_pms_area() failed (%s) - test_mprot_set_permissions\n", esp_err_to_name(err));
}
}
static void test_mprot_read(esp_mprot_mem_t mem_type, const int core)
{
esp_err_t err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed on core %d (%s) - test_mprot_read\n", core, esp_err_to_name(err));
return;
}
//get current permission settings
bool write_perm_low, write_perm_high, read_perm_low, read_perm_high, exec_perm_low, exec_perm_high;
bool is_exec_mem = mem_type & MEMPROT_TYPE_IRAM0_ANY;
test_mprot_get_permissions(true, mem_type, &read_perm_low, &write_perm_low, is_exec_mem ? &exec_perm_low : NULL, core);
test_mprot_get_permissions(false, mem_type, &read_perm_high, &write_perm_high, is_exec_mem ? &exec_perm_high : NULL, core);
//get testing pointers for low & high regions
uint32_t *ptr_low = test_mprot_addr_low(mem_type);
uint32_t *ptr_high = test_mprot_addr_high(mem_type);
const uint32_t test_val = 100;
//temporarily allow WRITE for setting the test values
err = esp_mprot_set_monitor_en(mem_type, false, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
return;
}
test_mprot_set_permissions(LOW_REGION, mem_type, read_perm_low, WRITE_ENA, is_exec_mem ? &exec_perm_low : NULL, core);
test_mprot_set_permissions(HIGH_REGION, mem_type, read_perm_high, WRITE_ENA, is_exec_mem ? &exec_perm_high : NULL, core);
//store testing values to appropriate memory
*ptr_low = test_val;
*ptr_high = test_val + 1;
//restore current PMS settings
test_mprot_set_permissions(LOW_REGION, mem_type, read_perm_low, write_perm_low, is_exec_mem ? &exec_perm_low : NULL, core);
test_mprot_set_permissions(HIGH_REGION, mem_type, read_perm_high, write_perm_high, is_exec_mem ? &exec_perm_high : NULL, core);
//reenable monitoring
err = esp_mprot_set_monitor_en(mem_type, true, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
return;
}
//perform READ test in low region
esp_rom_printf("%s (core %d) read low: ", esp_mprot_mem_type_to_str(mem_type), core);
err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_read\n", esp_err_to_name(err));
return;
}
volatile uint32_t val = *ptr_low;
if (read_perm_low && val != test_val) {
esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val );
test_mprot_dump_status_register(mem_type, core);
} else {
test_mprot_check_test_result(mem_type, read_perm_low);
}
//perform READ in high region
esp_rom_printf("%s (core %d) read high: ", esp_mprot_mem_type_to_str(mem_type), core);
err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed on core %d (%s) - test_mprot_read\n", core, esp_err_to_name(err));
return;
}
val = *ptr_high;
if (read_perm_high && val != (test_val + 1)) {
esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
test_mprot_dump_status_register(mem_type, core);
} else {
test_mprot_check_test_result(mem_type, read_perm_high);
}
esp_mprot_monitor_clear_intr(mem_type, core);
//test_mprot_dump_status_register(mem_type, core);
}
static void test_mprot_write(esp_mprot_mem_t mem_type, const int core)
{
esp_err_t err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed on core %d (%s) - test_mprot_write\n", core, esp_err_to_name(err));
return;
}
//get current READ & WRITE permission settings
bool write_perm_low, write_perm_high, read_perm_low, read_perm_high, exec_perm_low, exec_perm_high;
bool is_exec_mem = mem_type & MEMPROT_TYPE_IRAM0_ANY;
test_mprot_get_permissions(LOW_REGION, mem_type, &read_perm_low, &write_perm_low, is_exec_mem ? &exec_perm_low : NULL, core);
test_mprot_get_permissions(HIGH_REGION, mem_type, &read_perm_high, &write_perm_high, is_exec_mem ? &exec_perm_high : NULL, core);
//ensure READ enabled
err = esp_mprot_set_monitor_en(mem_type, false, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
}
test_mprot_set_permissions(LOW_REGION, mem_type, READ_ENA, write_perm_low, is_exec_mem ? &exec_perm_low : NULL, core);
test_mprot_set_permissions(HIGH_REGION, mem_type, READ_ENA, write_perm_high, is_exec_mem ? &exec_perm_high : NULL, core);
err = esp_mprot_set_monitor_en(mem_type, true, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
}
volatile uint32_t *ptr_low = test_mprot_addr_low(mem_type);
volatile uint32_t *ptr_high = test_mprot_addr_high(mem_type);
const uint32_t test_val = 10;
//perform WRITE in low region
esp_rom_printf("%s (core %d) write low: ", esp_mprot_mem_type_to_str(mem_type), core);
err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed on core %d (%s) - test_mprot_write\n", core, esp_err_to_name(err));
return;
}
volatile uint32_t val = 0;
*ptr_low = test_val;
val = *ptr_low;
if (write_perm_low && val != test_val) {
esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
test_mprot_dump_status_register(mem_type, core);
} else {
test_mprot_check_test_result(mem_type, write_perm_low);
}
//perform WRITE in high region
esp_rom_printf("%s (core %d) write high: ", esp_mprot_mem_type_to_str(mem_type), core);
err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed on core %d (%s) - test_mprot_write\n", core, esp_err_to_name(err));
return;
}
val = 0;
*ptr_high = test_val + 1;
val = *ptr_high;
if (val != (test_val + 1) && write_perm_high) {
esp_rom_printf( "UNEXPECTED VALUE 0x%08X -", val);
test_mprot_dump_status_register(mem_type, core);
} else {
test_mprot_check_test_result(mem_type, write_perm_high);
}
//restore original permissions
err = esp_mprot_set_monitor_en(mem_type, false, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
}
test_mprot_set_permissions(LOW_REGION, mem_type, read_perm_low, write_perm_low, is_exec_mem ? &exec_perm_low : NULL, core);
test_mprot_set_permissions(HIGH_REGION, mem_type, read_perm_high, write_perm_high, is_exec_mem ? &exec_perm_high : NULL, core);
err = esp_mprot_set_monitor_en(mem_type, true, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_write\n", esp_err_to_name(err));
return;
}
esp_mprot_monitor_clear_intr(mem_type, core);
}
static void test_mprot_exec(esp_mprot_mem_t mem_type, const int core)
{
if (!(mem_type & MEMPROT_TYPE_IRAM0_ANY)) {
esp_rom_printf("Error: EXEC test available only for IRAM access.\n" );
return;
}
esp_err_t err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed on core %d (%s) - test_mprot_exec\n", core, esp_err_to_name(err));
return;
}
err = esp_mprot_set_monitor_en(mem_type, false, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
}
//get require mem_type permissions
bool write_perm_low, write_perm_high, read_perm_low, read_perm_high, exec_perm_low, exec_perm_high;
test_mprot_get_permissions(LOW_REGION, mem_type, &read_perm_low, &write_perm_low, &exec_perm_low, core);
test_mprot_get_permissions(HIGH_REGION, mem_type, &read_perm_high, &write_perm_high, &exec_perm_high, core);
void *fnc_ptr_low = NULL;
void *fnc_ptr_high = NULL;
if (mem_type == MEMPROT_TYPE_IRAM0_SRAM) {
//temporarily enable WRITE for DBUS
test_mprot_set_permissions(LOW_REGION, MEMPROT_TYPE_DRAM0_SRAM, READ_ENA, WRITE_ENA, NULL, core);
//get testing pointers for low & high regions using DBUS FOR CODE INJECTION!
fnc_ptr_low = test_mprot_addr_low(MEMPROT_TYPE_DRAM0_SRAM);
fnc_ptr_high = test_mprot_addr_high(MEMPROT_TYPE_DRAM0_SRAM);
//inject the code to both low & high segments
memcpy(fnc_ptr_low, (const void *) s_fnc_buff, sizeof(s_fnc_buff));
memcpy(fnc_ptr_high, (const void *) s_fnc_buff, sizeof(s_fnc_buff));
fnc_ptr_low = (void *) MAP_DRAM_TO_IRAM(fnc_ptr_low);
fnc_ptr_high = (void *) MAP_DRAM_TO_IRAM(fnc_ptr_high);
//reenable DBUS protection
test_mprot_set_permissions(LOW_REGION, MEMPROT_TYPE_DRAM0_SRAM, READ_ENA, WRITE_DIS, NULL, core);
} else if (mem_type == MEMPROT_TYPE_IRAM0_RTCFAST) {
//enable WRITE for low region
test_mprot_set_permissions(LOW_REGION, MEMPROT_TYPE_IRAM0_RTCFAST, read_perm_low, WRITE_ENA, &exec_perm_low, core);
fnc_ptr_low = test_mprot_addr_low(MEMPROT_TYPE_IRAM0_RTCFAST);
fnc_ptr_high = test_mprot_addr_high(MEMPROT_TYPE_IRAM0_RTCFAST);
//inject the code to both low & high segments
memcpy(fnc_ptr_low, (const void *) s_fnc_buff, sizeof(s_fnc_buff));
memcpy(fnc_ptr_high, (const void *) s_fnc_buff, sizeof(s_fnc_buff));
//reenable original protection
test_mprot_set_permissions(LOW_REGION, MEMPROT_TYPE_IRAM0_RTCFAST, read_perm_low, write_perm_low, &exec_perm_low, core);
} else {
assert(0);
}
uint32_t res = 0;
//LOW REGION: clear the intr flag & try to execute the code injected
esp_rom_printf("%s (core %d) exec low: ", esp_mprot_mem_type_to_str(mem_type), core);
err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
}
err = esp_mprot_set_monitor_en(mem_type, true, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_monitor_en() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
}
fnc_ptr fnc = (fnc_ptr)fnc_ptr_low;
g_override_illegal_instruction = true;
CODE_EXEC(fnc, 5, res)
g_override_illegal_instruction = false;
//check results
bool fnc_call_ok = res == 10;
if (fnc_call_ok) {
test_mprot_check_test_result(mem_type, exec_perm_low);
} else {
if (!exec_perm_low) {
test_mprot_check_test_result(mem_type, false);
} else {
esp_rom_printf(" FAULT [injected code not executed]\n");
}
}
//HIGH REGION: clear the intr-on flag & try to execute the code injected
esp_rom_printf("%s (core %d) exec high: ", esp_mprot_mem_type_to_str(mem_type), core);
err = esp_mprot_monitor_clear_intr(mem_type, core);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_monitor_clear_intr() failed (%s) - test_mprot_exec\n", esp_err_to_name(err));
return;
}
fnc = (fnc_ptr)fnc_ptr_high;
g_override_illegal_instruction = true;
CODE_EXEC(fnc, 6, res)
g_override_illegal_instruction = false;
fnc_call_ok = res == 12;
if (fnc_call_ok) {
test_mprot_check_test_result(mem_type, exec_perm_high);
} else {
if (!exec_perm_high) {
test_mprot_check_test_result(mem_type, false);
} else {
esp_rom_printf(" FAULT [injected code not executed]\n");
}
}
esp_mprot_monitor_clear_intr(mem_type, core);
}
// testing per-CPU tasks
esp_memp_config_t memp_cfg = {
.invoke_panic_handler = false,
.lock_feature = false,
.split_addr = NULL,
.mem_type_mask = MEMPROT_TYPE_IRAM0_SRAM | MEMPROT_TYPE_DRAM0_SRAM,
#if portNUM_PROCESSORS > 1
.target_cpu_count = 2,
.target_cpu = {PRO_CPU_NUM, APP_CPU_NUM}
#else
.target_cpu_count = 1,
.target_cpu = {PRO_CPU_NUM}
#endif
};
typedef struct {
int core;
SemaphoreHandle_t sem;
} test_ctx_t;
static void task_on_CPU(void *arg)
{
test_ctx_t *ctx = (test_ctx_t *)arg;
if (memp_cfg.mem_type_mask & MEMPROT_TYPE_IRAM0_SRAM) {
test_mprot_read(MEMPROT_TYPE_IRAM0_SRAM, ctx->core);
test_mprot_write(MEMPROT_TYPE_IRAM0_SRAM, ctx->core);
/* temporarily disabled */
//test_mprot_exec(MEMPROT_TYPE_IRAM0_SRAM, ctx->core);
}
if (memp_cfg.mem_type_mask & MEMPROT_TYPE_DRAM0_SRAM) {
test_mprot_read(MEMPROT_TYPE_DRAM0_SRAM, ctx->core);
test_mprot_write(MEMPROT_TYPE_DRAM0_SRAM, ctx->core);
}
if (memp_cfg.mem_type_mask & MEMPROT_TYPE_IRAM0_RTCFAST) {
test_mprot_read(MEMPROT_TYPE_IRAM0_RTCFAST, ctx->core);
test_mprot_write(MEMPROT_TYPE_IRAM0_RTCFAST, ctx->core);
test_mprot_exec(MEMPROT_TYPE_IRAM0_RTCFAST, ctx->core);
}
xSemaphoreGive(ctx->sem);
vTaskDelete(NULL);
}
/* ********************************************************************************************
* main test runner
*/
void app_main(void)
{
esp_err_t err = esp_mprot_set_prot(&memp_cfg);
if (err != ESP_OK) {
esp_rom_printf("Error: esp_mprot_set_prot() failed (%s) - app_main\n", esp_err_to_name(err));
return;
}
//test each core separate
test_ctx_t ctx = {
.sem = xSemaphoreCreateBinary(),
.core = PRO_CPU_NUM
};
xTaskCreatePinnedToCore(task_on_CPU, "task_PRO_CPU", 4096, &ctx, 3, NULL, PRO_CPU_NUM);
xSemaphoreTake(ctx.sem, portMAX_DELAY);
//multicore setup
if (portNUM_PROCESSORS > 1) {
ctx.core = APP_CPU_NUM;
xTaskCreatePinnedToCore(task_on_CPU, "task_APP_CPU", 4096, &ctx, 3, NULL, APP_CPU_NUM);
xSemaphoreTake(ctx.sem, portMAX_DELAY);
}
}

Wyświetl plik

@ -0,0 +1,78 @@
/*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "freertos/xtensa_context.h"
#include "esp_private/panic_internal.h"
#include "hal/wdt_hal.h"
extern void esp_panic_handler(panic_info_t *info);
extern volatile bool g_override_illegal_instruction;
void __real_esp_panic_handler(panic_info_t *info);
void __real_esp_panic_handler_reconfigure_wdts(void);
void __real_soc_hal_stall_core(int core);
static void disable_all_wdts(void)
{
wdt_hal_context_t wdt0_context = {.inst = WDT_MWDT0, .mwdt_dev = &TIMERG0};
#if SOC_TIMER_GROUPS >= 2
wdt_hal_context_t wdt1_context = {.inst = WDT_MWDT1, .mwdt_dev = &TIMERG1};
#endif
//Todo: Refactor to use Interrupt or Task Watchdog API, and a system level WDT context
//Task WDT is the Main Watchdog Timer of Timer Group 0
wdt_hal_write_protect_disable(&wdt0_context);
wdt_hal_disable(&wdt0_context);
wdt_hal_write_protect_enable(&wdt0_context);
#if SOC_TIMER_GROUPS >= 2
//Interupt WDT is the Main Watchdog Timer of Timer Group 1
wdt_hal_write_protect_disable(&wdt1_context);
wdt_hal_disable(&wdt1_context);
wdt_hal_write_protect_enable(&wdt1_context);
#endif
}
/* Memprot test specific IllegalInstruction exception handler:
* when testing the protection against a code execution, sample code
* is being injected into various memory regions which produces
* EXCCAUSE_ILLEGAL on execution attempt. Such a result is expected
* but it causes system reboot in the standard panic handler.
* The following variant of panic handling simply returns back to the
* next instruction and continues normal execution.
*
* NOTE: if EXCCAUSE_ILLEGAL comes from a different source than the testing code
* the behavior is undefined
* */
void __wrap_esp_panic_handler(panic_info_t *info)
{
XtExcFrame *frm = (XtExcFrame *)info->frame;
if ( frm->exccause == EXCCAUSE_ILLEGAL && g_override_illegal_instruction == true ) {
frm->pc = frm->a0;
return;
} else {
__real_esp_panic_handler(info);
}
}
void __wrap_esp_panic_handler_reconfigure_wdts(void)
{
if ( g_override_illegal_instruction == true ) {
disable_all_wdts();
return;
} else {
__real_esp_panic_handler_reconfigure_wdts();
}
}
void __wrap_soc_hal_stall_core(int core)
{
if ( g_override_illegal_instruction == true ) {
return;
} else {
__real_soc_hal_stall_core(core);
}
}