diff --git a/build.sh b/build.sh index 6a0adb0..196ab45 100755 --- a/build.sh +++ b/build.sh @@ -15,6 +15,7 @@ FILES=( BUILT_CIC=false BUILT_N64=false BUILT_RISCV=false +BUILT_SW=false BUILT_FPGA=false BUILT_UPDATE=false BUILT_RELEASE=false @@ -44,7 +45,6 @@ build_n64 () { if [ ! -z "${GIT_BRANCH+x}" ]; then N64_FLAGS+=" -DGIT_BRANCH='\"$GIT_BRANCH\"'"; fi if [ ! -z "${GIT_TAG+x}" ]; then N64_FLAGS+=" -DGIT_TAG='\"$GIT_TAG\"'"; fi if [ ! -z "${GIT_SHA+x}" ]; then N64_FLAGS+=" -DGIT_SHA='\"$GIT_SHA\"'"; fi - if [ ! -z "${GIT_MESSAGE+x}" ]; then N64_FLAGS+=" -DGIT_MESSAGE='\"$GIT_MESSAGE\"'"; fi make all -j USER_FLAGS="$N64_FLAGS" popd > /dev/null @@ -64,15 +64,29 @@ build_riscv () { BUILT_RISCV=true } -build_fpga () { - if [ "$BUILT_FPGA" = true ]; then return; fi +build_sw () { + if [ "$BUILT_SW" = true ]; then return; fi build_n64 build_riscv + pushd fw > /dev/null + mkdir -p output_files > /dev/null + cat ../sw/n64/build/n64boot.bin ../sw/riscv/build/governor.bin > output_files/SC64_software.bin + objcopy -I binary -O ihex output_files/SC64_software.bin output_files/SC64_software.hex + popd + + BUILT_SW=true +} + +build_fpga () { + if [ "$BUILT_FPGA" = true ]; then return; fi + + build_sw + pushd fw > /dev/null if [ "$SKIP_FPGA_REBUILD" = true ] && [ -f output_files/SummerCart64.sof ]; then - quartus_cpf -c SummerCart64.cof + echo Skipping FPGA build else if [ "$DEBUG_ENABLED" = true ]; then quartus_sh --set VERILOG_MACRO="DEBUG" ./SummerCart64.qpf @@ -91,9 +105,8 @@ build_update () { build_fpga pushd fw/output_files > /dev/null - cat sc64_firmware_ufm_auto.rpd sc64_firmware_cfm0_auto.rpd > SC64_update_tmp.bin - objcopy -I binary -O binary --reverse-bytes=4 SC64_update_tmp.bin SC64_update.bin - rm SC64_update_tmp.bin + objcopy -I binary -O binary --reverse-bytes=4 sc64_firmware_cfm0_auto.rpd SC64_firmware.bin + cat SC64_software.bin SC64_firmware.bin > SC64_update.bin popd > /dev/null BUILT_UPDATE=true @@ -120,7 +133,8 @@ print_usage () { 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 " sw - compile all software (triggers 'n64' and 'riscv' build)" + echo " fpga - compile FPGA design (triggers 'sw' 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" @@ -142,6 +156,7 @@ fi TRIGGER_CIC=false TRIGGER_N64=false TRIGGER_RISCV=false +TRIGGER_SW=false TRIGGER_FPGA=false TRIGGER_UPDATE=false TRIGGER_RELEASE=false @@ -157,6 +172,9 @@ while test $# -gt 0; do riscv) TRIGGER_RISCV=true ;; + sw) + TRIGGER_SW=true + ;; fpga) TRIGGER_FPGA=true ;; @@ -193,6 +211,7 @@ if [ "$DEBUG_ENABLED" = true ]; then USER_FLAGS+=" -DDEBUG"; fi if [ "$TRIGGER_CIC" = true ]; then build_cic; fi if [ "$TRIGGER_N64" = true ]; then build_n64; fi if [ "$TRIGGER_RISCV" = true ]; then build_riscv; fi +if [ "$TRIGGER_SW" = true ]; then build_sw; fi if [ "$TRIGGER_FPGA" = true ]; then build_fpga; fi if [ "$TRIGGER_UPDATE" = true ]; then build_update; fi if [ "$TRIGGER_RELEASE" = true ]; then build_release; fi diff --git a/docker_build.sh b/docker_build.sh index b4391c9..33e5dcb 100755 --- a/docker_build.sh +++ b/docker_build.sh @@ -16,7 +16,6 @@ fi GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) GIT_TAG=$(git describe --tags 2> /dev/null) GIT_SHA=$(git rev-parse HEAD) -GIT_MESSAGE=$(git log -1 --pretty=format:%s) if [ -t 1 ]; then DOCKER_OPTIONS="-it" @@ -27,6 +26,5 @@ docker exec \ -e GIT_BRANCH="$GIT_BRANCH" \ -e GIT_TAG="$GIT_TAG" \ -e GIT_SHA="$GIT_SHA" \ - -e GIT_MESSAGE="$GIT_MESSAGE" \ $CONTAINER_NAME \ ./build.sh $@ diff --git a/fw/SummerCart64.cof b/fw/SummerCart64.cof index ebd1b9d..d10644c 100644 --- a/fw/SummerCart64.cof +++ b/fw/SummerCart64.cof @@ -27,9 +27,7 @@ 0 0 2 - ../sw/n64/build/n64boot.hex - ../sw/riscv/build/governor.hex - 305152 + output_files/SC64_software.hex 1 diff --git a/fw/rtl/n64/n64_bootloader.sv b/fw/rtl/n64/n64_bootloader.sv index 0f5942e..76565a4 100644 --- a/fw/rtl/n64/n64_bootloader.sv +++ b/fw/rtl/n64/n64_bootloader.sv @@ -89,7 +89,7 @@ module n64_bootloader ( bus.ack = source_request == T_N64 && data_ack; bus.rdata = 16'd0; - if (bus.ack && bus.address >= 32'h10000000 && bus.address < 32'h10016800) begin + if (bus.ack && bus.address >= 32'h10000000 && bus.address < 32'h10010000) begin if (bus.address[1]) bus.rdata = {data_rdata[23:16], data_rdata[31:24]}; else bus.rdata = {data_rdata[7:0], data_rdata[15:8]}; end diff --git a/fw/rtl/system/sc64.sv b/fw/rtl/system/sc64.sv index 9facdb1..224d5c2 100644 --- a/fw/rtl/system/sc64.sv +++ b/fw/rtl/system/sc64.sv @@ -33,7 +33,7 @@ package sc64; 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 [31:0] CPU_RESET_VECTOR = {4'(ID_CPU_FLASH), 28'h0010000}; parameter int UART_BAUD_RATE = 32'd1_000_000; `ifdef DEBUG diff --git a/sw/n64/Makefile b/sw/n64/Makefile index cdad8c1..23caa7b 100644 --- a/sw/n64/Makefile +++ b/sw/n64/Makefile @@ -15,16 +15,16 @@ BUILD_DIR = build SRC_FILES = \ startup.S \ - ipl2.S \ - exception.S \ boot.c \ crc32.c \ error.c \ exception.c \ + exception.S \ font.c \ init.c \ interrupt.c \ io.c \ + ipl2.S \ main.c \ sc64.c \ storage.c \ @@ -56,7 +56,7 @@ $(BUILD_DIR)/n64boot.elf: $(OBJS) N64.ld $(BUILD_DIR)/n64boot.bin: $(BUILD_DIR)/n64boot.elf @$(OBJCOPY) -O binary $< $@ @chksum64 $@ > /dev/null - @truncate --size=90k $@ + @truncate --size=64k $@ $(BUILD_DIR)/n64boot.hex: $(BUILD_DIR)/n64boot.bin @$(OBJCOPY) -I binary -O ihex $< $@ diff --git a/sw/n64/N64.ld b/sw/n64/N64.ld index 52415fb..b4d0349 100644 --- a/sw/n64/N64.ld +++ b/sw/n64/N64.ld @@ -1,12 +1,12 @@ MEMORY { - rdram (rwx) : org = 0x80300000, len = 1M - flash (r) : org = 0xB0000000, len = 90k + rdram (rwx) : org = 0x803E0000, len = 128k + flash (r) : org = 0xB0000000, len = 64k } ENTRY(entry_handler) __exception_stack_size = 8k; -__stack_size = 64k; +__stack_size = 16k; SECTIONS { .flash : { diff --git a/sw/n64/src/exception.c b/sw/n64/src/exception.c index 72c9db7..54bab75 100644 --- a/sw/n64/src/exception.c +++ b/sw/n64/src/exception.c @@ -76,6 +76,8 @@ typedef struct { #define START_X_OFFSET (19) +extern const io32_t entry_handler __attribute__((section(".data"))); + static const vi_regs_t vi_config[] = {{ .CR = VI_CR_TYPE_32, .H_WIDTH = SCREEN_WIDTH, @@ -106,12 +108,14 @@ static const vi_regs_t vi_config[] = {{ .V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60), }}; -static io32_t *exception_framebuffer = (io32_t *) (0x0026A000UL); +static io32_t *exception_framebuffer; static void exception_init_screen (void) { const vi_regs_t *cfg = &vi_config[OS_INFO->tv_type]; + exception_framebuffer = (io32_t *) (((io32_t) (&entry_handler)) - (SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(io32_t))); + for (int y = 0; y < SCREEN_HEIGHT; y++) { for (int x = 0; x < SCREEN_WIDTH; x++) { uint32_t color; @@ -237,8 +241,7 @@ void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask, exception_print("----- SummerCart64 n64boot -----\n"); exception_print("branch: %s\n", version->git_branch); exception_print("tag: %s\n", version->git_tag); - exception_print("sha: %s\n", version->git_sha); - exception_print("msg: %s\n\n", version->git_message); + exception_print("sha: %s\n\n", version->git_sha); exception_print("%s at pc: 0x%08lX\n", exception_get_description(exception_code), e->epc.u32); exception_print("sr: 0x%08lX cr: 0x%08lX hw: 0x%08lX [%4s]\n", e->sr, e->cr, sc64_version, (char *) (&sc64_version)); exception_print("zr: 0x%08lX at: 0x%08lX v0: 0x%08lX v1: 0x%08lX\n", e->zr.u32, e->at.u32, e->v0.u32, e->v1.u32); diff --git a/sw/n64/src/storage.c b/sw/n64/src/storage.c index 3774ff8..220c8ca 100644 --- a/sw/n64/src/storage.c +++ b/sw/n64/src/storage.c @@ -4,6 +4,11 @@ #include "fatfs/ff.h" +#define ROM_ENTRY_OFFSET (8) +#define ROM_CODE_OFFSET (4096) +#define ROM_MAX_LOAD_SIZE (1 * 1024 * 1024) + + static const char *fatfs_error_codes[] = { "Succeeded", "A hard error occurred in the low level disk I/O layer", @@ -28,35 +33,47 @@ static const char *fatfs_error_codes[] = { }; -#define FF_CHECK(x, message) { \ - FRESULT fatfs_result = x; \ - if (fatfs_result != FR_OK) { \ - error_display("%s:\n %s\n", message, fatfs_error_codes[fatfs_result]); \ +#define FF_CHECK(x, message, ...) { \ + fresult = x; \ + if (fresult != FR_OK) { \ + error_display(message " [%s]:\n %s\n", __VA_ARGS__ __VA_OPT__(,) #x, fatfs_error_codes[fresult]); \ } \ } void storage_run_menu (storage_backend_t storage_backend) { + void (* menu)(void); + FRESULT fresult; FATFS fs; FIL fil; + UINT br; + FSIZE_t size = ROM_MAX_LOAD_SIZE; + const TCHAR *path = ""; if (storage_backend == STORAGE_BACKEND_SD) { - FF_CHECK(f_mount(&fs, "0:", 1), "Couldn't mount SD drive"); - FF_CHECK(f_chdrive("0:"), "Couldn't chdrive to SD drive"); + path = "0:"; } else if (storage_backend == STORAGE_BACKEND_USB) { - FF_CHECK(f_mount(&fs, "1:", 1), "Couldn't mount USB drive"); - FF_CHECK(f_chdrive("1:"), "Couldn't chdrive to USB drive"); + path = "1:"; } else { error_display("Unknown storage backend [%d]\n", storage_backend); } - FF_CHECK(f_open(&fil, "sc64menu.elf", FA_READ), "Couldn't open menu file"); - - // TODO: Implement ELF loader here - + FF_CHECK(f_mount(&fs, path, 1), "Couldn't mount drive"); + FF_CHECK(f_chdrive(path), "Couldn't chdrive"); + FF_CHECK(f_open(&fil, "sc64menu.n64", FA_READ), "Couldn't open menu file"); + FF_CHECK(f_lseek(&fil, ROM_ENTRY_OFFSET), "Couldn't seek to entry point offset"); + FF_CHECK(f_read(&fil, &menu, sizeof(menu), &br), "Couldn't read entry point"); + FF_CHECK(f_lseek(&fil, ROM_CODE_OFFSET), "Couldn't seek to code start offset"); + if ((f_size(&fil) - ROM_CODE_OFFSET) < size) { + size = (f_size(&fil) - ROM_CODE_OFFSET); + } + FF_CHECK(f_read(&fil, menu, size, &br), "Couldn't read menu file"); + FF_CHECK(br != size, "Read size is different than expected"); FF_CHECK(f_close(&fil), "Couldn't close menu file"); deinit(); - // menu(); + menu(); + + while (1); } diff --git a/sw/n64/src/version.c b/sw/n64/src/version.c index 1f1b0ef..47401e4 100644 --- a/sw/n64/src/version.c +++ b/sw/n64/src/version.c @@ -1,7 +1,7 @@ #include "version.h" -version_t version = { +static version_t version = { #ifdef GIT_BRANCH .git_branch = GIT_BRANCH, #else @@ -17,11 +17,6 @@ version_t version = { #else #warning "No GIT_SHA provided" #endif -#ifdef GIT_MESSAGE - .git_message = GIT_MESSAGE, -#else -#warning "No GIT_MESSAGE provided" -#endif }; diff --git a/sw/n64/src/version.h b/sw/n64/src/version.h index 8b875ed..439e320 100644 --- a/sw/n64/src/version.h +++ b/sw/n64/src/version.h @@ -6,7 +6,6 @@ typedef const struct { const char *git_branch; const char *git_tag; const char *git_sha; - const char *git_message; } version_t; diff --git a/sw/riscv/Makefile b/sw/riscv/Makefile index 6ce172d..4d24214 100644 --- a/sw/riscv/Makefile +++ b/sw/riscv/Makefile @@ -46,7 +46,7 @@ $(BUILD_DIR)/governor.elf: $(OBJS) SC64.ld @$(OBJDUMP) -D $@ > $(BUILD_DIR)/governor.lst $(BUILD_DIR)/governor.bin: $(BUILD_DIR)/governor.elf - @$(OBJCOPY) -O binary $< $@ + @$(OBJCOPY) -O binary --gap-fill 0xFF --pad-to 0x10016800 $< $@ $(BUILD_DIR)/governor.hex: $(BUILD_DIR)/governor.bin @$(OBJCOPY) -I binary -O ihex $< $@ diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld index bae2abd..8b3874a 100644 --- a/sw/riscv/SC64.ld +++ b/sw/riscv/SC64.ld @@ -1,6 +1,6 @@ MEMORY { ram (rwx) : org = 0x00000000, len = 16k - rom (rx) : org = 0x10035800, len = 16k + rom (rx) : org = 0x10010000, len = 26k } ENTRY(reset_handler)