7676#define FCW_MUTEX_LOCK_MASK 0x1
7777
7878#define FCW_WRITE_SIZE (4 * 8)
79+ #define FCW_WRITE_WORD_SIZE (8)
7980static uint32_t pic32_last_err = 0 ;
8081
8182#define OSCCTRL_STATUS (*(volatile uint32_t *)(OSCCTRL_BASE + 0x10U))
@@ -170,16 +171,15 @@ static void pic32_fcw_wait_complete(void)
170171 while (FCW_STATUS & FCW_BUSY_MASK ) {}
171172}
172173
173- static int pic32_write_dqword_aligned (uint32_t addr , const uint8_t * data )
174+ static int pic32_write_dqword_aligned (uint32_t addr , const uint32_t * data )
174175{
175- uint32_t i ;
176- uint32_t * _data = (uint32_t * )data ;
177176 uint32_t err ;
177+ uint32_t i ;
178178
179179 pic32_fcw_wait_complete ();
180180 FCW_ADDR = addr ;
181181 for (i = 0 ; i < 8 ; i ++ ) {
182- FCW_DATA [i ] = _data [i ];
182+ FCW_DATA [i ] = data [i ];
183183 }
184184 FCW_KEY = FCW_UNLOCK_WRKEY ;
185185 pic32_fcw_start_op (FCW_OP_QUAD_DOUBLE_WORD_WRITE );
@@ -201,14 +201,6 @@ static uint32_t pic32_addr_dqword_align(uint32_t addr)
201201 return (addr & ~0x1F );
202202}
203203
204- static void pic32_copy_dqword (uint8_t * dst , uint32_t addr )
205- {
206- int i ;
207- for (i = 0 ; i < FCW_WRITE_SIZE ; i ++ ) {
208- dst [i ] = * (volatile uint8_t * )(addr + i );
209- }
210- }
211-
212204static int pic32_fcw_erase_sector (uint32_t addr )
213205{
214206 uint32_t err ;
@@ -239,7 +231,8 @@ static uint8_t pic32_mask_zeros(uint8_t programmed, uint8_t to_program)
239231
240232int pic32_flash_write (uint32_t address , const uint8_t * data , int len )
241233{
242- uint8_t buff [FCW_WRITE_SIZE ], curr [FCW_WRITE_SIZE ];
234+ uint32_t buff [FCW_WRITE_WORD_SIZE ], curr [FCW_WRITE_WORD_SIZE ];
235+ uint8_t * p_buff , * p_curr ;
243236 uint32_t _addr ;
244237 uint8_t i ;
245238 int ret ;
@@ -256,11 +249,13 @@ int pic32_flash_write(uint32_t address, const uint8_t *data, int len)
256249 * is at least WOLFBOOT_SECTOR_SIZE, an erase was already performed,
257250 * so we can write data directly.
258251 */
259- pic32_copy_dqword (curr , _addr );
260- memset (buff , 0xff , FCW_WRITE_SIZE );
252+ memcpy (curr , ( uint8_t * )( uintptr_t ) _addr , sizeof ( curr ) );
253+ memset (buff , 0xff , sizeof ( buff ) );
261254 i = address - _addr ;
255+ p_curr = (uint8_t * )curr ;
256+ p_buff = (uint8_t * )buff ;
262257 for (; i < FCW_WRITE_SIZE && len > 0 ; i ++ , len -- ) {
263- buff [i ] = pic32_mask_zeros (curr [i ], * data );
258+ p_buff [i ] = pic32_mask_zeros (p_curr [i ], * data );
264259 data ++ ;
265260 address ++ ;
266261 }
@@ -269,7 +264,15 @@ int pic32_flash_write(uint32_t address, const uint8_t *data, int len)
269264 return ret ;
270265 continue ;
271266 }
272- ret = pic32_write_dqword_aligned (address , data );
267+
268+ /* move data in aligned buffer */
269+ if (!pic32_addr_is_dqword_aligned ((uint32_t )(uintptr_t )data )) {
270+ memcpy (buff , data , sizeof (buff ));
271+ ret = pic32_write_dqword_aligned (address , buff );
272+ } else {
273+ ret = pic32_write_dqword_aligned (address , (uint32_t * )data );
274+ }
275+
273276 if (ret != 0 )
274277 return ret ;
275278 address += FCW_WRITE_SIZE ;
@@ -406,6 +409,7 @@ int hal_flash_test_align(void);
406409int hal_flash_test_write_once (void );
407410int hal_flash_test (void );
408411int hal_flash_test_dualbank (void );
412+ int hal_flash_test_unaligned_src (void );
409413void pic32_flash_test (void )
410414{
411415 int ret ;
@@ -419,6 +423,12 @@ void pic32_flash_test(void)
419423 ret = hal_flash_test_write_once ();
420424 if (ret != 0 )
421425 wolfBoot_panic ();
426+ /* enable unaligned access fault for testing */
427+ ret = * (volatile uint32_t * )0xE000ED14 ;
428+ * (volatile uint32_t * )0xE000ED14 = ret | 8 ;
429+ ret = hal_flash_test_unaligned_src ();
430+ if (ret != 0 )
431+ wolfBoot_panic ();
422432#ifdef DUALBANK_SWAP
423433 ret = hal_flash_test_dualbank ();
424434 if (ret != 0 )
0 commit comments