Skip to content

Commit

Permalink
Reset SPI flash before accessing it
Browse files Browse the repository at this point in the history
If the system is reset while a SPI access is going on, the SPI device
might not be in the correct state and using it directly will fail,
and we don't show helpful message in this case, just
"Failed ELF Magic Check".

Add a software reset sequence to reset it to a well known state before
accessing.
  • Loading branch information
nbdd0121 committed Aug 16, 2024
1 parent 4cd011e commit a4c69df
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
1 change: 1 addition & 0 deletions sw/cheri/boot/boot_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ extern "C" void rom_loader_entry(void *rwRoot)
uart->init(BAUD_RATE);

SpiFlash spi_flash(spi, gpio, FLASH_CSN_GPIO_BIT);
spi_flash.reset();
read_elf(spi_flash, uart, sram);

write_str(uart, prefix);
Expand Down
17 changes: 17 additions & 0 deletions sw/cheri/common/flash-utils.hh
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#pragma once
#include "timer-utils.hh"
#include <cheri.hh>
#include <platform-gpio.hh>
#include <platform-spi.hh>

typedef CHERI::Capability<volatile SonataGPIO> &GpioRef;
typedef CHERI::Capability<volatile SonataSpi> &SpiRef;

static const uint8_t CmdEnableReset = 0x66;
static const uint8_t CmdReset = 0x99;
static const uint8_t CmdReadJEDECId = 0x9f;
static const uint8_t CmdWriteEnable = 0x06;
static const uint8_t CmdSectorErase = 0x20;
Expand All @@ -32,6 +35,20 @@ class SpiFlash
{
}

void reset()
{
set_cs(true);
spi->blocking_write(&CmdEnableReset, 1);
set_cs(false);

set_cs(true);
spi->blocking_write(&CmdReset, 1);
set_cs(false);

// Need to wait at least 30us for the reset to complete.
wait_mcycle(2000);
}

void read_jedec_id(uint8_t *jedec_id_out)
{
set_cs(true);
Expand Down
20 changes: 20 additions & 0 deletions sw/cheri/common/timer-utils.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once
#include <stdint.h>

static inline uint32_t get_mcycle(void)
{
uint32_t result;
asm volatile("csrr %0, mcycle;" : "=r"(result));
return result;
}

static inline void reset_mcycle(void)
{
asm volatile("csrw mcycle, x0");
}

static inline void wait_mcycle(uint32_t value)
{
reset_mcycle();
while (get_mcycle() < value) {}
}

0 comments on commit a4c69df

Please sign in to comment.