risc-v/esp32c3: Disable access to invalid memory regions using MPU
Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
This commit is contained in:
parent
88bfadc55d
commit
5805ad3954
|
@ -156,6 +156,13 @@ config ESP32C3_CPU_FREQ_MHZ
|
|||
default 80 if ESP32C3_CPU_FREQ_80
|
||||
default 160 if ESP32C3_CPU_FREQ_160
|
||||
|
||||
config ESP32C3_REGION_PROTECTION
|
||||
bool "Enable region protection"
|
||||
default y
|
||||
select ARCH_USE_MPU
|
||||
---help---
|
||||
Configure the MPU to disable access to invalid memory regions.
|
||||
|
||||
config ESP32C3_RT_TIMER
|
||||
bool "Real-time Timer"
|
||||
default n
|
||||
|
|
|
@ -41,6 +41,10 @@ CHIP_CSRCS += esp32c3_lowputc.c esp32c3_serial.c
|
|||
CHIP_CSRCS += esp32c3_systemreset.c esp32c3_resetcause.c
|
||||
CHIP_CSRCS += esp32c3_uid.c
|
||||
|
||||
ifeq ($(CONFIG_ESP32C3_REGION_PROTECTION),y)
|
||||
CHIP_CSRCS += esp32c3_region.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||
CHIP_CSRCS += esp32c3_userspace.c
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/esp32c3/esp32c3_region.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
#include "hardware/esp32c3_soc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
/* BUILD_PROTECTED also makes use of the ESP32-C3 PMP (MPU) for isolating
|
||||
* the Kernel from the Userspace.
|
||||
*/
|
||||
|
||||
# error "ESP32C3_REGION_PROTECTION shall not be enabled with Protected Mode"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_region_protection
|
||||
*
|
||||
* Description:
|
||||
* Configure the MPU to disable access to invalid memory regions.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
* Notes:
|
||||
* 1) ESP32-C3 CPU doesn't support overlapping PMP regions.
|
||||
* 2) Therefore, we use TOR (top of range) entries to map the whole address
|
||||
* space, bottom to top.
|
||||
* 3) There are not enough entries to describe all the memory regions 100%
|
||||
* accurately.
|
||||
* 4) This means some gaps (invalid memory) are accessible. Priority for
|
||||
* extending regions to cover gaps is to extend read-only or read-execute
|
||||
* regions or read-only regions only (executing unmapped addresses should
|
||||
* always fault with invalid instruction, read-only means stores will
|
||||
* correctly fault even if reads may return some invalid value).
|
||||
* 5) Entries are grouped in order with some static asserts to try and verify
|
||||
* everything is correct.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32C3_REGION_PROTECTION
|
||||
void esp32c3_region_protection(void)
|
||||
{
|
||||
const uintptr_t R = PMPCFG_L | PMPCFG_R;
|
||||
const uintptr_t RW = PMPCFG_L | PMPCFG_R | PMPCFG_W;
|
||||
const uintptr_t RX = PMPCFG_L | PMPCFG_R | PMPCFG_X;
|
||||
const uintptr_t RWX = PMPCFG_L | PMPCFG_R | PMPCFG_W | PMPCFG_X;
|
||||
|
||||
/* 1. Gap at bottom of address space */
|
||||
|
||||
riscv_config_pmp_region(0, PMPCFG_A_TOR, SOC_DEBUG_LOW, 0);
|
||||
|
||||
/* 2. Debug region */
|
||||
|
||||
riscv_config_pmp_region(1, PMPCFG_A_TOR | RWX, SOC_DEBUG_HIGH, 0);
|
||||
static_assert(SOC_DEBUG_LOW < SOC_DEBUG_HIGH, "Invalid CPU debug region");
|
||||
|
||||
/* 3. Gap between debug region & DROM (flash cache) */
|
||||
|
||||
riscv_config_pmp_region(2, PMPCFG_A_TOR, SOC_DROM_LOW, 0);
|
||||
static_assert(SOC_DEBUG_HIGH < SOC_DROM_LOW, "Invalid PMP entry order");
|
||||
|
||||
/* 4. DROM (flash cache)
|
||||
* 5. Gap between DROM & DRAM
|
||||
* Note: To save PMP entries these two are merged into one read-only region
|
||||
*/
|
||||
|
||||
riscv_config_pmp_region(3, PMPCFG_A_TOR | R, SOC_DRAM_LOW, 0);
|
||||
static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid DROM region");
|
||||
static_assert(SOC_DROM_HIGH < SOC_DRAM_LOW, "Invalid PMP entry order");
|
||||
|
||||
/* 6. DRAM */
|
||||
|
||||
riscv_config_pmp_region(4, PMPCFG_A_TOR | RW, SOC_DRAM_HIGH, 0);
|
||||
static_assert(SOC_DRAM_LOW < SOC_DRAM_HIGH, "Invalid DRAM region");
|
||||
|
||||
/* 7. Gap between DRAM and Mask DROM
|
||||
* 8. Mask DROM
|
||||
* Note: to save PMP entries these two are merged into one read-only region
|
||||
*/
|
||||
|
||||
riscv_config_pmp_region(5, PMPCFG_A_TOR | R, SOC_DROM_MASK_HIGH, 0);
|
||||
static_assert(SOC_DRAM_HIGH < SOC_DROM_MASK_LOW,
|
||||
"Invalid PMP entry order");
|
||||
static_assert(SOC_DROM_MASK_LOW < SOC_DROM_MASK_HIGH,
|
||||
"Invalid mask DROM region");
|
||||
|
||||
/* 9. Gap between mask DROM and mask IROM
|
||||
* 10. Mask IROM
|
||||
* Note: to save PMP entries these two are merged into one RX region
|
||||
*/
|
||||
|
||||
riscv_config_pmp_region(6, PMPCFG_A_TOR | RX, SOC_IROM_MASK_HIGH, 0);
|
||||
static_assert(SOC_DROM_MASK_HIGH < SOC_IROM_MASK_LOW,
|
||||
"Invalid PMP entry order");
|
||||
static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH,
|
||||
"Invalid mask IROM region");
|
||||
|
||||
/* 11. Gap between mask IROM & IRAM */
|
||||
|
||||
riscv_config_pmp_region(7, PMPCFG_A_TOR, SOC_IRAM_LOW, 0);
|
||||
static_assert(SOC_IROM_MASK_HIGH < SOC_IRAM_LOW,
|
||||
"Invalid PMP entry order");
|
||||
|
||||
/* 12. IRAM */
|
||||
|
||||
riscv_config_pmp_region(8, PMPCFG_A_TOR | RWX, SOC_IRAM_HIGH, 0);
|
||||
static_assert(SOC_IRAM_LOW < SOC_IRAM_HIGH, "Invalid IRAM region");
|
||||
|
||||
/* 13. Gap between IRAM and IROM
|
||||
* 14. IROM (flash cache)
|
||||
* Note: to save PMP entries these two are merged into one RX region
|
||||
*/
|
||||
|
||||
riscv_config_pmp_region(9, PMPCFG_A_TOR | RX, SOC_IROM_HIGH, 0);
|
||||
static_assert(SOC_IRAM_HIGH < SOC_IROM_LOW, "Invalid PMP entry order");
|
||||
static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid IROM region");
|
||||
|
||||
/* 15. Gap between IROM & RTC slow memory */
|
||||
|
||||
riscv_config_pmp_region(10, PMPCFG_A_TOR, SOC_RTC_RAM_LOW, 0);
|
||||
static_assert(SOC_IROM_HIGH < SOC_RTC_RAM_LOW, "Invalid PMP entry order");
|
||||
|
||||
/* 16. RTC fast memory */
|
||||
|
||||
riscv_config_pmp_region(11, PMPCFG_A_TOR | RWX, SOC_RTC_RAM_HIGH, 0);
|
||||
static_assert(SOC_RTC_RAM_LOW < SOC_RTC_RAM_HIGH,
|
||||
"Invalid RTC IRAM region");
|
||||
|
||||
/* 17. Gap between RTC fast memory & peripheral addresses */
|
||||
|
||||
riscv_config_pmp_region(12, PMPCFG_A_TOR, SOC_PERIPHERAL_LOW, 0);
|
||||
static_assert(SOC_RTC_RAM_HIGH < SOC_PERIPHERAL_LOW,
|
||||
"Invalid PMP entry order");
|
||||
|
||||
/* 18. Peripheral addresses */
|
||||
|
||||
riscv_config_pmp_region(13, PMPCFG_A_TOR | RW, SOC_PERIPHERAL_HIGH, 0);
|
||||
static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH,
|
||||
"Invalid peripheral region");
|
||||
|
||||
/* 19. End of address space */
|
||||
|
||||
riscv_config_pmp_region(14, PMPCFG_A_TOR, UINT32_MAX, 0);
|
||||
riscv_config_pmp_region(15, PMPCFG_A_NA4, UINT32_MAX, 0);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/esp32c3/esp32c3_region.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_REGION_H
|
||||
#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_REGION_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_region_protection
|
||||
*
|
||||
* Description:
|
||||
* Configure the MPU to disable access to invalid memory regions.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_region_protection(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#undef EXTERN
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_REGION_H */
|
|
@ -36,6 +36,9 @@
|
|||
#include "esp32c3_clockconfig.h"
|
||||
#include "esp32c3_irq.h"
|
||||
#include "esp32c3_lowputc.h"
|
||||
#ifdef CONFIG_ESP32C3_REGION_PROTECTION
|
||||
#include "esp32c3_region.h"
|
||||
#endif
|
||||
#include "esp32c3_rtc.h"
|
||||
#include "esp32c3_start.h"
|
||||
#include "esp32c3_wdt.h"
|
||||
|
@ -243,6 +246,12 @@ void __esp32c3_start(void)
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ESP32C3_REGION_PROTECTION
|
||||
/* Configure region protection */
|
||||
|
||||
esp32c3_region_protection();
|
||||
#endif
|
||||
|
||||
/* Initialize RTC parameters */
|
||||
|
||||
esp32c3_rtc_init();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_ESP32C3_REGION_PROTECTION is not set
|
||||
# CONFIG_NSH_ARGCAT is not set
|
||||
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
|
||||
# CONFIG_NSH_CMDPARMS is not set
|
||||
|
|
Loading…
Reference in New Issue