Skip to content

Commit 88d0e4d

Browse files
committed
HiFive1 eSPI driver: Fixed return-to-hwmode, refactoring hal_flash_write
for short write operations
1 parent e8eb120 commit 88d0e4d

1 file changed

Lines changed: 62 additions & 13 deletions

File tree

hal/hifive1.c

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
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

268269
static 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

274277
static 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

280293
static 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 */
466480
int 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

524570
int 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

Comments
 (0)