2828 */
2929
3030#include <stdint.h>
31+ #include <string.h>
3132#include <target.h>
3233#include "image.h"
3334#ifndef ARCH_RISCV
@@ -253,7 +254,7 @@ void uart_flush(void)
253254 bits_per_symbol = (UART_REG_TXCTRL & (1 << 1 )) ? 9 : 10 ;
254255 cycles_to_wait = bits_per_symbol * (UART_REG_DIV + 1 );
255256 for (x = 0 ; x < cycles_to_wait ; x ++ ) {
256- asm("nop" );
257+ asm volatile ("nop" );
257258 }
258259}
259260
@@ -267,14 +268,26 @@ void fespi_init(uint32_t cpu_clock, uint32_t flash_freq)
267268
268269static RAMFUNCTION void fespi_swmode (void )
269270{
271+ asm volatile ("fence" );
272+ asm volatile ("fence.i" );
270273 if (FESPI_REG_FCTRL & FESPI_FCTRL_MODE_SEL )
271274 FESPI_REG_FCTRL &= ~FESPI_FCTRL_MODE_SEL ;
272275}
273276
274277static RAMFUNCTION void fespi_hwmode (void )
275278{
279+ uint32_t x ;
276280 if ((FESPI_REG_FCTRL & FESPI_FCTRL_MODE_SEL ) == 0 )
277281 FESPI_REG_FCTRL |= FESPI_FCTRL_MODE_SEL ;
282+ asm volatile ("fence" );
283+ asm volatile ("fence.i" );
284+ /* Wait two milliseconds for the eSPI device
285+ * to reboot into hw-mapped mode and link to the
286+ * instruction cache
287+ */
288+ for (x = 0 ; x < CPU_FREQ / 500 ; x ++ ) {
289+ asm volatile ("nop" );
290+ }
278291}
279292
280293static RAMFUNCTION void fespi_csmode_hold (void )
@@ -461,25 +474,58 @@ void hal_prepare_boot(void)
461474}
462475
463476#define FLASH_PAGE_SIZE 256
477+ #define FLASH_BASE 0x20000000UL
464478
465479/* Flash functions must be relocated to RAM for execution */
466480int RAMFUNCTION hal_flash_write (uint32_t address , const uint8_t * data , int len )
467481{
468- int i , j = 0 ;
469- uint32_t off = address & 0xFF ;
470- uint32_t page = address >> 8 ;
471- FESPI_REG_TXMARK = 1 ;
472- fespi_swmode ();
473- fespi_wait_flash_busy ();
474-
475- while (j < len ) {
482+ uint32_t i , j = 0 ;
483+ uint32_t off , page ;
484+ const uint8_t * src ;
485+ uint8_t data_copy [FLASH_PAGE_SIZE ];
486+ int swmode = 0 ;
487+
488+
489+ if (address >= FLASH_BASE )
490+ address -= FLASH_BASE ;
491+ off = address & 0xFF ;
492+ page = address >> 8 ;
493+
494+ while (j < (uint32_t )len ) {
495+ if ((off > 0 ) || (len < FLASH_PAGE_SIZE )) {
496+ uint8_t * orig = (uint8_t * )(FLASH_BASE + (page << 8 ));
497+ int rel_len ;
498+ rel_len = FLASH_PAGE_SIZE - off ;
499+ if (swmode ) {
500+ fespi_hwmode ();
501+ swmode = 0 ;
502+ }
503+ if (rel_len > len )
504+ rel_len = len ;
505+ for (i = 0 ; i < off ; i ++ )
506+ data_copy [i ] = orig [i ];
507+ for (i = off ; i < off + rel_len ; i ++ )
508+ data_copy [i ] = data [j ++ ];
509+ for (i = off + rel_len ; i < FLASH_PAGE_SIZE ; i ++ )
510+ data_copy [i ] = orig [i ];
511+ src = data_copy ;
512+ } else {
513+ src = (data + j );
514+ j += FLASH_PAGE_SIZE ;
515+ }
516+ if (!swmode ) {
517+ FESPI_REG_TXMARK = 1 ;
518+ fespi_swmode ();
519+ fespi_wait_flash_busy ();
520+ swmode ++ ;
521+ }
476522 fespi_write_enable ();
477523 fespi_csmode_hold ();
478524 fespi_sw_tx (FESPI_PAGE_PROGRAM );
479525 fespi_wait_txwm ();
480- fespi_write_address ((page << 8 ) + off );
481- for (i = off ; i < FLASH_PAGE_SIZE ; i ++ ) {
482- fespi_sw_tx (data [ j ++ ]);
526+ fespi_write_address ((page << 8 ));
527+ for (i = 0 ; i < FLASH_PAGE_SIZE ; i ++ ) {
528+ fespi_sw_tx (src [ i ]);
483529 }
484530 fespi_csmode_auto ();
485531 page ++ ;
@@ -523,8 +569,11 @@ static uint32_t RAMFUNCTION fespi_flash_probe(void)
523569
524570int RAMFUNCTION hal_flash_erase (uint32_t address , int len )
525571{
526- uint32_t end = address + len - 1 ;
572+ uint32_t end ;
527573 uint32_t p ;
574+ if (address >= FLASH_BASE )
575+ address -= FLASH_BASE ;
576+ end = address + len - 1 ;
528577
529578
530579 FESPI_REG_TXMARK = 1 ;
0 commit comments