13
13
14
14
#include "sdkconfig.h"
15
15
#include "esp_err.h"
16
+ #include "hal/cache_hal.h"
17
+ #include "hal/mmu_hal.h"
16
18
#include "bootloader_flash_priv.h"
17
19
#include "esp_flash_encrypt.h"
18
20
#include "mcuboot_config/mcuboot_config.h"
@@ -148,6 +150,24 @@ void flash_area_close(const struct flash_area *area)
148
150
149
151
}
150
152
153
+ #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
154
+ static void flush_cache (size_t start_addr , size_t length )
155
+ {
156
+ #if CONFIG_IDF_TARGET_ESP32
157
+ Cache_Read_Disable (0 );
158
+ Cache_Flush (0 );
159
+ Cache_Read_Enable (0 );
160
+ #else
161
+ uint32_t vaddr = 0 ;
162
+
163
+ mmu_hal_paddr_to_vaddr (0 , start_addr , MMU_TARGET_FLASH0 , MMU_VADDR_DATA , & vaddr );
164
+ if (vaddr != NULL ) {
165
+ cache_hal_invalidate_addr (vaddr , length );
166
+ }
167
+ #endif
168
+ }
169
+ #endif
170
+
151
171
static bool aligned_flash_read (uintptr_t addr , void * dest , size_t size )
152
172
{
153
173
if (IS_ALIGNED (addr , 4 ) && IS_ALIGNED ((uintptr_t )dest , 4 ) && IS_ALIGNED (size , 4 )) {
@@ -225,29 +245,31 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
225
245
#else
226
246
bool flash_encryption_enabled = false;
227
247
#endif
248
+ size_t alignment = flash_encryption_enabled ? 32 : 4 ;
228
249
229
- if (IS_ALIGNED (dest_addr , 4 ) && IS_ALIGNED ((uintptr_t )src , 4 ) && IS_ALIGNED (size , 4 )) {
250
+ if (IS_ALIGNED (dest_addr , alignment ) && IS_ALIGNED ((uintptr_t )src , 4 ) && IS_ALIGNED (size , alignment )) {
230
251
/* A single write operation is enough when all parameters are aligned */
231
252
232
253
return bootloader_flash_write (dest_addr , (void * )src , size , flash_encryption_enabled ) == ESP_OK ;
233
254
}
255
+ BOOT_LOG_DBG ("%s: forcing unaligned write dest_addr: 0x%08x src: 0x%08x size: 0x%x" , __func__ , (uint32_t )dest_addr , (uint32_t )src , size );
234
256
235
- const uint32_t aligned_addr = ALIGN_DOWN (dest_addr , 4 );
236
- const uint32_t addr_offset = ALIGN_OFFSET (dest_addr , 4 );
257
+ const uint32_t aligned_addr = ALIGN_DOWN (dest_addr , alignment );
258
+ const uint32_t addr_offset = ALIGN_OFFSET (dest_addr , alignment );
237
259
uint32_t bytes_remaining = size ;
238
- uint8_t write_data [FLASH_BUFFER_SIZE ] = {0 };
260
+ uint8_t write_data [FLASH_BUFFER_SIZE ] __attribute__(( aligned ( 32 ))) = {0 };
239
261
240
262
/* Perform a read operation considering an offset not aligned to 4-byte boundary */
241
263
242
264
uint32_t bytes = MIN (bytes_remaining + addr_offset , sizeof (write_data ));
243
- if (bootloader_flash_read (aligned_addr , write_data , ALIGN_UP (bytes , 4 ), true) != ESP_OK ) {
265
+ if (bootloader_flash_read (aligned_addr , write_data , ALIGN_UP (bytes , alignment ), true) != ESP_OK ) {
244
266
return false;
245
267
}
246
268
247
269
uint32_t bytes_written = bytes - addr_offset ;
248
270
memcpy (& write_data [addr_offset ], src , bytes_written );
249
271
250
- if (bootloader_flash_write (aligned_addr , write_data , ALIGN_UP (bytes , 4 ), flash_encryption_enabled ) != ESP_OK ) {
272
+ if (bootloader_flash_write (aligned_addr , write_data , ALIGN_UP (bytes , alignment ), flash_encryption_enabled ) != ESP_OK ) {
251
273
return false;
252
274
}
253
275
@@ -259,13 +281,13 @@ static bool aligned_flash_write(size_t dest_addr, const void *src, size_t size)
259
281
260
282
while (bytes_remaining != 0 ) {
261
283
bytes = MIN (bytes_remaining , sizeof (write_data ));
262
- if (bootloader_flash_read (aligned_addr + offset , write_data , ALIGN_UP (bytes , 4 ), true) != ESP_OK ) {
284
+ if (bootloader_flash_read (aligned_addr + offset , write_data , ALIGN_UP (bytes , alignment ), true) != ESP_OK ) {
263
285
return false;
264
286
}
265
287
266
288
memcpy (write_data , & ((uint8_t * )src )[bytes_written ], bytes );
267
289
268
- if (bootloader_flash_write (aligned_addr + offset , write_data , ALIGN_UP (bytes , 4 ), flash_encryption_enabled ) != ESP_OK ) {
290
+ if (bootloader_flash_write (aligned_addr + offset , write_data , ALIGN_UP (bytes , alignment ), flash_encryption_enabled ) != ESP_OK ) {
269
291
return false;
270
292
}
271
293
@@ -284,35 +306,39 @@ static bool aligned_flash_erase(size_t addr, size_t size)
284
306
285
307
return bootloader_flash_erase_range (addr , size ) == ESP_OK ;
286
308
}
309
+ BOOT_LOG_DBG ("%s: forcing unaligned erase on sector Offset: 0x%x Length: 0x%x" ,
310
+ __func__ , (int )addr , (int )size );
287
311
288
312
const uint32_t aligned_addr = ALIGN_DOWN (addr , FLASH_SECTOR_SIZE );
289
313
const uint32_t addr_offset = ALIGN_OFFSET (addr , FLASH_SECTOR_SIZE );
290
314
uint32_t bytes_remaining = size ;
291
- uint8_t write_data [FLASH_SECTOR_SIZE ] = {0 };
315
+ uint8_t write_data [FLASH_SECTOR_SIZE ] __attribute__(( aligned ( 32 ))) = {0 };
292
316
293
- /* Perform a read operation considering an offset not aligned to 4-byte boundary */
317
+ /* Perform a read operation considering an offset not aligned */
294
318
295
319
uint32_t bytes = MIN (bytes_remaining + addr_offset , sizeof (write_data ));
296
320
297
321
if (bootloader_flash_read (aligned_addr , write_data , ALIGN_UP (bytes , FLASH_SECTOR_SIZE ), true) != ESP_OK ) {
298
322
return false;
299
323
}
300
324
301
-
302
325
if (bootloader_flash_erase_range (aligned_addr , ALIGN_UP (bytes , FLASH_SECTOR_SIZE )) != ESP_OK ) {
303
- BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
304
- return -1 ;
326
+ return false;
305
327
}
306
328
307
329
uint32_t bytes_written = bytes - addr_offset ;
308
330
309
331
/* Write first part of non-erased data */
310
332
if (addr_offset > 0 ) {
311
- aligned_flash_write (aligned_addr , write_data , addr_offset );
333
+ if (!aligned_flash_write (aligned_addr , write_data , addr_offset )) {
334
+ return false;
335
+ }
312
336
}
313
337
314
338
if (bytes < sizeof (write_data )) {
315
- aligned_flash_write (aligned_addr + bytes , write_data + bytes , sizeof (write_data ) - bytes );
339
+ if (!aligned_flash_write (aligned_addr + bytes , write_data + bytes , sizeof (write_data ) - bytes )) {
340
+ return false;
341
+ }
316
342
}
317
343
318
344
bytes_remaining -= bytes_written ;
@@ -328,12 +354,13 @@ static bool aligned_flash_erase(size_t addr, size_t size)
328
354
}
329
355
330
356
if (bootloader_flash_erase_range (aligned_addr + offset , ALIGN_UP (bytes , FLASH_SECTOR_SIZE )) != ESP_OK ) {
331
- BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
332
- return -1 ;
357
+ return false;
333
358
}
334
359
335
360
if (bytes < sizeof (write_data )) {
336
- aligned_flash_write (aligned_addr + offset + bytes , write_data + bytes , sizeof (write_data ) - bytes );
361
+ if (!aligned_flash_write (aligned_addr + offset + bytes , write_data + bytes , sizeof (write_data ) - bytes )) {
362
+ return false;
363
+ }
337
364
}
338
365
339
366
offset += bytes ;
@@ -360,12 +387,15 @@ int flash_area_write(const struct flash_area *fa, uint32_t off, const void *src,
360
387
const uint32_t start_addr = fa -> fa_off + off ;
361
388
BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d" , __func__ , (int )start_addr , (int )len );
362
389
363
-
364
390
if (!aligned_flash_write (start_addr , src , len )) {
365
391
BOOT_LOG_ERR ("%s: Flash write failed" , __func__ );
366
392
return -1 ;
367
393
}
368
394
395
+ #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
396
+ flush_cache (start_addr , len );
397
+ #endif
398
+
369
399
return 0 ;
370
400
}
371
401
@@ -376,23 +406,17 @@ int flash_area_erase(const struct flash_area *fa, uint32_t off, uint32_t len)
376
406
}
377
407
378
408
const uint32_t start_addr = fa -> fa_off + off ;
409
+ BOOT_LOG_DBG ("%s: Addr: 0x%08x Length: %d" , __func__ , (int )start_addr , (int )len );
379
410
380
- if ((len % FLASH_SECTOR_SIZE ) != 0 || (off % FLASH_SECTOR_SIZE ) != 0 ) {
381
- BOOT_LOG_DBG ("%s: Not aligned on sector Offset: 0x%x Length: 0x%x" ,
382
- __func__ , (int )start_addr , (int )len );
383
-
384
- if (!aligned_flash_erase (start_addr , len )) {
385
- return -1 ;
386
- }
387
- } else {
388
- BOOT_LOG_DBG ("%s: Aligned Addr: 0x%08x Length: %d" , __func__ , (int )start_addr , (int )len );
389
-
390
- if (bootloader_flash_erase_range (start_addr , len ) != ESP_OK ) {
391
- BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
392
- return -1 ;
393
- }
411
+ if (!aligned_flash_erase (start_addr , len )) {
412
+ BOOT_LOG_ERR ("%s: Flash erase failed" , __func__ );
413
+ return -1 ;
394
414
}
395
415
416
+ #ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
417
+ flush_cache (start_addr , len );
418
+ #endif
419
+
396
420
#if VALIDATE_PROGRAM_OP
397
421
for (size_t i = 0 ; i < len ; i ++ ) {
398
422
uint8_t * val = (void * )(start_addr + i );
0 commit comments