riscv/esp32c3: Support SPI Flash encryption read/write
This commit is contained in:
parent
48b0e48cd4
commit
76df958e34
@ -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
|
||||
****************************************************************************/
|
||||
@ -103,6 +162,14 @@ static ssize_t esp32c3_bwrite_encrypt(struct mtd_dev_s *dev,
|
||||
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
|
||||
****************************************************************************/
|
||||
@ -154,6 +221,175 @@ static sem_t g_exclsem = SEM_INITIALIZER(1);
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
*
|
||||
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -181,6 +181,24 @@ int board_bmp180_initialize(int devno, int busno);
|
||||
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
|
||||
*
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user