You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2021/05/23 11:37:37 UTC
[incubator-nuttx] branch master updated: riscv/esp32c3: Support SPI
Flash encryption read/write
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 76df958 riscv/esp32c3: Support SPI Flash encryption read/write
76df958 is described below
commit 76df958e34cc5e1cf32a204c3b6ce524eb644496
Author: Dong Heng <do...@espressif.com>
AuthorDate: Tue May 11 15:08:29 2021 +0800
riscv/esp32c3: Support SPI Flash encryption read/write
---
arch/risc-v/src/esp32c3/esp32c3_spiflash.c | 246 ++++++++++++++++++++-
boards/risc-v/esp32c3/esp32c3-devkit/Kconfig | 16 ++
.../esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld | 6 +-
.../esp32c3/esp32c3-devkit/src/esp32c3-devkit.h | 18 ++
.../esp32c3/esp32c3-devkit/src/esp32c3_bringup.c | 5 +
.../esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c | 9 +-
6 files changed, 288 insertions(+), 12 deletions(-)
diff --git a/arch/risc-v/src/esp32c3/esp32c3_spiflash.c b/arch/risc-v/src/esp32c3/esp32c3_spiflash.c
index 96f19ad..41e9810 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_spiflash.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_spiflash.c
@@ -36,13 +36,41 @@
#include <nuttx/semaphore.h>
#include <nuttx/mtd/mtd.h>
+#include "esp32c3_attr.h"
#include "esp32c3_spiflash.h"
#include "rom/esp32c3_spiflash.h"
+#include "hardware/esp32c3_soc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
+/* RO data page in MMU index */
+
+#define DROM0_PAGES_START (2)
+#define DROM0_PAGES_END (128)
+
+/* MMU invalid value */
+
+#define INVALID_MMU_VAL (0x100)
+
+/* MMU page size */
+
+#define SPI_FLASH_MMU_PAGE_SIZE (0x10000)
+
+/* MMU base virtual mapped address */
+
+#define VADDR0_START_ADDR (0x3c020000)
+
+/* Flash MMU table for CPU */
+
+#define MMU_TABLE ((volatile uint32_t *)DR_REG_MMU_TABLE)
+
+#define MMU_ADDR2PAGE(_addr) ((_addr) / SPI_FLASH_MMU_PAGE_SIZE)
+#define MMU_ADDR2OFF(_addr) ((_addr) % SPI_FLASH_MMU_PAGE_SIZE)
+#define MMU_BYTES2PAGES(_n) (((_n) + SPI_FLASH_MMU_PAGE_SIZE - 1) / \
+ SPI_FLASH_MMU_PAGE_SIZE)
+
#define SPI_FLASH_BLK_SIZE 256
#define SPI_FLASH_ERASE_SIZE 4096
#define SPI_FLASH_SIZE (4 * 1024 * 1024)
@@ -72,6 +100,37 @@ struct esp32c3_spiflash_s
const struct spiflash_legacy_data_s **data;
};
+/* SPI Flash map request data */
+
+struct spiflash_map_req_s
+{
+ /* Request mapping SPI Flash base address */
+
+ uint32_t src_addr;
+
+ /* Request mapping SPI Flash size */
+
+ uint32_t size;
+
+ /* Mapped memory pointer */
+
+ void *ptr;
+
+ /* Mapped started MMU page index */
+
+ uint32_t start_page;
+
+ /* Mapped MMU page count */
+
+ uint32_t page_cnt;
+};
+
+struct spiflash_cachestate_s
+{
+ irqstate_t flags;
+ uint32_t val;
+};
+
/****************************************************************************
* Private Functions Prototypes
****************************************************************************/
@@ -104,6 +163,14 @@ static int esp32c3_ioctl(struct mtd_dev_s *dev, int cmd,
unsigned long arg);
/****************************************************************************
+ * Public Functions Declaration
+ ****************************************************************************/
+
+extern int cache_invalidate_addr(uint32_t addr, uint32_t size);
+extern uint32_t cache_suspend_icache(void);
+extern void cache_resume_icache(uint32_t val);
+
+/****************************************************************************
* Public Data
****************************************************************************/
@@ -155,6 +222,175 @@ static sem_t g_exclsem = SEM_INITIALIZER(1);
****************************************************************************/
/****************************************************************************
+ * Name: spiflash_opstart
+ *
+ * Description:
+ * Prepare for an SPIFLASH operation.
+ *
+ ****************************************************************************/
+
+static inline void spiflash_opstart(struct spiflash_cachestate_s *state)
+{
+ state->flags = enter_critical_section();
+ state->val = cache_suspend_icache() << 16;
+}
+
+/****************************************************************************
+ * Name: spiflash_opdone
+ *
+ * Description:
+ * Undo all the steps of opstart.
+ *
+ ****************************************************************************/
+
+static inline void spiflash_opdone(const struct spiflash_cachestate_s *state)
+{
+ cache_resume_icache(state->val >> 16);
+ leave_critical_section(state->flags);
+}
+
+/****************************************************************************
+ * Name: esp32c3_mmap
+ *
+ * Description:
+ * Mapped SPI Flash address to ESP32-C3's address bus, so that software
+ * can read SPI Flash data by reading data from memory access.
+ *
+ * If SPI Flash hardware encryption is enable, the read from mapped
+ * address is decrypted.
+ *
+ * Input Parameters:
+ * req - SPI Flash mapping requesting parameters
+ *
+ * Returned Value:
+ * 0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR esp32c3_mmap(struct spiflash_map_req_s *req)
+{
+ int ret;
+ int i;
+ int start_page;
+ int flash_page;
+ int page_cnt;
+ uint32_t mapped_addr;
+ struct spiflash_cachestate_s state;
+
+ spiflash_opstart(&state);
+
+ for (start_page = DROM0_PAGES_START;
+ start_page < DROM0_PAGES_END;
+ ++start_page)
+ {
+ if (MMU_TABLE[start_page] == INVALID_MMU_VAL)
+ {
+ break;
+ }
+ }
+
+ flash_page = MMU_ADDR2PAGE(req->src_addr);
+ page_cnt = MMU_BYTES2PAGES(req->size);
+
+ if (start_page + page_cnt < DROM0_PAGES_END)
+ {
+ mapped_addr = (start_page - DROM0_PAGES_START) *
+ SPI_FLASH_MMU_PAGE_SIZE +
+ VADDR0_START_ADDR;
+
+ for (i = 0; i < page_cnt; i++)
+ {
+ MMU_TABLE[start_page + i] = flash_page + i;
+ cache_invalidate_addr(mapped_addr + i * SPI_FLASH_MMU_PAGE_SIZE,
+ SPI_FLASH_MMU_PAGE_SIZE);
+ }
+
+ req->start_page = start_page;
+ req->page_cnt = page_cnt;
+ req->ptr = (void *)(mapped_addr + MMU_ADDR2OFF(req->src_addr));
+ ret = OK;
+ }
+ else
+ {
+ ret = -ENOBUFS;
+ }
+
+ spiflash_opdone(&state);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: esp32c3_ummap
+ *
+ * Description:
+ * Unmap SPI Flash address in ESP32-C3's address bus, and free resource.
+ *
+ * Input Parameters:
+ * req - SPI Flash mapping requesting parameters
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_ummap(const struct spiflash_map_req_s *req)
+{
+ int i;
+ struct spiflash_cachestate_s state;
+
+ spiflash_opstart(&state);
+
+ for (i = req->start_page; i < req->start_page + req->page_cnt; ++i)
+ {
+ MMU_TABLE[i] = INVALID_MMU_VAL;
+ }
+
+ spiflash_opdone(&state);
+}
+
+/****************************************************************************
+ * Name: esp32c3_readdata_encrypted
+ *
+ * Description:
+ * Read decrypted data from SPI Flash at designated address when
+ * enable SPI Flash hardware encryption.
+ *
+ * Input Parameters:
+ * addr - target address
+ * buffer - data buffer pointer
+ * size - data number
+ *
+ * Returned Value:
+ * OK if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+static IRAM_ATTR int esp32c3_readdata_encrypted(uint32_t addr,
+ uint8_t *buffer,
+ uint32_t size)
+{
+ int ret;
+ struct spiflash_map_req_s req =
+ {
+ .src_addr = addr,
+ .size = size
+ };
+
+ ret = esp32c3_mmap(&req);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ memcpy(buffer, req.ptr, size);
+
+ esp32c3_ummap(&req);
+
+ return OK;
+}
+
+/****************************************************************************
* Name: esp32c3_erase
*
* Description:
@@ -359,7 +595,7 @@ static ssize_t esp32c3_read_decrypt(struct mtd_dev_s *dev,
return ret;
}
- ret = spi_flash_read_encrypted(offset, buffer, nbytes);
+ ret = esp32c3_readdata_encrypted(offset, buffer, nbytes);
nxsem_post(&g_exclsem);
@@ -393,9 +629,9 @@ static ssize_t esp32c3_read_decrypt(struct mtd_dev_s *dev,
****************************************************************************/
static ssize_t esp32c3_bread_decrypt(struct mtd_dev_s *dev,
- off_t startblock,
- size_t nblocks,
- uint8_t *buffer)
+ off_t startblock,
+ size_t nblocks,
+ uint8_t *buffer)
{
ssize_t ret;
uint32_t addr = startblock * SPI_FLASH_BLK_SIZE;
@@ -412,7 +648,7 @@ static ssize_t esp32c3_bread_decrypt(struct mtd_dev_s *dev,
return ret;
}
- ret = spi_flash_read_encrypted(addr, buffer, size);
+ ret = esp32c3_readdata_encrypted(addr, buffer, size);
nxsem_post(&g_exclsem);
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig b/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig
index e26862b..40bd0db 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig
@@ -65,4 +65,20 @@ choice
endchoice
+config ESP32C3_SPIFLASH_ENCRYPTION_TEST
+ bool "SPI Flash encryption test"
+ default n
+ depends on ESP32C3_SPIFLASH
+ select DEBUG_ASSERTIONS
+ ---help---
+ Enable SPI Flash encryption test. This option will also select
+ DEBUG_ASSERTIONS to enable kernel assert macro.
+
+config ESP32C3_SPIFLASH_TEST_ADDRESS
+ hex "SPI Flash test address"
+ default 0x180000
+ depends on ESP32C3_SPIFLASH_ENCRYPTION_TEST
+ ---help---
+ SPI Flash encryption test read/write address.
+
endif # ARCH_BOARD_ESP32C3_DEVKIT
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
index 55dc5f3..f282eef 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
@@ -296,7 +296,7 @@ PROVIDE( Cache_Enable_Defalut_ICache_Mode = 0x400004c4 );
PROVIDE( ROM_Boot_Cache_Init = 0x400004c8 );
PROVIDE( Cache_Invalidate_ICache_Items = 0x400004cc );
PROVIDE( Cache_Op_Addr = 0x400004d0 );
-PROVIDE( Cache_Invalidate_Addr = 0x400004d4 );
+PROVIDE( cache_invalidate_addr = 0x400004d4 );
PROVIDE( Cache_Invalidate_ICache_All = 0x400004d8 );
PROVIDE( Cache_Mask_All = 0x400004dc );
PROVIDE( Cache_UnMask_Dram0 = 0x400004e0 );
@@ -316,8 +316,8 @@ PROVIDE( Cache_Lock_Addr = 0x40000514 );
PROVIDE( Cache_Unlock_Addr = 0x40000518 );
PROVIDE( Cache_Disable_ICache = 0x4000051c );
PROVIDE( Cache_Enable_ICache = 0x40000520 );
-PROVIDE( Cache_Suspend_ICache = 0x40000524 );
-PROVIDE( Cache_Resume_ICache = 0x40000528 );
+PROVIDE( cache_suspend_icache = 0x40000524 );
+PROVIDE( cache_resume_icache = 0x40000528 );
PROVIDE( Cache_Freeze_ICache_Enable = 0x4000052c );
PROVIDE( Cache_Freeze_ICache_Disable = 0x40000530 );
PROVIDE( Cache_Pms_Lock = 0x40000534 );
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h
index ac4ba6d..7f90352 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3-devkit.h
@@ -182,6 +182,24 @@ int esp32c3_spiflash_init(void);
#endif
/****************************************************************************
+ * Name: esp32c3_spiflash_encrypt_test
+ *
+ * Description:
+ * Test ESP32-C3 SPI Flash driver read/write with encryption.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_SPIFLASH_ENCRYPTION_TEST
+void esp32c3_spiflash_encrypt_test(void);
+#endif
+
+/****************************************************************************
* Name: esp32c3_ledc_setup
*
* Description:
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
index 55c4915..405ee9d 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
@@ -144,6 +144,11 @@ int esp32c3_bringup(void)
#endif
#ifdef CONFIG_ESP32C3_SPIFLASH
+
+# ifdef CONFIG_ESP32C3_SPIFLASH_ENCRYPTION_TEST
+ esp32c3_spiflash_encrypt_test();
+# endif
+
ret = esp32c3_spiflash_init();
if (ret)
{
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c
index ea7f1df..17f2402 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_spiflash.c
@@ -26,6 +26,7 @@
#include <sys/mount.h>
+#include "inttypes.h"
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
@@ -126,8 +127,8 @@ void esp32c3_spiflash_encrypt_test(void)
uint32_t erase_nblocks;
uint32_t rw_block;
uint32_t rw_nblocks;
- struct mtd_dev_s *mtd = esp32c3_spiflash_get_mtd();
- struct mtd_dev_s *enc_mtd = esp32c3_spiflash_encrypt_get_mtd();
+ struct mtd_dev_s *mtd = esp32c3_spiflash_mtd();
+ struct mtd_dev_s *enc_mtd = esp32c3_spiflash_encrypt_mtd();
const uint32_t address = CONFIG_ESP32C3_SPIFLASH_TEST_ADDRESS;
const uint32_t size = 4096;
@@ -142,14 +143,14 @@ void esp32c3_spiflash_encrypt_test(void)
wbuf = kmm_malloc(size);
if (!wbuf)
{
- ferr("ERROR: Failed to alloc %d heap\n", size);
+ ferr("ERROR: Failed to alloc %" PRIu32 " heap\n", size);
DEBUGASSERT(0);
}
rbuf = kmm_malloc(size);
if (!rbuf)
{
- ferr("ERROR: Failed to alloc %d heap\n", size);
+ ferr("ERROR: Failed to alloc %" PRIu32 " heap\n", size);
DEBUGASSERT(0);
}