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,23 +171,26 @@ 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 );
186186 pic32_fcw_wait_complete ();
187187 err = pic32_get_errs ();
188188 pic32_last_err = err ;
189- err &= ~FCW_INTFLAG_DONE_BIT ;
189+ if (!(err & FCW_INTFLAG_DONE_BIT )) {
190+ err = -1 ;
191+ } else {
192+ err &= ~FCW_INTFLAG_DONE_BIT ;
193+ }
190194 pic32_clear_errs ();
191195 return err ;
192196}
@@ -201,14 +205,6 @@ static uint32_t pic32_addr_dqword_align(uint32_t addr)
201205 return (addr & ~0x1F );
202206}
203207
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-
212208static int pic32_fcw_erase_sector (uint32_t addr )
213209{
214210 uint32_t err ;
@@ -218,9 +214,13 @@ static int pic32_fcw_erase_sector(uint32_t addr)
218214 pic32_fcw_start_op (FCW_OP_ERASE_SECTOR );
219215 pic32_fcw_wait_complete ();
220216 err = pic32_get_errs ();
221- pic32_clear_errs ();
222217 pic32_last_err = err ;
223- err &= ~FCW_INTFLAG_DONE_BIT ;
218+ if (!(err & FCW_INTFLAG_DONE_BIT )) {
219+ err = -1 ;
220+ } else {
221+ err &= ~FCW_INTFLAG_DONE_BIT ;
222+ }
223+ pic32_clear_errs ();
224224 return err ;
225225}
226226
@@ -239,7 +239,8 @@ static uint8_t pic32_mask_zeros(uint8_t programmed, uint8_t to_program)
239239
240240int pic32_flash_write (uint32_t address , const uint8_t * data , int len )
241241{
242- uint8_t buff [FCW_WRITE_SIZE ], curr [FCW_WRITE_SIZE ];
242+ uint32_t buff [FCW_WRITE_WORD_SIZE ], curr [FCW_WRITE_WORD_SIZE ];
243+ uint8_t * p_buff , * p_curr ;
243244 uint32_t _addr ;
244245 uint8_t i ;
245246 int ret ;
@@ -256,11 +257,13 @@ int pic32_flash_write(uint32_t address, const uint8_t *data, int len)
256257 * is at least WOLFBOOT_SECTOR_SIZE, an erase was already performed,
257258 * so we can write data directly.
258259 */
259- pic32_copy_dqword (curr , _addr );
260- memset (buff , 0xff , FCW_WRITE_SIZE );
260+ memcpy (curr , ( uint8_t * )( uintptr_t ) _addr , sizeof ( curr ) );
261+ memset (buff , 0xff , sizeof ( buff ) );
261262 i = address - _addr ;
263+ p_curr = (uint8_t * )curr ;
264+ p_buff = (uint8_t * )buff ;
262265 for (; i < FCW_WRITE_SIZE && len > 0 ; i ++ , len -- ) {
263- buff [i ] = pic32_mask_zeros (curr [i ], * data );
266+ p_buff [i ] = pic32_mask_zeros (p_curr [i ], * data );
264267 data ++ ;
265268 address ++ ;
266269 }
@@ -269,7 +272,15 @@ int pic32_flash_write(uint32_t address, const uint8_t *data, int len)
269272 return ret ;
270273 continue ;
271274 }
272- ret = pic32_write_dqword_aligned (address , data );
275+
276+ /* move data in aligned buffer */
277+ if (!pic32_addr_is_dqword_aligned ((uint32_t )(uintptr_t )data )) {
278+ memcpy (buff , data , sizeof (buff ));
279+ ret = pic32_write_dqword_aligned (address , buff );
280+ } else {
281+ ret = pic32_write_dqword_aligned (address , (uint32_t * )data );
282+ }
283+
273284 if (ret != 0 )
274285 return ret ;
275286 address += FCW_WRITE_SIZE ;
@@ -406,6 +417,7 @@ int hal_flash_test_align(void);
406417int hal_flash_test_write_once (void );
407418int hal_flash_test (void );
408419int hal_flash_test_dualbank (void );
420+ int hal_flash_test_unaligned_src (void );
409421void pic32_flash_test (void )
410422{
411423 int ret ;
@@ -419,6 +431,12 @@ void pic32_flash_test(void)
419431 ret = hal_flash_test_write_once ();
420432 if (ret != 0 )
421433 wolfBoot_panic ();
434+ /* enable unaligned access fault for testing */
435+ ret = * (volatile uint32_t * )0xE000ED14 ;
436+ * (volatile uint32_t * )0xE000ED14 = ret | 8 ;
437+ ret = hal_flash_test_unaligned_src ();
438+ if (ret != 0 )
439+ wolfBoot_panic ();
422440#ifdef DUALBANK_SWAP
423441 ret = hal_flash_test_dualbank ();
424442 if (ret != 0 )
0 commit comments