Skip to content

Commit 622a0bb

Browse files
committed
flash_ipuc: Add cache handling
Handle cache in IPUC pseudo flash driver. Ref: NCSDK-31701 Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 71e9e16 commit 622a0bb

File tree

1 file changed

+94
-12
lines changed

1 file changed

+94
-12
lines changed

drivers/flash/flash_ipuc/flash_ipuc.c

Lines changed: 94 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@
1111
#include <suit_ipuc.h>
1212
#include <suit_plat_decode_util.h>
1313
#include <zephyr/logging/log.h>
14+
#include <zephyr/cache.h>
1415

15-
LOG_MODULE_REGISTER(flash_ipuc, CONFIG_FLASH_IPUC_LOG_LEVEL);
16+
/* __ALIGNED macro is not defined on NATIVE POSIX. This platform uses __aligned macro. */
17+
#ifndef __ALIGNED
18+
#ifdef __aligned
19+
#define __ALIGNED __aligned
20+
#endif
21+
#endif
22+
23+
#ifdef CONFIG_DCACHE_LINE_SIZE
24+
#define CACHE_ALIGNMENT CONFIG_DCACHE_LINE_SIZE
25+
#else
26+
#define CACHE_ALIGNMENT 4
27+
#endif
1628

1729
#define FLASH_WRITE_BLOCK_SIZE DT_PROP(DT_CHOSEN(zephyr_flash), write_block_size)
1830
#define WRITE_BLOCK_SIZE FLASH_WRITE_BLOCK_SIZE
@@ -45,6 +57,8 @@ struct ipuc_context {
4557

4658
#define DEFINE_NRF_IPUC_REF(x, _) &__device_flash_nrf_ipuc_##x
4759

60+
LOG_MODULE_REGISTER(flash_ipuc, CONFIG_FLASH_IPUC_LOG_LEVEL);
61+
4862
static int nrf_ipuc_read(const struct device *dev, off_t offset, void *data, size_t len)
4963
{
5064
struct ipuc_context *ctx = NULL;
@@ -75,8 +89,11 @@ static int nrf_ipuc_read(const struct device *dev, off_t offset, void *data, siz
7589

7690
static int nrf_ipuc_write(const struct device *dev, off_t offset, const void *data, size_t len)
7791
{
92+
uint8_t unaligned_data_buf[CACHE_ALIGNMENT] __ALIGNED(CACHE_ALIGNMENT) = {0};
93+
size_t unaligned_len = MIN(CACHE_ALIGNMENT - (((uintptr_t)data) % CACHE_ALIGNMENT), len);
94+
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
7895
struct ipuc_context *ctx = NULL;
79-
bool last_chunk = false;
96+
int ret = 0;
8097

8198
if (dev == NULL) {
8299
return -EINVAL;
@@ -88,20 +105,75 @@ static int nrf_ipuc_write(const struct device *dev, off_t offset, const void *da
88105
return -EBADF;
89106
}
90107

108+
if (offset + len > ctx->size) {
109+
return -ENOMEM;
110+
}
111+
91112
LOG_DBG("write: %p:%zu", (void *)offset, len);
92113

93114
if (len == 0) {
94-
last_chunk = true;
115+
plat_ret = suit_ipuc_write(&ctx->component_id, offset, 0, 0, true);
116+
if (plat_ret != SUIT_PLAT_SUCCESS) {
117+
LOG_ERR("Last write (flush) error: %d", plat_ret);
118+
return -EIO;
119+
}
120+
121+
return 0;
95122
}
96123

97-
if (offset + len > ctx->size) {
98-
return -ENOMEM;
124+
/* Optimize: Use a single write call if all bytes can be transferred using stack-based
125+
* aligned buffer.
126+
*/
127+
if (len <= ARRAY_SIZE(unaligned_data_buf)) {
128+
unaligned_len = len;
99129
}
100130

101-
suit_plat_err_t plat_ret =
102-
suit_ipuc_write(&ctx->component_id, offset, (uintptr_t)data, len, last_chunk);
131+
/* If the data buffer is not aligned to the cache lines:
132+
* - copy the unaligned part into stack-based aligned buffer
133+
* - write the internal buffer
134+
* - skip the unaligned bytes of the input buffer
135+
*/
136+
if (unaligned_len != CACHE_ALIGNMENT) {
137+
memcpy(unaligned_data_buf, data, unaligned_len);
103138

139+
LOG_DBG("align: %p:%zu", (void *)data, unaligned_len);
140+
141+
ret = sys_cache_data_flush_range((void *)unaligned_data_buf,
142+
sizeof(unaligned_data_buf));
143+
if (ret != 0 && ret != -EAGAIN && ret != -ENOTSUP) {
144+
LOG_ERR("Failed to flush cache buffer range (%p, 0x%x): %d",
145+
(void *)unaligned_data_buf, sizeof(unaligned_data_buf), ret);
146+
return -EIO;
147+
}
148+
149+
plat_ret = suit_ipuc_write(&ctx->component_id, offset,
150+
(uintptr_t)unaligned_data_buf, unaligned_len, false);
151+
if (plat_ret != SUIT_PLAT_SUCCESS) {
152+
LOG_ERR("Unaligned data write (%p, 0x%x) error: %d",
153+
(void *)unaligned_data_buf, unaligned_len, plat_ret);
154+
return -EIO;
155+
}
156+
157+
offset += unaligned_len;
158+
len -= unaligned_len;
159+
data = (void *)((uintptr_t)data + unaligned_len);
160+
}
161+
162+
/* If no more (aligned) bytes left - return. */
163+
if (len == 0) {
164+
return 0;
165+
}
166+
167+
/* Write (now aligned) data buffer. */
168+
ret = sys_cache_data_flush_range((void *)data, len);
169+
if (ret != 0 && ret != -EAGAIN && ret != -ENOTSUP) {
170+
LOG_ERR("Failed to flush cache memory range (%p, 0x%x): %d", data, len, ret);
171+
return -EIO;
172+
}
173+
174+
plat_ret = suit_ipuc_write(&ctx->component_id, offset, (uintptr_t)data, len, false);
104175
if (plat_ret != SUIT_PLAT_SUCCESS) {
176+
LOG_ERR("Aligned data write (%p, 0x%x) error: %d", data, len, plat_ret);
105177
return -EIO;
106178
}
107179

@@ -110,7 +182,8 @@ static int nrf_ipuc_write(const struct device *dev, off_t offset, const void *da
110182

111183
static int nrf_ipuc_erase(const struct device *dev, off_t offset, size_t size)
112184
{
113-
static uint8_t erase_block[WRITE_BLOCK_SIZE] = {ERASE_VALUE};
185+
static const uint8_t erase_block[WRITE_BLOCK_SIZE] __ALIGNED(CACHE_ALIGNMENT) = {
186+
ERASE_VALUE};
114187
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
115188
struct ipuc_context *ctx = NULL;
116189

@@ -128,18 +201,27 @@ static int nrf_ipuc_erase(const struct device *dev, off_t offset, size_t size)
128201
return -ENOMEM;
129202
}
130203

204+
int ret = sys_cache_data_flush_range((void *)erase_block, sizeof(erase_block));
205+
206+
if (ret != 0 && ret != -EAGAIN && ret != -ENOTSUP) {
207+
LOG_ERR("Failed to flush cache range (%p, 0x%x): %d", erase_block,
208+
sizeof(erase_block), ret);
209+
return -EIO;
210+
}
211+
131212
LOG_DBG("erase: %p:%zu", (void *)offset, size);
213+
132214
while (size > 0) {
133215
plat_ret = suit_ipuc_write(&ctx->component_id, offset, (uintptr_t)erase_block,
134216
sizeof(erase_block), false);
217+
if (plat_ret != SUIT_PLAT_SUCCESS) {
218+
return -EIO;
219+
}
220+
135221
offset += sizeof(erase_block);
136222
size -= sizeof(erase_block);
137223
}
138224

139-
if (plat_ret != SUIT_PLAT_SUCCESS) {
140-
return -EIO;
141-
}
142-
143225
return 0;
144226
}
145227

0 commit comments

Comments
 (0)