From 29aca8aea6f932ecaae78b00d80483ca72ddcf9e Mon Sep 17 00:00:00 2001 From: Mateusz Faderewski Date: Tue, 16 Nov 2021 22:37:48 +0100 Subject: [PATCH] [SC64][FW][SW] Made CPU boot process simpler, UART is now an optional module (#12) --- .github/workflows/main.yml | 2 +- .gitmodules | 2 +- build.sh | 49 ++++++++---- fw/SummerCart64.cof | 2 +- fw/SummerCart64.qsf | 25 +------ fw/rtl/cpu/cpu_soc.sv | 27 ++++--- fw/rtl/cpu/cpu_wrapper.sv | 2 +- fw/rtl/intel/flash/intel_flash.qsys | 10 +-- fw/rtl/system/sc64.sv | 13 ++-- fw/scripts/{post_flow.tcl => post_module.tcl} | 2 +- sw/riscv/Makefile | 43 +++++------ sw/riscv/SC64.ld | 74 +++++++++---------- sw/riscv/src/dma.c | 5 -- sw/riscv/src/dma.h | 1 - sw/riscv/src/flashram.c | 47 +++++++++--- sw/riscv/src/handlers.c | 26 ------- sw/riscv/src/main.c | 7 -- sw/riscv/src/process.c | 29 +++++--- sw/riscv/src/rtc.c | 8 +- sw/riscv/src/startup.S | 48 ++++++++++++ sw/riscv/src/sys.h | 67 ++++++++--------- sw/riscv/src/uart.c | 5 -- sw/riscv/tools/bin2rom.py | 22 ------ sw/riscv/tools/bin2sv.py | 34 --------- sw/riscv/tools/cpu_bootloader_template.sv | 23 ------ 25 files changed, 261 insertions(+), 312 deletions(-) rename fw/scripts/{post_flow.tcl => post_module.tcl} (74%) delete mode 100644 sw/riscv/src/handlers.c delete mode 100644 sw/riscv/src/main.c create mode 100644 sw/riscv/src/startup.S delete mode 100644 sw/riscv/tools/bin2rom.py delete mode 100644 sw/riscv/tools/bin2sv.py delete mode 100644 sw/riscv/tools/cpu_bootloader_template.sv 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('