diff --git a/build.sh b/build.sh index 01e1a29..3ae8020 100755 --- a/build.sh +++ b/build.sh @@ -25,9 +25,9 @@ SKIP_FPGA_REBUILD=false build_cic () { if [ "$BUILT_CIC" = true ]; then return; fi - pushd sw/cic + pushd sw/cic > /dev/null avra UltraCIC-III.asm -D attiny45 - popd + popd > /dev/null BUILT_CIC=true } @@ -35,12 +35,12 @@ build_cic () { build_n64 () { if [ "$BUILT_N64" = true ]; then return; fi - pushd sw/n64 + pushd sw/n64 > /dev/null if [ "$FORCE_CLEAN" = true ]; then make clean fi - make all -j - popd + make all -j USER_FLAGS="-D__SC64_VERSION=\"$__SC64_VERSION\"" + popd > /dev/null BUILT_N64=true } @@ -48,12 +48,12 @@ build_n64 () { build_riscv () { if [ "$BUILT_RISCV" = true ]; then return; fi - pushd sw/riscv + pushd sw/riscv > /dev/null if [ "$FORCE_CLEAN" = true ]; then make clean -j fi - make all - popd + make all USER_FLAGS="-D__SC64_VERSION=\"$__SC64_VERSION\"" + popd > /dev/null BUILT_RISCV=true } @@ -64,13 +64,13 @@ build_fpga () { build_n64 build_riscv - pushd fw + pushd fw > /dev/null 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 + popd > /dev/null BUILT_FPGA=true } @@ -80,11 +80,11 @@ build_update () { build_fpga - pushd fw/output_files + 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 - popd + popd > /dev/null BUILT_UPDATE=true } diff --git a/docker_build.sh b/docker_build.sh index f80869e..38271b1 100755 --- a/docker_build.sh +++ b/docker_build.sh @@ -1,8 +1,18 @@ #!/bin/bash +GIT_SHA=$(git rev-parse --short HEAD) +GIT_TAG=$(git describe --tags --exact-match 2> /dev/null) + +if [ ! -z "$GIT_TAG" ]; then + __SC64_VERSION="git tag: $GIT_TAG" +else + __SC64_VERSION="git sha: $GIT_SHA" +fi + docker run \ --rm \ --user $(id -u):$(id -g) \ --mount type=bind,src="$(pwd)",target="/workdir" \ + -e __SC64_VERSION="$__SC64_VERSION" \ ghcr.io/polprzewodnikowy/sc64env:v1.2 \ ./build.sh $@ diff --git a/fw/SummerCart64.cof b/fw/SummerCart64.cof index e3d8f89..ebd1b9d 100644 --- a/fw/SummerCart64.cof +++ b/fw/SummerCart64.cof @@ -27,7 +27,7 @@ 0 0 2 - ../sw/n64/build/SummerLoader64.hex + ../sw/n64/build/n64boot.hex ../sw/riscv/build/governor.hex 305152 diff --git a/sw/n64/Makefile b/sw/n64/Makefile index 8b384cc..b7b497d 100644 --- a/sw/n64/Makefile +++ b/sw/n64/Makefile @@ -1,28 +1,56 @@ +TOOLCHAIN = mips64-elf- +CC = $(TOOLCHAIN)gcc +CXX = $(TOOLCHAIN)g++ +OBJCOPY = $(TOOLCHAIN)objcopy +OBJDUMP = $(TOOLCHAIN)objdump +SIZE = $(TOOLCHAIN)size + +FLAGS = -march=vr4300 -mtune=vr4300 -falign-functions=32 $(USER_FLAGS) +CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP +LDFLAGS = -lc -nostartfiles -Wl,--gc-sections + +SRC_DIR = src BUILD_DIR = build -SOURCE_DIR = src -PROGRAM_NAME = SummerLoader64 -include $(N64_INST)/include/n64.mk +SRC_FILES = startup.S main.c sc64.c boot.c crc32.c -src = main.c sc64.c boot.c crc32.c +SRCS = $(addprefix $(SRC_DIR)/, $(SRC_FILES)) +OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(patsubst %,%.o,$(SRCS)))) +DEPS = $(OBJS:.o=.d) -all: $(BUILD_DIR)/$(PROGRAM_NAME).hex +VPATH = $(SRC_DIR) -$(BUILD_DIR)/$(PROGRAM_NAME).elf: $(src:%.c=$(BUILD_DIR)/%.o) +$(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null)) -$(PROGRAM_NAME).z64: N64_ROM_TITLE="$(PROGRAM_NAME)" +$(BUILD_DIR)/%.S.o: %.S + $(CC) -x assembler-with-cpp $(FLAGS) $(CFLAGS) -c $< -o $@ -$(BUILD_DIR)/$(PROGRAM_NAME).hex: $(PROGRAM_NAME).z64 - sed '$$ s/\x00*$$//' $(PROGRAM_NAME).z64 > $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64 - @if [ $$(stat -L -c %s $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64) -gt 92160 ]; then\ - echo "\n Error: stripped file size is larger than 90kB thus cannot fit inside FPGA flash.\n"; exit 1;\ - fi - truncate --size=90k $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64 - $(N64_OBJCOPY) -I binary -O ihex $(BUILD_DIR)/$(PROGRAM_NAME)_stripped.z64 $(BUILD_DIR)/$(PROGRAM_NAME).hex +$(BUILD_DIR)/%.c.o: %.c + $(CC) $(FLAGS) $(CFLAGS) -c $< -o $@ + +$(BUILD_DIR)/n64boot.elf: $(OBJS) N64.ld + $(CXX) $(FLAGS) $(LDFLAGS) -TN64.ld $(OBJS) -o $@ + @$(OBJDUMP) -D $@ > $(BUILD_DIR)/n64boot.lst + +$(BUILD_DIR)/n64boot.bin: $(BUILD_DIR)/n64boot.elf + @$(OBJCOPY) -O binary $< $@ + @truncate --size=90k $@ + @chksum64 $@ > /dev/null + +$(BUILD_DIR)/n64boot.hex: $(BUILD_DIR)/n64boot.bin + @$(OBJCOPY) -I binary -O ihex $< $@ + +print_size: $(BUILD_DIR)/n64boot.elf + @echo 'Size of modules:' + @$(SIZE) -B -d -t --common $(OBJS) + @echo 'Size of n64boot:' + @$(SIZE) -B -d $< + +all: $(BUILD_DIR)/n64boot.hex print_size clean: - rm -rf ./$(BUILD_DIR) ./$(PROGRAM_NAME).z64 + @rm -rf ./$(BUILD_DIR)/* --include $(wildcard $(BUILD_DIR)/*.d) +.PHONY: all clean print_size -.PHONY: all clean +-include $(DEPS) diff --git a/sw/n64/N64.ld b/sw/n64/N64.ld new file mode 100644 index 0000000..056d014 --- /dev/null +++ b/sw/n64/N64.ld @@ -0,0 +1,47 @@ +MEMORY { + rdram (rwx) : org = 0x80300000, len = 1M + flash (r) : org = 0xB0000000, len = 90k +} + +ENTRY(entry_handler) + +SECTIONS { + .flash : { + KEEP(*(.text.bootcode)); + } > flash + + .text : { + *(.text.entry_handler) + *(.text .text.* .gnu.linkonce.t.*) + *(.rdata .rodata .rodata.* .gnu.linkonce.r.*) + } > rdram AT > flash + + .data : { + . = ALIGN(8); + _sdata = .; + *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN(8); + _ssdata = .; + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.lit8) + *(.lit4) + } > rdram AT > flash + + .bss : { + . = ALIGN(8); + _sbss = .; + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon .scommon.*) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(8); + _ebss = .; + } > rdram + + /DISCARD/ : { + *(.MIPS.*) + } + + _gp = MIN(_ssdata + 0x8000, MAX(_sdata + 0x8000, _ebss - 0x8000)); + _sp = ORIGIN(rdram) + LENGTH(rdram); +} diff --git a/sw/n64/blob/ipl3.bin b/sw/n64/blob/ipl3.bin new file mode 100644 index 0000000..a53352e Binary files /dev/null and b/sw/n64/blob/ipl3.bin differ diff --git a/sw/n64/src/startup.S b/sw/n64/src/startup.S new file mode 100644 index 0000000..448f85a --- /dev/null +++ b/sw/n64/src/startup.S @@ -0,0 +1,71 @@ +#define STR(x) #x +#define XSTR(s) STR(s) +#define VERSION XSTR(__SC64_VERSION) + +.section .text.bootcode +header_pi_config: + .word 0x80371240 + +header_clock_rate: + .word 0x0000000F + +header_load_addr: + .word entry_handler + +header_release_addr: + .word 0x00000000 + +header_crc: + .fill 2, 4, 0 + + .org 0x18, 0x00 + +header_text_info: + .ascii "byMFinPL" + .ascii "SummerLoader64 " + .ascii VERSION + + .org 0x40, 0x20 + +ipl3: + .incbin "blob/ipl3.bin" + + +.section .text.entry_handler +.set noreorder +entry_handler: + .global entry_handler + + li $a0, 0x08 + sw $a0, 0xBFC007FC + + la $gp, _gp + la $sp, _sp + +init_bss: + la $a0, _sbss + la $a1, _ebss + bge $a0, $a1, 2f + nop +1: + sd $zero, 0($a0) + addi $a0, $a0, 8 + blt $a0, $a1, 1b + nop +2: + +init_bss_cache: + la $a0, _sbss + la $a1, _ebss + bge $a0, $a1, 2f + nop +1: + cache 0x15, 0($a0) + addi $a0, $a0, 16 + blt $a0, $a1, 1b + nop +2: + +run: + j main + nop diff --git a/sw/pc/sc64.py b/sw/pc/sc64.py index fbe8498..021637d 100644 --- a/sw/pc/sc64.py +++ b/sw/pc/sc64.py @@ -442,7 +442,7 @@ if __name__ == "__main__": print(f"Setting CIC seed to [{hex(cic_seed) if cic_seed != 0xFFFF else 'Unknown'}]") sc64.set_cic_seed(cic_seed) - print(f"Setting 64DD emulation to [{'Enabled' if skip_bootloader else 'Disabled'}]") + print(f"Setting 64DD emulation to [{'Enabled' if dd_enable else 'Disabled'}]") sc64.set_dd_enable(dd_enable) if (rom_file): diff --git a/sw/riscv/Makefile b/sw/riscv/Makefile index c7a619c..1253a1b 100644 --- a/sw/riscv/Makefile +++ b/sw/riscv/Makefile @@ -1,5 +1,6 @@ TOOLCHAIN = riscv32-unknown-elf- CC = $(TOOLCHAIN)gcc +CXX = $(TOOLCHAIN)g++ OBJCOPY = $(TOOLCHAIN)objcopy OBJDUMP = $(TOOLCHAIN)objdump SIZE = $(TOOLCHAIN)size @@ -21,27 +22,33 @@ VPATH = $(SRC_DIR) $(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null)) -all: $(BUILD_DIR)/governor.hex +$(BUILD_DIR)/%.S.o: %.S + $(CC) -x assembler-with-cpp $(FLAGS) $(CFLAGS) -c $< -o $@ $(BUILD_DIR)/%.c.o: %.c $(CC) $(FLAGS) $(CFLAGS) -c $< -o $@ -$(BUILD_DIR)/%.S.o: %.S - $(CC) -x assembler $(FLAGS) $(CFLAGS) -c $< -o $@ +$(BUILD_DIR)/governor.elf: $(OBJS) SC64.ld + $(CXX) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -o $@ + @$(OBJDUMP) -D $@ > $(BUILD_DIR)/governor.lst -$(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 $@ +$(BUILD_DIR)/governor.bin: $(BUILD_DIR)/governor.elf + @$(OBJCOPY) -O binary $< $@ + +$(BUILD_DIR)/governor.hex: $(BUILD_DIR)/governor.bin + @$(OBJCOPY) -I binary -O ihex $< $@ + +print_size: $(BUILD_DIR)/governor.elf @echo 'Size of modules:' - @$(SIZE) -B -t --common $(OBJS) + @$(SIZE) -B -d -t --common $(OBJS) @echo 'Size of governor:' - @$(SIZE) -B $(BUILD_DIR)/governor.elf + @$(SIZE) -B -d $< + +all: $(BUILD_DIR)/governor.hex print_size clean: - rm -rf ./$(BUILD_DIR)/* + @rm -rf ./$(BUILD_DIR)/* -.PHONY: all clean +.PHONY: all clean print_size -include $(DEPS) diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld index 30e29bd..2e8471e 100644 --- a/sw/riscv/SC64.ld +++ b/sw/riscv/SC64.ld @@ -15,7 +15,7 @@ SECTIONS { . = ALIGN(4); _stext = .; *(.text .text.* .gnu.linkonce.t.*) - *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rdata .rodata .rodata.* .gnu.linkonce.r.*) . = ALIGN(4); _etext = .; } > ram AT > rom @@ -37,7 +37,7 @@ SECTIONS { . = ALIGN(4); _sbss = .; *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) + *(.scommon .scommon.*) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) . = ALIGN(4); diff --git a/sw/riscv/src/startup.S b/sw/riscv/src/startup.S index 0eb3670..b7dd186 100644 --- a/sw/riscv/src/startup.S +++ b/sw/riscv/src/startup.S @@ -1,5 +1,8 @@ -.section .text.reset_handler +#define STR(x) #x +#define XSTR(s) STR(s) +#define VERSION XSTR(__SC64_VERSION) +.section .text.reset_handler reset_handler: .global reset_handler @@ -10,6 +13,17 @@ reset_handler: la sp, __stack_pointer$ + j init_text + + .org 0x18, 0x00 + +header_text_info: + .ascii "byMFinPL" + .ascii "SummerGovernor64" + .ascii VERSION + + .org 0x40, 0x20 + init_text: la a0, _sitext la a1, _stext