drivers: nrf: rram: Support TF-M
Non-secure images cannot reference NRF_RRAMC_NS because NRF_RRAMC_NS does not exist. TF-M will configure RRAMC according to these Kconfig's before booting the non-secure image so we ifdef out this code. Also, rewrite the implementation of commit_changes to also work when the commit task is not available. Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
This commit is contained in:
parent
ec83ab333d
commit
99f94295eb
|
@ -17,6 +17,26 @@
|
||||||
|
|
||||||
#include <zephyr/../../drivers/flash/soc_flash_nrf.h>
|
#include <zephyr/../../drivers/flash/soc_flash_nrf.h>
|
||||||
|
|
||||||
|
/* Note that it is supported to compile this driver for both secure
|
||||||
|
* and non-secure images, but non-secure images cannot call
|
||||||
|
* nrf_rramc_config_set because NRF_RRAMC_NS does not exist.
|
||||||
|
*
|
||||||
|
* Instead, when TF-M boots, it will configure RRAMC with this static
|
||||||
|
* configuration:
|
||||||
|
*
|
||||||
|
* nrf_rramc_config_t config = {
|
||||||
|
* .mode_write = true,
|
||||||
|
* .write_buff_size = WRITE_BUFFER_SIZE
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* nrf_rramc_ready_next_timeout_t params = {
|
||||||
|
* .value = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE,
|
||||||
|
* .enable = true,
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* For more details see NCSDK-26982.
|
||||||
|
*/
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(flash_nrf_rram, CONFIG_FLASH_LOG_LEVEL);
|
LOG_MODULE_REGISTER(flash_nrf_rram, CONFIG_FLASH_LOG_LEVEL);
|
||||||
|
|
||||||
#define RRAM DT_INST(0, soc_nv_flash)
|
#define RRAM DT_INST(0, soc_nv_flash)
|
||||||
|
@ -85,19 +105,43 @@ static inline bool is_within_bounds(off_t addr, size_t len, off_t boundary_start
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WRITE_BUFFER_ENABLE
|
#if WRITE_BUFFER_ENABLE
|
||||||
static void commit_changes(size_t len)
|
static void commit_changes(off_t addr, size_t len)
|
||||||
{
|
{
|
||||||
|
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
|
||||||
if (nrf_rramc_empty_buffer_check(NRF_RRAMC)) {
|
if (nrf_rramc_empty_buffer_check(NRF_RRAMC)) {
|
||||||
/* The internal write-buffer has been committed to RRAM and is now empty. */
|
/* The internal write-buffer has been committed to RRAM and is now empty. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((len % (WRITE_BUFFER_MAX_SIZE)) == 0) {
|
if ((len % (WRITE_BUFFER_MAX_SIZE)) == 0) {
|
||||||
/* Our last operation was buffer size-aligned, so we're done. */
|
/* Our last operation was buffer size-aligned, so we're done. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
|
||||||
|
ARG_UNUSED(addr);
|
||||||
|
|
||||||
nrf_rramc_task_trigger(NRF_RRAMC, NRF_RRAMC_TASK_COMMIT_WRITEBUF);
|
nrf_rramc_task_trigger(NRF_RRAMC, NRF_RRAMC_TASK_COMMIT_WRITEBUF);
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* When the commit task is unavailable we need to get creative to
|
||||||
|
* ensure this is committed.
|
||||||
|
*
|
||||||
|
* According to the PS the buffer is committed when "There is a
|
||||||
|
* read operation from a 128-bit word line in the buffer that has
|
||||||
|
* already been written to".
|
||||||
|
*
|
||||||
|
* So we read the last byte that has been written to trigger this
|
||||||
|
* commit.
|
||||||
|
*
|
||||||
|
* If this approach proves to be problematic, e.g. for writes to
|
||||||
|
* write-only memory, then one would have to rely on
|
||||||
|
* READYNEXTTIMEOUT to eventually commit the write.
|
||||||
|
*/
|
||||||
|
volatile uint8_t dummy_read = *(volatile uint8_t *)(addr + len - 1);
|
||||||
|
ARG_UNUSED(dummy_read);
|
||||||
|
#endif
|
||||||
|
|
||||||
barrier_dmem_fence_full();
|
barrier_dmem_fence_full();
|
||||||
}
|
}
|
||||||
|
@ -105,9 +149,11 @@ static void commit_changes(size_t len)
|
||||||
|
|
||||||
static void rram_write(off_t addr, const void *data, size_t len)
|
static void rram_write(off_t addr, const void *data, size_t len)
|
||||||
{
|
{
|
||||||
|
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
|
||||||
nrf_rramc_config_t config = {.mode_write = true, .write_buff_size = WRITE_BUFFER_SIZE};
|
nrf_rramc_config_t config = {.mode_write = true, .write_buff_size = WRITE_BUFFER_SIZE};
|
||||||
|
|
||||||
nrf_rramc_config_set(NRF_RRAMC, &config);
|
nrf_rramc_config_set(NRF_RRAMC, &config);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
memcpy((void *)addr, data, len);
|
memcpy((void *)addr, data, len);
|
||||||
|
@ -118,11 +164,13 @@ static void rram_write(off_t addr, const void *data, size_t len)
|
||||||
barrier_dmem_fence_full(); /* Barrier following our last write. */
|
barrier_dmem_fence_full(); /* Barrier following our last write. */
|
||||||
|
|
||||||
#if WRITE_BUFFER_ENABLE
|
#if WRITE_BUFFER_ENABLE
|
||||||
commit_changes(len);
|
commit_changes(addr, len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
|
||||||
config.mode_write = false;
|
config.mode_write = false;
|
||||||
nrf_rramc_config_set(NRF_RRAMC, &config);
|
nrf_rramc_config_set(NRF_RRAMC, &config);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE
|
||||||
|
@ -298,11 +346,12 @@ static int nrf_rram_init(const struct device *dev)
|
||||||
nrf_flash_sync_init();
|
nrf_flash_sync_init();
|
||||||
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */
|
||||||
|
|
||||||
#if CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE > 0
|
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) && CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE > 0
|
||||||
nrf_rramc_ready_next_timeout_t params = {
|
nrf_rramc_ready_next_timeout_t params = {
|
||||||
.value = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE,
|
.value = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE,
|
||||||
.enable = true,
|
.enable = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
nrf_rramc_ready_next_timeout_set(NRF_RRAMC, ¶ms);
|
nrf_rramc_ready_next_timeout_set(NRF_RRAMC, ¶ms);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue