diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 0aa8995..4da4db4 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -22,7 +22,7 @@ jobs:
submodules: true
- name: Build script
- run: ./docker_build.sh release
+ run: ./docker_build.sh release --force-clean
- name: Upload artifact
uses: actions/upload-artifact@v2
diff --git a/.gitmodules b/.gitmodules
index cebf992..e1371e8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,4 @@
-[submodule "fw/cpu/picorv32"]
+[submodule "fw/picorv32"]
path = fw/picorv32
url = https://github.com/cliffordwolf/picorv32.git
ignore = dirty
diff --git a/build.sh b/build.sh
index c8aa6c9..0038ea3 100755
--- a/build.sh
+++ b/build.sh
@@ -19,6 +19,9 @@ BUILT_FPGA=false
BUILT_UPDATE=false
BUILT_RELEASE=false
+FORCE_CLEAN=false
+SKIP_FPGA_REBUILD=false
+
build_cic () {
if [ "$BUILT_CIC" = true ]; then return; fi
@@ -33,7 +36,10 @@ build_n64 () {
if [ "$BUILT_N64" = true ]; then return; fi
pushd sw/n64
- make clean all
+ if [ "$FORCE_CLEAN" = true ]; then
+ make clean
+ fi
+ make all
popd
BUILT_N64=true
@@ -43,7 +49,10 @@ build_riscv () {
if [ "$BUILT_RISCV" = true ]; then return; fi
pushd sw/riscv
- make clean all
+ if [ "$FORCE_CLEAN" = true ]; then
+ make clean
+ fi
+ make all
popd
BUILT_RISCV=true
@@ -56,7 +65,11 @@ build_fpga () {
build_riscv
pushd fw
- quartus_sh --flow compile ./SummerCart64.qpf
+ if [ "$SKIP_FPGA_REBUILD" = true ] && [ -f output_files/SummerCart64.sof ]; then
+ quartus_cpf -c SummerCart64.cof
+ else
+ quartus_sh --flow compile ./SummerCart64.qpf
+ fi
popd
BUILT_FPGA=true
@@ -82,25 +95,29 @@ build_release () {
build_cic
build_update
- if [[ -e "./${PACKAGE_FILE_NAME}.zip" ]]; then
+ if [ -e "./${PACKAGE_FILE_NAME}.zip" ]; then
rm -f "./${PACKAGE_FILE_NAME}.zip"
fi
- zip -r "./${PACKAGE_FILE_NAME}.zip" ${FILES[@]}
+ zip -j -r "./${PACKAGE_FILE_NAME}.zip" ${FILES[@]}
BUILT_RELEASE=true
}
print_usage () {
echo "builder script for SummerCart64"
- echo "usage: ./build.sh [cic] [n64] [riscv] [fpga] [update] [release] [--help]"
+ echo "usage: ./build.sh [cic] [n64] [riscv] [fpga] [update] [release] [-c] [-s] [--help]"
echo "parameters:"
- echo " cic - assemble UltraCIC-III software"
- echo " n64 - compile N64 bootloader software"
- echo " riscv - compile cart governor software"
- echo " fpga - compile FPGA design (triggers 'n64' and 'riscv' build)"
- echo " update - convert programming .pof file to raw binary for user upgrade (triggers 'fpga' build)"
- echo " release - collect and zip files for release (triggers 'cic' and 'update' build)"
- echo " --help - print this guide"
+ echo " cic - assemble UltraCIC-III software"
+ echo " n64 - compile N64 bootloader software"
+ echo " riscv - compile cart governor software"
+ echo " fpga - compile FPGA design (triggers 'n64' and 'riscv' build)"
+ echo " update - convert programming .pof file to raw binary for self-upgrade (triggers 'fpga' build)"
+ echo " release - collect and zip files for release (triggers 'cic' and 'update' build)"
+ echo " -c | --force-clean"
+ echo " - clean software compilation result directories before build"
+ echo " -s | --skip-fpga-rebuild"
+ echo " - do not recompile whole FPGA design if it's already done, just update software binaries"
+ echo " --help - print this guide"
}
if test $# -eq 0; then
@@ -137,6 +154,12 @@ while test $# -gt 0; do
release)
TRIGGER_RELEASE=true
;;
+ -c|--force-clean)
+ FORCE_CLEAN=true
+ ;;
+ -s|--skip-fpga-rebuild)
+ SKIP_FPGA_REBUILD=true
+ ;;
--help)
print_usage
exit 0
diff --git a/fw/SummerCart64.cof b/fw/SummerCart64.cof
index bf1be85..e3d8f89 100644
--- a/fw/SummerCart64.cof
+++ b/fw/SummerCart64.cof
@@ -28,7 +28,7 @@
0
2
../sw/n64/build/SummerLoader64.hex
- ../sw/riscv/build/controller.hex
+ ../sw/riscv/build/governor.hex
305152
diff --git a/fw/SummerCart64.qsf b/fw/SummerCart64.qsf
index b0b22b8..d2199ee 100644
--- a/fw/SummerCart64.qsf
+++ b/fw/SummerCart64.qsf
@@ -19,7 +19,7 @@
#
# Quartus Prime
# Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
-# Date created = 23:52:20 November 09, 2021
+# Date created = 13:29:40 November 11, 2021
#
# -------------------------------------------------------------------------- #
#
@@ -52,7 +52,6 @@ set_global_assignment -name QIP_FILE rtl/intel/gpio/intel_gpio_ddro.qip
set_global_assignment -name QIP_FILE rtl/intel/pll/intel_pll.qip
set_global_assignment -name SDC_FILE SummerCart64.sdc
set_global_assignment -name SYSTEMVERILOG_FILE picorv32/picorv32.v
-set_global_assignment -name SYSTEMVERILOG_FILE ../sw/riscv/build/cpu_bootloader.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_bus.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_cfg.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/cpu/cpu_dma.sv
@@ -83,7 +82,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/config.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/sc64.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/system/system.sv
set_global_assignment -name SYSTEMVERILOG_FILE rtl/usb/usb_ft1248.sv
-set_global_assignment -name POST_FLOW_SCRIPT_FILE "quartus_sh:scripts/post_flow.tcl"
+set_global_assignment -name POST_MODULE_SCRIPT_FILE "quartus_sh:scripts/post_module.tcl"
# Pin & Location Assignments
# ==========================
@@ -289,22 +288,4 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -
# -------------------------
# end ENTITY(SummerCart64)
-# ------------------------
-
-# ------------------------------
-# start ENTITY(altera_gpio_lite)
-
- # Project-Wide Assignments
- # ========================
-
-# end ENTITY(altera_gpio_lite)
-# ----------------------------
-
-# -----------------------------
-# start ENTITY(intel_gpio_ddro)
-
- # Project-Wide Assignments
- # ========================
-
-# end ENTITY(intel_gpio_ddro)
-# ---------------------------
\ No newline at end of file
+# ------------------------
\ No newline at end of file
diff --git a/fw/rtl/cpu/cpu_soc.sv b/fw/rtl/cpu/cpu_soc.sv
index 5d77544..14e82bd 100644
--- a/fw/rtl/cpu/cpu_soc.sv
+++ b/fw/rtl/cpu/cpu_soc.sv
@@ -40,9 +40,10 @@ module cpu_soc (
.bus(bus.at[sc64::ID_CPU_RAM].device)
);
- cpu_bootloader cpu_bootloader_inst (
+ cpu_flash cpu_flash_inst (
.sys(sys),
- .bus(bus.at[sc64::ID_CPU_BOOTLOADER].device)
+ .bus(bus.at[sc64::ID_CPU_FLASH].device),
+ .flash(flash)
);
cpu_gpio cpu_gpio_inst (
@@ -71,12 +72,16 @@ module cpu_soc (
.usb_pwren(usb_pwren)
);
- cpu_uart cpu_uart_inst (
- .sys(sys),
- .bus(bus.at[sc64::ID_CPU_UART].device),
- .uart_rxd(uart_rxd),
- .uart_txd(uart_txd)
- );
+ generate
+ if (sc64::CPU_HAS_UART) begin
+ cpu_uart cpu_uart_inst (
+ .sys(sys),
+ .bus(bus.at[sc64::ID_CPU_UART].device),
+ .uart_rxd(uart_rxd),
+ .uart_txd(uart_txd)
+ );
+ end
+ endgenerate
cpu_dma cpu_dma_inst (
.sys(sys),
@@ -108,12 +113,6 @@ module cpu_soc (
.si(si)
);
- cpu_flash cpu_flash_inst (
- .sys(sys),
- .bus(bus.at[sc64::ID_CPU_FLASH].device),
- .flash(flash)
- );
-
assign sd_clk = 1'bZ;
assign sd_cmd = 1'bZ;
assign sd_dat = 4'bZZZZ;
diff --git a/fw/rtl/cpu/cpu_wrapper.sv b/fw/rtl/cpu/cpu_wrapper.sv
index 3ac4040..aaededc 100644
--- a/fw/rtl/cpu/cpu_wrapper.sv
+++ b/fw/rtl/cpu/cpu_wrapper.sv
@@ -33,7 +33,7 @@ module cpu_wrapper (
.ENABLE_COUNTERS64(0),
.CATCH_MISALIGN(0),
.CATCH_ILLINSN(0),
- .PROGADDR_RESET({4'(sc64::ID_CPU_BOOTLOADER), 28'h000_0000})
+ .PROGADDR_RESET(sc64::CPU_RESET_VECTOR)
) cpu_inst (
.clk(sys.clk),
.resetn(~sys.reset),
diff --git a/fw/rtl/intel/flash/intel_flash.qsys b/fw/rtl/intel/flash/intel_flash.qsys
index c1fdaf6..5759c65 100644
--- a/fw/rtl/intel/flash/intel_flash.qsys
+++ b/fw/rtl/intel/flash/intel_flash.qsys
@@ -6,7 +6,7 @@
version="1.0"
description=""
tags="INTERNAL_COMPONENT=true"
- categories="" />
+ categories="System" />
Read and write,Read and write,Hidden,Read and write,Read and write
$${FILENAME}_onchip_flash_0
-
- ../sw/n64/build/SummerLoader64.hex
- ../sw/n64/build/SummerLoader64.hex
-
+
+
+
+
diff --git a/fw/rtl/system/sc64.sv b/fw/rtl/system/sc64.sv
index 5f63a3c..b14c128 100644
--- a/fw/rtl/system/sc64.sv
+++ b/fw/rtl/system/sc64.sv
@@ -11,7 +11,7 @@ package sc64;
typedef enum bit [3:0] {
ID_CPU_RAM,
- ID_CPU_BOOTLOADER,
+ ID_CPU_FLASH,
ID_CPU_GPIO,
ID_CPU_I2C,
ID_CPU_USB,
@@ -21,7 +21,6 @@ package sc64;
ID_CPU_SDRAM,
ID_CPU_FLASHRAM,
ID_CPU_SI,
- ID_CPU_FLASH,
__ID_CPU_END
} e_cpu_id;
@@ -31,10 +30,10 @@ package sc64;
__ID_DMA_END
} e_dma_id;
- parameter bit [31:0] SC64_VER = 32'h53437632;
-
- parameter int CLOCK_FREQUENCY = 32'd100_000_000;
-
- parameter int UART_BAUD_RATE = 32'd1_000_000;
+ parameter bit [31:0] SC64_VER = 32'h53437632;
+ parameter int CLOCK_FREQUENCY = 32'd100_000_000;
+ parameter bit [31:0] CPU_RESET_VECTOR = {4'(ID_CPU_FLASH), 28'h0035800};
+ parameter bit CPU_HAS_UART = 1'b0;
+ parameter int UART_BAUD_RATE = 32'd1_000_000;
endpackage
diff --git a/fw/scripts/post_flow.tcl b/fw/scripts/post_module.tcl
similarity index 74%
rename from fw/scripts/post_flow.tcl
rename to fw/scripts/post_module.tcl
index 9fa437e..ed19714 100644
--- a/fw/scripts/post_flow.tcl
+++ b/fw/scripts/post_module.tcl
@@ -1,6 +1,6 @@
set flow [lindex $quartus(args) 0]
-if [string match "compile" $flow] {
+if [string match "quartus_asm" $flow] {
post_message "Generating final programming file"
qexec "quartus_cpf -c SummerCart64.cof"
}
diff --git a/sw/riscv/Makefile b/sw/riscv/Makefile
index 897e6c5..6f1fdfd 100644
--- a/sw/riscv/Makefile
+++ b/sw/riscv/Makefile
@@ -1,47 +1,44 @@
TOOLCHAIN = riscv32-unknown-elf-
CC = $(TOOLCHAIN)gcc
+AS = $(TOOLCHAIN)as
OBJCOPY = $(TOOLCHAIN)objcopy
+OBJDUMP = $(TOOLCHAIN)objdump
SIZE = $(TOOLCHAIN)size
-FLAGS = -mabi=ilp32 -march=rv32i $(USER_FLAGS)
+FLAGS = -mabi=ilp32 -march=rv32i
CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP
LDFLAGS = -nostartfiles -Wl,--gc-sections
SRC_DIR = src
BUILD_DIR = build
-SRCS = $(wildcard $(patsubst %, %/*.c, . $(SRC_DIR)))
-OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(SRCS:.c=.o)))
+SRC_FILES = startup.S process.c usb.c cfg.c dma.c joybus.c rtc.c i2c.c flashram.c uart.c flash.c
+
+SRCS = $(addprefix $(SRC_DIR)/, $(SRC_FILES))
+OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(patsubst %,%.o,$(SRCS))))
DEPS = $(OBJS:.o=.d)
VPATH = $(SRC_DIR)
$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
-all: $(BUILD_DIR)/cpu_bootloader.sv $(BUILD_DIR)/controller.rom
+all: $(BUILD_DIR)/governor.hex
-$(BUILD_DIR)/%.o: %.c
- $(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
+$(BUILD_DIR)/%.c.o: %.c
+ $(CC) $(FLAGS) $(CFLAGS) $(USER_FLAGS) -c $< -o $@
-$(BUILD_DIR)/uc.elf: $(OBJS) SC64.ld
- $(CC) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -o $@
+$(BUILD_DIR)/%.S.o: %.S
+ $(AS) $(FLAGS) $(ASFLAGS) -c $< -o $@
-$(BUILD_DIR)/controller.rom: $(BUILD_DIR)/uc.elf
- $(OBJCOPY) -R .bootloader $(BUILD_DIR)/uc.elf $(BUILD_DIR)/controller.elf
- $(OBJCOPY) -O binary --set-section-flags .bss=alloc,contents $(BUILD_DIR)/controller.elf $(BUILD_DIR)/controller.bin
- $(OBJCOPY) -I binary -O ihex $(BUILD_DIR)/controller.bin $(BUILD_DIR)/controller.hex
- python3 tools/bin2rom.py $@ < $(BUILD_DIR)/controller.bin
- @echo 'Size of controller modules:'
+$(BUILD_DIR)/governor.hex: $(OBJS) SC64.ld
+ $(CC) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -o $(BUILD_DIR)/governor.elf
+ $(OBJDUMP) -D $(BUILD_DIR)/governor.elf > $(BUILD_DIR)/governor.map
+ $(OBJCOPY) -O binary $(BUILD_DIR)/governor.elf $(BUILD_DIR)/governor.bin
+ $(OBJCOPY) -I binary -O ihex $(BUILD_DIR)/governor.bin $@
+ @echo 'Size of modules:'
@$(SIZE) -B -t --common $(OBJS)
- @echo 'Size of controller:'
- @$(SIZE) -B $(BUILD_DIR)/controller.elf
-
-$(BUILD_DIR)/cpu_bootloader.sv: $(BUILD_DIR)/uc.elf
- $(OBJCOPY) -j .bootloader $(BUILD_DIR)/uc.elf $(BUILD_DIR)/bootloader.elf
- $(OBJCOPY) -O binary $(BUILD_DIR)/bootloader.elf $(BUILD_DIR)/bootloader.bin
- python3 tools/bin2sv.py tools/cpu_bootloader_template.sv $@ < $(BUILD_DIR)/bootloader.bin
- @echo 'Size of bootloader:'
- @$(SIZE) -B $(BUILD_DIR)/bootloader.elf
+ @echo 'Size of governor:'
+ @$(SIZE) -B $(BUILD_DIR)/governor.elf
clean:
rm -rf ./$(BUILD_DIR)/*
diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld
index 2ca7c56..30e29bd 100644
--- a/sw/riscv/SC64.ld
+++ b/sw/riscv/SC64.ld
@@ -1,51 +1,49 @@
MEMORY {
- RAM (rwx) : org = 0x00000000, len = 16k
- ROM (rx) : org = 0x10000000, len = 128
+ ram (rwx) : org = 0x00000000, len = 16k
+ rom (rx) : org = 0x10035800, len = 16k
}
-__stack_pointer = ORIGIN(RAM) + LENGTH(RAM) - 16;
-
ENTRY(reset_handler)
SECTIONS {
- .text : {
- *(.text.app_handler)
- *(.text.unlikely .text.unlikely.*)
- *(.text.startup .text.startup.*)
- *(.text .text.*)
- *(.gnu.linkonce.t.*)
- } > RAM
+ .text.reset_handler : {
+ *(.text.reset_handler)
+ } > rom
- .rodata : {
- *(.rdata)
- *(.rodata .rodata.*)
- *(.gnu.linkonce.r.*)
- . = ALIGN(8);
- *(.srodata.cst16)
- *(.srodata.cst8)
- *(.srodata.cst4)
- *(.srodata.cst2)
- *(.srodata .srodata.*)
- } > RAM
+ .text : {
+ _sitext = LOADADDR(.text);
+ . = ALIGN(4);
+ _stext = .;
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ . = ALIGN(4);
+ _etext = .;
+ } > ram AT > rom
.data : {
- *(.data .data.*)
- *(.gnu.linkonce.d.*)
- . = ALIGN(8);
- PROVIDE(__global_pointer = . + 0x800);
- *(.sdata .sdata.* .sdata2.*)
- *(.gnu.linkonce.s.*)
- } > RAM
+ _sidata = LOADADDR(.data);
+ . = ALIGN(4);
+ _sdata = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN(4);
+ _ssdata = .;
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(4);
+ _edata = .;
+ } > ram AT > rom
- .bss : ALIGN(8) {
- *(.sbss*)
- *(.gnu.linkonce.sb.*)
- *(.bss .bss.*)
- *(.gnu.linkonce.b.*)
+ .bss : {
+ . = ALIGN(4);
+ _sbss = .;
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ *(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
- } > RAM
+ . = ALIGN(4);
+ _ebss = .;
+ } > ram
- .bootloader : {
- *(.text.reset_handler)
- } > ROM
+ __global_pointer$ = MIN(_ssdata + 0x800, MAX(_sdata + 0x800, _ebss - 0x800));
+ __stack_pointer$ = ORIGIN(ram) + LENGTH(ram);
}
diff --git a/sw/riscv/src/dma.c b/sw/riscv/src/dma.c
index 3015753..243a558 100644
--- a/sw/riscv/src/dma.c
+++ b/sw/riscv/src/dma.c
@@ -19,8 +19,3 @@ void dma_stop (void) {
void dma_init (void) {
dma_stop();
}
-
-
-void process_dma (void) {
-
-}
diff --git a/sw/riscv/src/dma.h b/sw/riscv/src/dma.h
index e259cbb..75462a7 100644
--- a/sw/riscv/src/dma.h
+++ b/sw/riscv/src/dma.h
@@ -20,7 +20,6 @@ bool dma_busy (void);
void dma_start (uint32_t memory_address, size_t length, enum dma_id id, enum dma_dir dir);
void dma_stop (void);
void dma_init (void);
-void process_dma (void);
#endif
diff --git a/sw/riscv/src/flashram.c b/sw/riscv/src/flashram.c
index b850472..02c5b5a 100644
--- a/sw/riscv/src/flashram.c
+++ b/sw/riscv/src/flashram.c
@@ -14,6 +14,17 @@ enum operation {
};
+struct process {
+ bool save_in_progress;
+ enum operation op;
+ io32_t *save_pointer;
+ uint32_t num_words;
+ uint32_t current_word;
+};
+
+static struct process p;
+
+
static enum operation get_operation_type (void) {
uint32_t scr = FLASHRAM->SCR;
@@ -44,26 +55,38 @@ static size_t get_operation_length (enum operation op) {
void flashram_init (void) {
FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
+
+ p.save_in_progress = false;
}
void process_flashram (void) {
- enum operation op = get_operation_type();
- size_t length;
- io32_t *save_data;
+ if (!p.save_in_progress) {
+ p.op = get_operation_type();
- if (op != OP_NONE) {
- length = get_operation_length(op);
- save_data = (io32_t *) (SDRAM_BASE + CFG->SAVE_OFFSET + ((FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE));
+ if (p.op != OP_NONE) {
+ uint32_t sdram_address = SDRAM_BASE + CFG->SAVE_OFFSET;
- for (uint32_t i = 0; i < (length / 4); i++) {
- if (op == OP_WRITE_PAGE) {
- *save_data++ &= FLASHRAM->BUFFER[i];
- } else {
- *save_data++ = FLASHRAM_ERASE_VALUE;
+ p.save_in_progress = true;
+ if (p.op != OP_ERASE_ALL) {
+ sdram_address += (FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE;
}
+ p.save_pointer = (io32_t *) (sdram_address);
+ p.num_words = get_operation_length(p.op) / sizeof(uint32_t);
+ p.current_word = 0;
+ }
+ } else {
+ if (p.op == OP_WRITE_PAGE) {
+ *p.save_pointer++ &= FLASHRAM->BUFFER[p.current_word];
+ } else {
+ *p.save_pointer++ = FLASHRAM_ERASE_VALUE;
}
- FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
+ p.current_word += 1;
+
+ if (p.current_word >= p.num_words) {
+ p.save_in_progress = false;
+ FLASHRAM->SCR = FLASHRAM_OPERATION_DONE;
+ }
}
}
diff --git a/sw/riscv/src/handlers.c b/sw/riscv/src/handlers.c
deleted file mode 100644
index dfc69de..0000000
--- a/sw/riscv/src/handlers.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include
-#include "sys.h"
-
-
-__attribute__ ((naked, section(".bootloader"))) void reset_handler (void) {
- io32_t *ram = (io32_t *) &RAM;
- io32_t *flash = (io32_t *) (FLASH_BASE + FLASH_CPU_IMAGE_OFFSET);
-
- for (int i = 0; i < RAM_SIZE; i += 4) {
- *ram++ = *flash++;
- }
-
- __asm__ volatile (
- "la t0, app_handler \n"
- "jalr zero, t0 \n"
- );
-}
-
-
-__attribute__ ((naked)) void app_handler (void) {
- __asm__ volatile (
- "la sp, __stack_pointer \n"
- "la gp, __global_pointer \n"
- "jal zero, main \n"
- );
-}
diff --git a/sw/riscv/src/main.c b/sw/riscv/src/main.c
deleted file mode 100644
index d539a5f..0000000
--- a/sw/riscv/src/main.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "process.h"
-
-
-void main (void) {
- process_init();
- process_loop();
-}
diff --git a/sw/riscv/src/process.c b/sw/riscv/src/process.c
index 093ded3..4f7c2e3 100644
--- a/sw/riscv/src/process.c
+++ b/sw/riscv/src/process.c
@@ -9,7 +9,20 @@
#include "uart.h"
-void process_init (void) {
+static const void (*process_table[])(void) = {
+ process_usb,
+ process_cfg,
+ process_rtc,
+ process_i2c,
+ process_flashram,
+ process_uart,
+ NULL,
+};
+
+
+__attribute__((naked)) void process_loop (void) {
+ void (**process_func)(void) = process_table;
+
usb_init();
cfg_init();
dma_init();
@@ -18,18 +31,12 @@ void process_init (void) {
i2c_init();
flashram_init();
uart_init();
-}
-
-void process_loop (void) {
while (1) {
- process_usb();
- process_cfg();
- process_dma();
process_joybus();
- process_rtc();
- process_i2c();
- process_flashram();
- process_uart();
+ (*process_func++)();
+ if (*process_func == NULL) {
+ process_func = process_table;
+ }
}
}
diff --git a/sw/riscv/src/rtc.c b/sw/riscv/src/rtc.c
index c8c82b1..4c203c2 100644
--- a/sw/riscv/src/rtc.c
+++ b/sw/riscv/src/rtc.c
@@ -86,7 +86,13 @@ bool rtc_is_time_running (void) {
}
void rtc_set_time (rtc_time_t *time) {
- p.time = *time;
+ p.time.second = time->second;
+ p.time.minute = time->minute;
+ p.time.hour = time->hour;
+ p.time.weekday = time->weekday;
+ p.time.day = time->day;
+ p.time.month = time->month;
+ p.time.year = time->year;
p.new_time_valid = true;
}
diff --git a/sw/riscv/src/startup.S b/sw/riscv/src/startup.S
new file mode 100644
index 0000000..0eb3670
--- /dev/null
+++ b/sw/riscv/src/startup.S
@@ -0,0 +1,48 @@
+.section .text.reset_handler
+
+reset_handler:
+ .global reset_handler
+
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+
+ la sp, __stack_pointer$
+
+init_text:
+ la a0, _sitext
+ la a1, _stext
+ la a2, _etext
+ call copy_section
+
+init_data:
+ la a0, _sidata
+ la a1, _sdata
+ la a2, _edata
+ call copy_section
+
+init_bss:
+ la a0, _sbss
+ la a1, _ebss
+ bge a0, a1, 2f
+1:
+ sw zero, 0(a0)
+ addi a0, a0, 4
+ blt a0, a1, 1b
+2:
+
+run_in_ram:
+ la ra, process_loop
+ jalr zero, 0(ra)
+
+copy_section:
+ bge a1, a2, 2f
+1:
+ lw a3, 0(a0)
+ sw a3, 0(a1)
+ addi a0, a0, 4
+ addi a1, a1, 4
+ blt a1, a2, 1b
+2:
+ ret
diff --git a/sw/riscv/src/sys.h b/sw/riscv/src/sys.h
index b17f233..9b7db5b 100644
--- a/sw/riscv/src/sys.h
+++ b/sw/riscv/src/sys.h
@@ -16,8 +16,35 @@ typedef volatile uint32_t io32_t;
#define RAM_SIZE (16 * 1024)
-#define BOOTLOADER_BASE (0x10000000UL)
-#define BOOTLOADER (*((io32_t *) BOOTLOADER_BASE))
+#define FLASH_BASE (0x10000000UL)
+#define FLASH (*((io32_t *) FLASH_BASE))
+
+#define FLASH_SIZE (0x39800)
+#define FLASH_NUM_SECTORS (4)
+
+
+typedef volatile struct flash_config_regs {
+ io32_t SR;
+ io32_t CR;
+} flash_config_regs_t;
+
+#define FLASH_CONFIG_BASE (0x18000000UL)
+#define FLASH_CONFIG ((flash_config_regs_t *) FLASH_CONFIG_BASE)
+
+#define FLASH_SR_STATUS_MASK (3 << 0)
+#define FLASH_SR_STATUS_IDLE (0)
+#define FLASH_SR_STATUS_BUSY_ERASE (1)
+#define FLASH_SR_STATUS_BUSY_WRITE (2)
+#define FLASH_SR_STATUS_BUSY_READ (3)
+#define FLASH_SR_READ_SUCCESSFUL (1 << 2)
+#define FLASH_SR_WRITE_SUCCESSFUL (1 << 3)
+#define FLASH_SR_ERASE_SUCCESSFUL (1 << 4)
+#define FLASH_SR_WRITE_PROTECT_BIT (5)
+
+#define FLASH_CR_PAGE_ERASE_BIT (0)
+#define FLASH_CR_SECTOR_ERASE_BIT (20)
+#define FLASH_CR_SECTOR_ERASE_MASK (7 << FLASH_CR_SECTOR_ERASE_BIT)
+#define FLASH_CR_WRITE_PROTECT_BIT (23)
typedef volatile struct gpio_regs {
@@ -158,40 +185,4 @@ typedef volatile struct joybus_regs {
#define JOYBUS_SCR_TX_LENGTH_BIT (16)
-#define FLASH_BASE (0xB0000000UL)
-#define FLASH (*((io32_t *) FLASH_BASE))
-
-#define FLASH_CPU_IMAGE_OFFSET (0x35800)
-#define FLASH_SIZE (0x39800)
-#define FLASH_NUM_SECTORS (4)
-
-
-typedef volatile struct flash_config_regs {
- io32_t SR;
- io32_t CR;
-} flash_config_regs_t;
-
-#define FLASH_CONFIG_BASE (0xB8000000UL)
-#define FLASH_CONFIG ((flash_config_regs_t *) FLASH_CONFIG_BASE)
-
-#define FLASH_SR_STATUS_MASK (3 << 0)
-#define FLASH_SR_STATUS_IDLE (0)
-#define FLASH_SR_STATUS_BUSY_ERASE (1)
-#define FLASH_SR_STATUS_BUSY_WRITE (2)
-#define FLASH_SR_STATUS_BUSY_READ (3)
-#define FLASH_SR_READ_SUCCESSFUL (1 << 2)
-#define FLASH_SR_WRITE_SUCCESSFUL (1 << 3)
-#define FLASH_SR_ERASE_SUCCESSFUL (1 << 4)
-#define FLASH_SR_WRITE_PROTECT_BIT (5)
-
-#define FLASH_CR_PAGE_ERASE_BIT (0)
-#define FLASH_CR_SECTOR_ERASE_BIT (20)
-#define FLASH_CR_SECTOR_ERASE_MASK (7 << FLASH_CR_SECTOR_ERASE_BIT)
-#define FLASH_CR_WRITE_PROTECT_BIT (23)
-
-
-void reset_handler (void);
-void app_handler (void);
-
-
#endif
diff --git a/sw/riscv/src/uart.c b/sw/riscv/src/uart.c
index 47c1b70..011b8cd 100644
--- a/sw/riscv/src/uart.c
+++ b/sw/riscv/src/uart.c
@@ -54,11 +54,6 @@ void process_uart (void) {
reset_handler();
break;
- case '\'':
- uart_print("App reset...\n");
- app_handler();
- break;
-
case 't':
time = rtc_get_time();
uart_print("Current time: ");
diff --git a/sw/riscv/tools/bin2rom.py b/sw/riscv/tools/bin2rom.py
deleted file mode 100644
index 390f3cb..0000000
--- a/sw/riscv/tools/bin2rom.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env python3
-import os
-import sys
-
-rom = None
-
-rom_name = sys.argv[1] or 'rom.bin'
-
-try:
- binary_data = sys.stdin.buffer.read()
- if (os.path.exists(rom_name)):
- os.remove(rom_name)
- rom = open(rom_name, mode='wb')
- rom.write(len(binary_data).to_bytes(4, byteorder='little'))
- rom.write(binary_data)
-
-except Exception as e:
- print(f'Unable to convert the rom: {e}', file=sys.stderr)
- sys.exit(-1)
-
-finally:
- if (rom): rom.close()
diff --git a/sw/riscv/tools/bin2sv.py b/sw/riscv/tools/bin2sv.py
deleted file mode 100644
index bee77f6..0000000
--- a/sw/riscv/tools/bin2sv.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python3
-import struct
-import sys
-
-sv_template = None
-sv_code = None
-
-template_name = sys.argv[1] or 'template.sv'
-code_name = sys.argv[2] or 'result.sv'
-
-try:
- sv_template = open(template_name, mode='r')
- sv_code = open(code_name, mode='w')
-
- var_name = sv_template.readline().strip()
-
- rom_formatted = ''
- index = 0
- for line in iter(lambda: sys.stdin.buffer.read(4), ''):
- if (not line):
- break
- value = format(struct.unpack('