Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sw/device/bootrom/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set(NAME bootrom)
add_executable(${NAME} bootrom.c)
target_link_libraries(${NAME} hal_vanilla runtime_vanilla startup_vanilla)
target_compile_options(${NAME} PUBLIC ${VANILLA_FLAGS})
target_link_options(${NAME} PUBLIC
target_link_options(${NAME} PUBLIC
"-nodefaultlibs"
"-Wl,--defsym,BOOT_ROM_OFFSET=0x00"
"-T${LDS}"
Expand Down
63 changes: 35 additions & 28 deletions sw/device/bootrom/bootrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "boot/trap.h"
#include "hal/gpio.h"
#include "hal/mmio.h"
#include "hal/mocha.h"
#include "hal/spi_device.h"
#include "hal/uart.h"
Expand Down Expand Up @@ -32,7 +33,7 @@ int main(void)
spi_boot_strap(console);

enum { BootAddress = 0x10004080 };
uprintf(console, "\nJumping to: 0x%0x\n", BootAddress);
uprintf(console, "\nJumping to: 0x%x\n", BootAddress);

boot(BootAddress);
uprintf(console, "\nFailed to boot?\n");
Expand All @@ -53,9 +54,9 @@ bool spi_boot_strap(uart_t console)

spi_device_t spid = mocha_system_spi_device();
spi_device_init(spid);
spi_device_enable_set(spid, true);
spi_device_flash_status_set(spid, 0);

spi_device_flash_mode_set(spid, spi_device_flash_mode_flash);
const spi_device_flash_status clear_status = { 0 };
spi_device_flash_status_set(spid, clear_status);
uint32_t received_resets = 0;
size_t count = 0;

Expand All @@ -66,45 +67,47 @@ bool spi_boot_strap(uart_t console)
count = 0;
}

spi_device_cmd_t cmd = spi_device_cmd_get_non_blocking(spid);
if (cmd.status != spi_device_status_ready) {
if (cmd.status == spi_device_status_overflow) {
spi_device_software_command command;
enum spi_device_status command_status =
spi_device_software_command_get_non_blocking(spid, &command);
if (command_status != spi_device_status_ready) {
if (command_status == spi_device_status_overflow) {
uprintf(console, "SPI payload overflow\n");
spi_device_flash_status_set(spid, 0);
spi_device_flash_status_busy_set(spid, false);
continue;
}
continue;
}

switch (cmd.opcode) {
case SPI_DEVICE_OPCODE_SECTOR_ERASE:
switch (command.opcode) {
case spi_device_opcode_sector_erase:
// No need to erase SRAM.
break;
case SPI_DEVICE_OPCODE_PAGE_PROGRAM:
if (cmd.payload_byte_count > 0) {
page_program(console, spid, cmd.address, cmd.payload_byte_count);
case spi_device_opcode_page_program:
if (command.has_address && command.payload_byte_count > 0) {
page_program(console, spid, command.address, command.payload_byte_count);
}
break;
case SPI_DEVICE_OPCODE_RESET:
case spi_device_opcode_reset:
// This is a workaround to openFPGALoader that starts with a reset.
if (received_resets++ > 0) {
// Exit boot strap
spi_device_enable_set(spid, false);
spi_device_flash_mode_set(spid, spi_device_flash_mode_disabled);
return true;
}
uprintf(console, "\nFirst reset");
uprintf(console, "\nFirst reset\n");
break;
default:
uprintf(console, "\nUnsupported command: 0x%0x", cmd.opcode);
uprintf(console, "\nUnsupported command: 0x%x", command.opcode);
break;
}
// Finished processing the write, clear the busy bit.
spi_device_flash_status_set(spid, 0);
spi_device_flash_status_busy_set(spid, false);
}

return true;
}

static inline bool is_overriding_me(uintptr_t addr)
static inline bool is_overwriting_me(uintptr_t addr)
{
return addr >= (uintptr_t)_program_start && addr < (uintptr_t)_program_end;
}
Expand All @@ -114,24 +117,28 @@ void page_program(uart_t console, spi_device_t spid, uint32_t offset, uint32_t b
// TODO: Enable the spi flash 4 bytes addressing.
enum { SramOffset = 0x10000000 };
uintptr_t ptr = SramOffset + offset;
uint32_t payload_offset = 0;
uprintf(console, "page program: addr: 0x%x len: 0x%x bytes\n", (uint32_t)ptr, bytes);
size_t num_words = bytes / 4;
if (bytes % 4 != 0) {
num_words++;
}

if (bytes > SPI_DEVICE_PAYLOAD_AREA_NUM_BYTES) {
if (bytes > spi_device_ingress_buffer_size_payload_fifo * sizeof(uint32_t)) {
uprintf(console, "\npage program size out of bounds");
return;
}

// TODO: Now only SRAM is supported, but when 4 bytes addressing is enabled and the HW supports
// DRAM and ROM, then we need to check that the offset is valid within a memory address space.
if (is_overriding_me(ptr) || is_overriding_me(ptr + bytes)) {
uprintf(console, "\nPlease don't override the bootROM.");
if (is_overwriting_me(ptr) || is_overwriting_me(ptr + bytes)) {
uprintf(console, "\nPlease don't overwrite the bootROM.");
return;
}

while (payload_offset < bytes) {
*((volatile uint64_t *)ptr) = spi_device_flash_payload_buffer_read64(spid, payload_offset);
ptr += sizeof(uint64_t);
payload_offset += sizeof(uint64_t);
for (size_t i = 0; i < num_words; i++) {
uint32_t word =
VOLATILE_READ(spid->ingress_buffer[spi_device_ingress_buffer_offset_payload_fifo + i]);
((uint32_t *)ptr)[i] = word;
}
}

Expand Down
40 changes: 22 additions & 18 deletions sw/device/examples/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,63 +15,67 @@ int main(void)
spi_device_t spi_device = mocha_system_spi_device();
uart_init(uart);
spi_device_init(spi_device);
spi_device_flash_mode_set(spi_device, spi_device_flash_mode_flash);
const spi_device_flash_status clear_status = { 0 };
spi_device_flash_status_set(spi_device, clear_status);

uprintf(uart, "Hello SPI in Mocha!\n");

// Poll and process SPI command
spi_device_cmd_t cmd;
while (1) {
spi_device_software_command cmd;
while (true) {
// Now process SPI command (if any)
cmd = spi_device_cmd_get(spi_device);
if (cmd.status != 0) {
uprintf(uart, "SPI payload overflow\n");
spi_device_flash_status_set(spi_device, 0);
continue;
enum spi_device_status status = spi_device_software_command_get(spi_device, &cmd);
if (status != spi_device_status_ready) {
if (status == spi_device_status_overflow) {
uprintf(uart, "SPI payload overflow\n");
spi_device_flash_status_set(spi_device, clear_status);
continue;
}
}

switch (cmd.opcode) {
case SPI_DEVICE_OPCODE_CHIP_ERASE:
case spi_device_opcode_chip_erase:
uprintf(uart, "SPI CHIP ERASE");
break;
case SPI_DEVICE_OPCODE_SECTOR_ERASE:
case spi_device_opcode_sector_erase:
uprintf(uart, "SPI SECTOR ERASE");
break;
case SPI_DEVICE_OPCODE_PAGE_PROGRAM:
case spi_device_opcode_page_program:
uprintf(uart, "SPI PAGE PROGRAM");
break;
case SPI_DEVICE_OPCODE_RESET:
case spi_device_opcode_reset:
uprintf(uart, "SPI RESET");
break;
default:
uprintf(uart, "SPI ??");
break;
}

if (cmd.address != UINT32_MAX) {
if (cmd.has_address) {
uprintf(uart, " addr: 0x%x\n", cmd.address);
}

if (cmd.payload_byte_count > 0) {
uprintf(uart, "payload bytes: 0x%x\n", cmd.payload_byte_count);
uint32_t payload_word_count = ((uint32_t)cmd.payload_byte_count) / sizeof(uint32_t);
if ((cmd.payload_byte_count % sizeof(uint32_t)) != 0) {
++payload_word_count;
payload_word_count++;
}

uprintf(uart, "payload data:\n");

uint32_t word;
for (uint32_t i = 0; i < payload_word_count; ++i) {
word = spi_device_flash_payload_buffer_read(spi_device, i * sizeof(uint32_t));
spi_device_flash_read_buffer_write(spi_device, cmd.address + i * sizeof(uint32_t),
word);
uprintf(uart, "0x%x\n", word);
if (spi_device_flash_payload_buffer_read_word(spi_device, i, &word)) {
uprintf(uart, "0x%x\n", word);
}
}
}

uprintf(uart, "\n");

spi_device_flash_status_set(spi_device, 0);
spi_device_flash_status_set(spi_device, clear_status);
}

return 0;
Expand Down
3 changes: 3 additions & 0 deletions sw/device/lib/hal/mmio.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@
#define DEV_READ16(addr) (*((volatile uint16_t *)(addr)))
#define DEV_WRITE64(addr, val) (*((volatile uint64_t *)(addr)) = (val))
#define DEV_READ64(addr) (*((volatile uint64_t *)(addr)))

#define VOLATILE_READ(reg) (*((volatile __typeof((reg)) *)&(reg)))
#define VOLATILE_WRITE(reg, val) (*((volatile __typeof((reg)) *)&(reg)) = (__typeof((reg)))(val))
3 changes: 2 additions & 1 deletion sw/device/lib/hal/mocha.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ i2c_t mocha_system_i2c(void)
spi_device_t mocha_system_spi_device(void)
{
#if defined(__riscv_zcherihybrid)
return (spi_device_t)create_mmio_capability(spi_device_base, 0x1FC0u);
return (spi_device_t)create_mmio_capability(spi_device_base,
sizeof(struct spi_device_memory_layout));
#else /* !defined(__riscv_zcherihybrid) */
return (spi_device_t)spi_device_base;
#endif /* defined(__riscv_zcherihybrid) */
Expand Down
18 changes: 0 additions & 18 deletions sw/device/lib/hal/reg_field.h

This file was deleted.

Loading