From 5671e20c3f0f9f985bd0063c1660d95b01018abf Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Wed, 1 Sep 2021 17:21:41 +0200 Subject: [PATCH] huge cleanup --- build_pcb.sh | 41 -- build_release.sh | 59 --- fw/SummerCart64.qsf | 6 +- fw/cpu/bootloader/Makefile | 36 -- fw/cpu/bootloader/main.c | 40 -- fw/cpu/bootloader/prv32_rx.ld | 16 - fw/cpu/bootloader/sys.h | 35 -- fw/cpu/controller/Makefile | 36 -- fw/cpu/controller/bin2rom.py | 25 -- fw/cpu/controller/init.c | 17 - fw/cpu/controller/init.h | 8 - fw/cpu/controller/main.c | 9 - fw/cpu/controller/process.c | 350 ------------------ fw/cpu/controller/process.h | 8 - fw/cpu/controller/prv32_rwx.ld | 27 -- fw/cpu/controller/rtc.c | 128 ------- fw/cpu/controller/rtc.h | 23 -- fw/rtl/cpu/cpu_bootloader.sv | 34 +- fw/rtl/cpu/cpu_cfg.sv | 18 +- fw/rtl/intel/flash/intel_flash.qsys | 4 +- fw/rtl/n64/n64_cfg.sv | 8 +- fw/rtl/n64/n64_flashram.sv | 11 +- fw/rtl/system/config.sv | 6 + sw/{bootloader => n64}/.gitignore | 0 sw/{bootloader => n64}/Makefile | 0 sw/{bootloader => n64}/build.sh | 0 sw/{bootloader => n64}/src/boot/boot.c | 0 sw/{bootloader => n64}/src/boot/boot.h | 0 sw/{bootloader => n64}/src/boot/crc32.c | 0 sw/{bootloader => n64}/src/boot/crc32.h | 0 sw/{bootloader => n64}/src/boot/n64_regs.h | 0 sw/{bootloader => n64}/src/main.c | 0 sw/{bootloader => n64}/src/platform.h | 0 sw/{bootloader => n64}/src/sc64.c | 2 +- sw/{bootloader => n64}/src/sc64.h | 0 sw/{dumpy => pc}/.gitignore | 0 sw/{dumpy => pc}/dum.py | 20 +- sw/riscv/.gitignore | 1 + sw/riscv/Makefile | 50 +++ sw/riscv/SC64.ld | 52 +++ sw/riscv/src/controller.c | 248 +++++++++++++ sw/riscv/src/driver.c | 257 +++++++++++++ sw/riscv/src/driver.h | 95 +++++ sw/riscv/src/handlers.c | 51 +++ {fw/cpu/controller => sw/riscv/src}/sys.h | 6 +- sw/riscv/tools/bin2rom.py | 22 ++ .../bootloader => sw/riscv/tools}/bin2sv.py | 10 +- .../riscv/tools}/cpu_bootloader_template.sv | 0 48 files changed, 850 insertions(+), 909 deletions(-) delete mode 100644 build_pcb.sh delete mode 100755 build_release.sh delete mode 100644 fw/cpu/bootloader/Makefile delete mode 100644 fw/cpu/bootloader/main.c delete mode 100644 fw/cpu/bootloader/prv32_rx.ld delete mode 100644 fw/cpu/bootloader/sys.h delete mode 100644 fw/cpu/controller/Makefile delete mode 100644 fw/cpu/controller/bin2rom.py delete mode 100644 fw/cpu/controller/init.c delete mode 100644 fw/cpu/controller/init.h delete mode 100644 fw/cpu/controller/main.c delete mode 100644 fw/cpu/controller/process.c delete mode 100644 fw/cpu/controller/process.h delete mode 100644 fw/cpu/controller/prv32_rwx.ld delete mode 100644 fw/cpu/controller/rtc.c delete mode 100644 fw/cpu/controller/rtc.h rename sw/{bootloader => n64}/.gitignore (100%) rename sw/{bootloader => n64}/Makefile (100%) rename sw/{bootloader => n64}/build.sh (100%) mode change 100755 => 100644 rename sw/{bootloader => n64}/src/boot/boot.c (100%) rename sw/{bootloader => n64}/src/boot/boot.h (100%) rename sw/{bootloader => n64}/src/boot/crc32.c (100%) rename sw/{bootloader => n64}/src/boot/crc32.h (100%) rename sw/{bootloader => n64}/src/boot/n64_regs.h (100%) rename sw/{bootloader => n64}/src/main.c (100%) rename sw/{bootloader => n64}/src/platform.h (100%) rename sw/{bootloader => n64}/src/sc64.c (93%) rename sw/{bootloader => n64}/src/sc64.h (100%) rename sw/{dumpy => pc}/.gitignore (100%) rename sw/{dumpy => pc}/dum.py (79%) create mode 100644 sw/riscv/.gitignore create mode 100644 sw/riscv/Makefile create mode 100644 sw/riscv/SC64.ld create mode 100644 sw/riscv/src/controller.c create mode 100644 sw/riscv/src/driver.c create mode 100644 sw/riscv/src/driver.h create mode 100644 sw/riscv/src/handlers.c rename {fw/cpu/controller => sw/riscv/src}/sys.h (92%) create mode 100644 sw/riscv/tools/bin2rom.py rename {fw/cpu/bootloader => sw/riscv/tools}/bin2sv.py (70%) rename {fw/cpu/bootloader => sw/riscv/tools}/cpu_bootloader_template.sv (100%) diff --git a/build_pcb.sh b/build_pcb.sh deleted file mode 100644 index d10b180..0000000 --- a/build_pcb.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -PACKAGES_FOLDER_NAME="packages" -PACKAGE_FILE_NAME="SummerCart64_PCB" -FILES=( - "./hw/v1/CAMOutputs" - # Manually created files - "./hw/v1/SummerCart64_sch.pdf" - "./hw/v1/SummerCart64_brd_top.pdf" - "./hw/v1/SummerCart64_brd_bot.pdf" - "./hw/v1/SummerCart64_brd_place_top.pdf" -) - - -# Add version to zip file name if provided -if [[ $1 ]]; then - PACKAGE_FILE_NAME="${PACKAGE_FILE_NAME}-${1}" -fi - - -# Generate Gerbers -pushd hw/v1 -if [[ -e CAMOutputs ]]; then - rm -rf CAMOutputs -fi -echo "Generating Gerbers" -eaglecon.exe -X -dCAMJOB -jSummerCart64.cam SummerCart64.brd -popd - - -# Create packages directory -echo "Creating ${PACKAGES_FOLDER_NAME} directory" -mkdir -p "${PACKAGES_FOLDER_NAME}" - - -# ZIP files for release -echo "Zipping PCB files" -if [[ -e "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ]]; then - rm -f "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" -fi -zip -r "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ${FILES[@]} diff --git a/build_release.sh b/build_release.sh deleted file mode 100755 index e02212f..0000000 --- a/build_release.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -PACKAGES_FOLDER_NAME="packages" -PACKAGE_FILE_NAME="SummerCart64" -FILES=( - "./fw/output_files/SummerCart64.pof" - "./hw/v1/ftdi-template.xml" - "./sw/cic/UltraCIC-III.hex" - "./sw/cic/UltraCIC-III.eep.hex" -) - - -# Add version to zip file name if provided -if [[ $1 ]]; then - PACKAGE_FILE_NAME="${PACKAGE_FILE_NAME}-${1}" -fi - - -# Build libsc64 -echo "Building libsc64" -pushd sw/libsc64 -./build.sh -popd - - -# Build bootloader -echo "Building bootloader" -pushd sw/bootloader -./build.sh -popd - - -# Cleanup docker space -docker image prune -a -f - - -# Build UltraCIC-III -pushd sw/cic -echo "Building UltraCIC-III" -avra UltraCIC-III.asm -D attiny45 -popd - - -# Build FPGA firmware -echo "Building FPGA firmware" -docker run -t --mount type=bind,src="$(pwd)",target="/build" chriz2600/quartus-lite:20.1.0 /usr/local/bin/quartus_wrapper quartus_sh --flow compile /build/fw/SummerCart64.qpf - - -# Create packages directory -echo "Creating ${PACKAGES_FOLDER_NAME} directory" -mkdir -p "${PACKAGES_FOLDER_NAME}" - - -# ZIP files for release -echo "Zipping files" -if [[ -e "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ]]; then - rm -f "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" -fi -zip -r "${PACKAGES_FOLDER_NAME}/${PACKAGE_FILE_NAME}.zip" ${FILES[@]} diff --git a/fw/SummerCart64.qsf b/fw/SummerCart64.qsf index b234d2a..3cf5236 100644 --- a/fw/SummerCart64.qsf +++ b/fw/SummerCart64.qsf @@ -83,7 +83,6 @@ 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 SIGNALTAP_FILE output_files/signaltap.stp -set_global_assignment -name SLD_FILE db/signaltap_auto_stripped.stp # Pin & Location Assignments # ========================== @@ -302,7 +301,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top - set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top # end DESIGN_PARTITION(Top) # ------------------------- @@ -326,4 +324,6 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - # ======================== # end ENTITY(intel_gpio_ddro) -# --------------------------- \ No newline at end of file +# --------------------------- +set_global_assignment -name SLD_FILE db/signaltap_auto_stripped.stp +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/fw/cpu/bootloader/Makefile b/fw/cpu/bootloader/Makefile deleted file mode 100644 index 6bda14f..0000000 --- a/fw/cpu/bootloader/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -CROSS=riscv64-unknown-elf- -FLAGS=\ - -mabi=ilp32 \ - -march=rv32i \ - -std=c11 \ - -Os \ - -Wall \ - -Wstrict-prototypes \ - -fverbose-asm \ - -ffunction-sections \ - -fdata-sections \ - -Tprv32_rx.ld \ - -Wl,--gc-sections \ - -ffreestanding \ - -nostartfiles \ - -nostdlib - -all: bootloader.bin cpu_bootloader.sv print_size - -bootloader.elf: prv32_rx.ld main.c - @$(CROSS)gcc $(FLAGS) main.c -o bootloader.elf - -bootloader.bin: bootloader.elf - @$(CROSS)objcopy -O binary bootloader.elf bootloader.bin - -cpu_bootloader.sv: bootloader.bin - @python3 bin2sv.py bootloader.bin cpu_bootloader_template.sv ../../rtl/cpu/cpu_bootloader.sv - -print_size: - @echo 'Size of target .elf file:' - $(CROSS)size -B bootloader.elf - -clean: - @rm -f bootloader.bin bootloader.elf - -.PHONY: clean diff --git a/fw/cpu/bootloader/main.c b/fw/cpu/bootloader/main.c deleted file mode 100644 index 928dabb..0000000 --- a/fw/cpu/bootloader/main.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "sys.h" - -int reset_handler (void) { -#ifdef BOOT_UART - io8_t pointer = &RAM; -#else -#ifdef BOOT_N64 - io32_t pointer = &RAM; -#endif -#endif - uint32_t length = 0; - -#ifdef BOOT_UART - for (int i = 0; i < 4; i++) { - while (!(UART_SR & UART_SR_RXNE)); - length |= (UART_DR << (i * 8)); - } -#else -#ifdef BOOT_N64 - while (!(CFG_SCR & CFG_SCR_BOOTSTRAP_PENDING)); - length = CFG_BOOTSTRAP; -#endif -#endif - - while (1) { -#ifdef BOOT_UART - while (!(UART_SR & UART_SR_RXNE)); - *pointer++ = UART_DR; -#else -#ifdef BOOT_N64 - while (!(CFG_SCR & CFG_SCR_BOOTSTRAP_PENDING)); - *pointer++ = CFG_BOOTSTRAP; -#endif -#endif - if (((uint32_t) pointer) == length) { - CFG_SCR |= CFG_SCR_CPU_BOOTSTRAPPED; - __asm__("call 0"); - } - } -} diff --git a/fw/cpu/bootloader/prv32_rx.ld b/fw/cpu/bootloader/prv32_rx.ld deleted file mode 100644 index b441721..0000000 --- a/fw/cpu/bootloader/prv32_rx.ld +++ /dev/null @@ -1,16 +0,0 @@ -MEMORY -{ - rom (rx) : org = 0x10000000, len = 128 -} - -ENTRY(reset_handler) - -SECTIONS -{ - .rom : - { - . = ALIGN(4); - *(.text .text* .rodata .rodata* .srodata .srodata*) - . = ALIGN(4); - } > rom AT > rom -} diff --git a/fw/cpu/bootloader/sys.h b/fw/cpu/bootloader/sys.h deleted file mode 100644 index e36985a..0000000 --- a/fw/cpu/bootloader/sys.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef BTLDR_H__ -#define BTLDR_H__ - - -#include - - -#define BOOT_UART -// #define BOOT_N64 - -typedef volatile uint8_t * io8_t; -typedef volatile uint32_t * io32_t; - -#ifdef BOOT_UART -#define RAM (*((io8_t) 0x00000000)) -#else -#ifdef BOOT_N64 -#define RAM (*((io32_t) 0x00000000)) -#endif -#endif - -#define UART_SR (*((io8_t) 0x50000000)) -#define UART_DR (*((io8_t) 0x50000004)) - -#define UART_SR_RXNE (1 << 0) -#define UART_SR_TXE (1 << 1) - -#define CFG_SCR (*((io32_t) 0x70000000)) -#define CFG_BOOTSTRAP (*((io32_t) 0x7000001C)) - -#define CFG_SCR_CPU_BOOTSTRAPPED (1 << 31) -#define CFG_SCR_BOOTSTRAP_PENDING (1 << 29) - - -#endif diff --git a/fw/cpu/controller/Makefile b/fw/cpu/controller/Makefile deleted file mode 100644 index 3224c0a..0000000 --- a/fw/cpu/controller/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -CROSS=riscv64-unknown-elf- -FLAGS=\ - -mabi=ilp32 \ - -march=rv32i \ - -std=c11 \ - -Os \ - -Wall \ - -Wstrict-prototypes \ - -fverbose-asm \ - -ffunction-sections \ - -fdata-sections \ - -Tprv32_rwx.ld \ - -Wl,--gc-sections \ - -ffreestanding \ - -nostartfiles \ - -nostdlib - -all: controller.bin print_size - -controller.elf: prv32_rwx.ld main.c init.c process.c - @$(CROSS)gcc $(FLAGS) main.c init.c process.c -o controller.elf - -controller.bin: controller.elf - @$(CROSS)objcopy -O binary controller.elf tmp.bin - @python3 bin2rom.py tmp.bin controller.bin - @rm -f tmp.bin - -print_size: - @echo 'Size of target .elf file:' - @$(CROSS)size -B controller.elf - @echo $(shell $(CROSS)size -B controller.elf | awk 'NR==2 { printf "\nTotal memory used: %.2f%%\n",(100/(16*1024))*($$4) }') - -clean: - @rm -f controller.bin controller.elf - -.PHONY: clean diff --git a/fw/cpu/controller/bin2rom.py b/fw/cpu/controller/bin2rom.py deleted file mode 100644 index 2f496fe..0000000 --- a/fw/cpu/controller/bin2rom.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -import os -import sys - -binary = None -rom = None - -binary_name = sys.argv[1] or 'binary.bin' -rom_name = sys.argv[2] or 'rom.bin' - -try: - binary = open(binary_name, mode='rb') - rom = open(rom_name, mode='wb') - - length = os.path.getsize(binary_name) - rom.write(length.to_bytes(4, byteorder='little')) - rom.write(binary.read()) - -except Exception as e: - print(f'Unable to convert the rom: {e}', file=sys.stderr) - sys.exit(-1) - -finally: - if (binary): binary.close() - if (rom): rom.close() diff --git a/fw/cpu/controller/init.c b/fw/cpu/controller/init.c deleted file mode 100644 index c050b0e..0000000 --- a/fw/cpu/controller/init.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "sys.h" - - -void init (void) { - DMA->SCR = DMA_SCR_STOP; - USB->SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_TX; - - GPIO->ODR = 0; - GPIO->OER = (1 << 0); - - CFG->SCR = CFG_SCR_SDRAM_SWITCH; - CFG->DD_OFFSET = DEFAULT_DD_OFFSET; - CFG->SAVE_OFFSET = DEFAULT_SAVE_OFFSET; - - while (!(UART->SCR & UART_SCR_TXE)); - UART->DR = '$'; -} diff --git a/fw/cpu/controller/init.h b/fw/cpu/controller/init.h deleted file mode 100644 index 8979396..0000000 --- a/fw/cpu/controller/init.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef INIT_H__ -#define INIT_H__ - - -void init (void); - - -#endif diff --git a/fw/cpu/controller/main.c b/fw/cpu/controller/main.c deleted file mode 100644 index 94b0e5e..0000000 --- a/fw/cpu/controller/main.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "init.h" -#include "process.h" - - -__attribute__((naked)) void main (void) { - __asm__("la sp, __stack_pointer"); - init(); - process(); -} diff --git a/fw/cpu/controller/process.c b/fw/cpu/controller/process.c deleted file mode 100644 index 1958214..0000000 --- a/fw/cpu/controller/process.c +++ /dev/null @@ -1,350 +0,0 @@ -#include "sys.h" -#include "process.h" - -static const uint8_t cmd_token[3] = { 'C', 'M', 'D' }; -static const uint8_t cmp_token[3] = { 'C', 'M', 'P' }; -static const uint8_t err_token[3] = { 'E', 'R', 'R' }; - -static uint8_t save_type = 0; -static uint16_t cic_type = 0xFFFF; -static uint8_t tv_type = 0xFF; -static uint32_t *save_pointer = (uint32_t *) (SDRAM_BASE + DEFAULT_SAVE_OFFSET); - -void process_usb (void); -void process_cfg (void); -void process_dd (void); -void process_si (void); -void process_uart (void); -void process_rtc (void); -void process_flashram (void); -void cfg_set_save_type (uint8_t type); -void cfg_update_config (uint32_t *args); - -// void print (const char *text); -// void print_02hex (unsigned char number); - -void process (void) { - while (1) { - process_usb(); - process_cfg(); - process_dd(); - process_si(); - process_uart(); - process_rtc(); - process_flashram(); - } -} - -void process_usb (void) { - static int state = 0; - static uint8_t current_byte = 0; - static uint8_t cmd; - static uint32_t args[2]; - static uint8_t is_error; - static uint8_t dma_started; - - uint8_t data; - - switch (state) { - case 0: { - if (USB->SCR & USB_SCR_RXNE) { - data = USB->DR; - if (current_byte == 3) { - state = 1; - current_byte = 0; - cmd = data; - args[0] = 0; - args[1] = 0; - is_error = 0; - dma_started = 0; - break; - } - if (data != cmd_token[current_byte]) { - current_byte = 0; - break; - } - current_byte += 1; - } - break; - } - - case 1: { - if (USB->SCR & USB_SCR_RXNE) { - data = USB->DR; - uint32_t *p = args + (current_byte >= 4 ? 1 : 0); - *p = (*p << 8) | data; - current_byte += 1; - if (current_byte == 8) { - state = 2; - current_byte = 0; - break; - } - } - break; - } - - case 2: { - if (cmd == 'R' || cmd == 'W') { - if (!dma_started) { - if (!(DMA->SCR & DMA_SCR_BUSY)) { - DMA->MADDR = args[0]; - DMA->ID_LEN = args[1]; - DMA->SCR = (cmd == 'W' ? DMA_SCR_DIR : 0) | DMA_SCR_START; - dma_started = 1; - } - } else { - if (!(DMA->SCR & DMA_SCR_BUSY)) { - state = 3; - } - } - } else if (cmd == 'C') { - cfg_update_config(args); - state = 3; - } else if (cmd == 'Q') { - if (USB->SCR & USB_SCR_TXE) { - switch (current_byte) { - case 0: USB->DR = cic_type >> 8; break; - case 1: USB->DR = cic_type; break; - case 2: USB->DR = ((tv_type & 0x3) << 4) | (save_type & 0x7); break; - case 3: USB->DR = CFG->SCR; break; - case 4: USB->DR = (CFG->SAVE_OFFSET >> 24); break; - case 5: USB->DR = (CFG->SAVE_OFFSET >> 16); break; - case 6: USB->DR = (CFG->SAVE_OFFSET >> 8); break; - case 7: USB->DR = (CFG->SAVE_OFFSET >> 0); break; - case 8: USB->DR = (CFG->DD_OFFSET >> 24); break; - case 9: USB->DR = (CFG->DD_OFFSET >> 16); break; - case 10: USB->DR = (CFG->DD_OFFSET >> 8); break; - case 11: USB->DR = (CFG->DD_OFFSET >> 0); break; - } - current_byte += 1; - if (current_byte == 12) { - state = 3; - current_byte = 0; - } - } - } else { - state = 3; - is_error = 1; - } - break; - } - - case 3: { - if (USB->SCR & USB_SCR_TXE) { - const uint8_t *p = is_error ? err_token : cmp_token; - USB->DR = (current_byte < 3) ? p[current_byte] : cmd; - current_byte += 1; - if (current_byte == 4) { - state = 0; - current_byte = 0; - } - } - break; - } - - default: { - state = 0; - break; - } - } -} - -void process_cfg (void) { - static uint8_t state = 0; - static uint8_t cmd; - static uint32_t args[3]; - - switch (state) { - case 0: { - if (CFG->SCR & CFG_SCR_CPU_BUSY) { - state = 1; - cmd = CFG->CMD; - args[0] = CFG->DATA[0]; - args[1] = CFG->DATA[1]; - } - break; - } - - case 1: { - if (cmd == 'C') { - cfg_update_config(args); - CFG->DATA[0] = (save_type << 8) | (CFG->SCR & 0x07); - CFG->DATA[1] = (tv_type << 16) | cic_type; - state = 2; - } else { - CFG->DATA[0] = 0xFFFFFFFF; - CFG->DATA[1] = 0xFFFFFFFF; - state = 2; - } - break; - } - - case 2: { - CFG->SCR &= ~(CFG_SCR_CPU_BUSY); - state = 0; - break; - } - - default: { - state = 0; - break; - } - } -} - -void process_dd (void) { - -} - -void process_si (void) { - -} - -void process_uart (void) { - if (UART->SCR & UART_SCR_RXNE) { - uint8_t data = UART->DR; - if (data == '/') { - while (!(UART->SCR & UART_SCR_TXE)); - UART->DR = '>'; - void (*bootloader) (void) = (void *) &BOOTLOADER; - bootloader(); - } - } -} - -void process_rtc (void) { - -} - -void process_flashram (void) { - uint32_t scr = FLASHRAM->SCR; - volatile uint32_t *offset_pointer = save_pointer; - size_t length; - - if (scr & FLASHRAM_OPERATION_PENDING) { - if (scr & FLASHRAM_WRITE_OR_ERASE) { - if (scr & FLASHRAM_SECTOR_OR_ALL) { - length = 128 * 1024; - } else { - offset_pointer += 32 * (scr >> FLASHRAM_SECTOR_BIT); - length = 16 * 1024; - } - for (size_t i = 0; i < (length / 4); i++) { - offset_pointer[i] = 0xFFFFFFFF; - } - } else { - offset_pointer += 32 * (scr >> FLASHRAM_SECTOR_BIT); - for (size_t i = 0; i < 32; i++) { - offset_pointer[i] &= FLASHRAM->BUFFER[i]; - } - } - FLASHRAM->SCR = FLASHRAM_OPERATION_DONE; - } -} - -void cfg_update_config (uint32_t *args) { - switch (args[0]) { - case 0: { - if (args[1]) { - CFG->SCR |= CFG_SCR_SDRAM_SWITCH; - } else { - CFG->SCR &= ~CFG_SCR_SDRAM_SWITCH; - } - break; - } - case 1: { - if (args[1]) { - CFG->SCR |= CFG_SCR_SDRAM_WRITABLE; - } else { - CFG->SCR &= ~CFG_SCR_SDRAM_WRITABLE; - } - break; - } - case 2: { - if (args[1]) { - CFG->SCR |= CFG_SCR_DD_EN; - } else { - CFG->SCR &= ~CFG_SCR_DD_EN; - } - break; - } - case 3: { - cfg_set_save_type(args[1] & 0xFF); - break; - } - case 4: { - cic_type = args[1] & 0xFFFF; - break; - } - case 5: { - tv_type = args[1] & 0xFF; - break; - } - } -} - -void cfg_set_save_type (uint8_t type) { - CFG->SCR &= ~(CFG_SCR_FLASHRAM_EN | CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN); - uint32_t save_offset = DEFAULT_SAVE_OFFSET; - - switch (type) { - case 0: { - break; - } - case 1: { - save_offset = SDRAM_SIZE - 512; - break; - } - case 2: { - save_offset = SDRAM_SIZE - 2048; - break; - } - case 3: { - save_offset = SDRAM_SIZE - (32 * 1024); - CFG->SCR |= CFG_SCR_SRAM_EN; - break; - } - case 4: { - save_offset = SDRAM_SIZE - (256 * 1024); - CFG->SCR |= CFG_SCR_FLASHRAM_EN; - break; - } - case 5: { - save_offset = SDRAM_SIZE - (3 * 32 * 1024); - CFG->SCR |= CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN; - break; - } - case 6: { - save_offset = 0x01608000; - CFG->SCR |= CFG_SCR_FLASHRAM_EN; - break; - } - default: { - return; - } - } - - save_pointer = (uint32_t *) (SDRAM_BASE + save_offset); - save_type = type; - - CFG->SAVE_OFFSET = save_offset; -} - -// void print (const char *text) { -// while (*text != '\0') { -// while (!(UART->SCR & UART_SCR_TXE)); -// UART->DR = *text++; -// } -// } - -// const char hex_char_map[16] = { -// '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -// }; - -// void print_02hex (unsigned char number) { -// char buffer[3]; -// buffer[0] = hex_char_map[number >> 4]; -// buffer[1] = hex_char_map[number & 0x0F]; -// buffer[2] = '\0'; -// print(buffer); -// } diff --git a/fw/cpu/controller/process.h b/fw/cpu/controller/process.h deleted file mode 100644 index 822b73e..0000000 --- a/fw/cpu/controller/process.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PROCESS_H__ -#define PROCESS_H__ - - -void process (void); - - -#endif diff --git a/fw/cpu/controller/prv32_rwx.ld b/fw/cpu/controller/prv32_rwx.ld deleted file mode 100644 index df0e65c..0000000 --- a/fw/cpu/controller/prv32_rwx.ld +++ /dev/null @@ -1,27 +0,0 @@ -MEMORY -{ - ram (rwx) : org = 0x00000000, len = 16k - bootloader (rx) : org = 0x10000000, len = 128 - sdram (rwx) : org = 0x80000000, len = 64M -} - -__ram_size = LENGTH(ram); -__stack_pointer = ORIGIN(ram) + LENGTH(ram) - 4; - -ENTRY(main) - -SECTIONS -{ - .ram : - { - . = ALIGN(4); - *(.text.main); - . = ALIGN(4); - *(.text .text* .rodata .rodata* .srodata .srodata*); - . = ALIGN(4); - *(.data .data.* .sdata .sdata.*); - . = ALIGN(4); - *(.bss .bss.* .sbss .sbss.*); - . = ALIGN(4); - } > ram AT > ram -} diff --git a/fw/cpu/controller/rtc.c b/fw/cpu/controller/rtc.c deleted file mode 100644 index 8157715..0000000 --- a/fw/cpu/controller/rtc.c +++ /dev/null @@ -1,128 +0,0 @@ -#include "sys.h" -#include "rtc.h" - - -static const uint8_t rtc_bit_mask[7] = { - 0b01111111, - 0b01111111, - 0b00111111, - 0b00000111, - 0b00111111, - 0b00011111, - 0b11111111 -}; - - -static uint8_t i2c_is_busy (void) { - return (I2C_SCR & I2C_SCR_BUSY); -} - -static void i2c_wait_busy (void) { - while (i2c_is_busy()); -} - -static uint8_t i2c_has_ack (void) { - return (I2C_SCR & I2C_SCR_ACK); -} - -static void i2c_start (void) { - i2c_wait_busy(); - I2C_SCR = I2C_SCR_START; -} - -static void i2c_stop (void) { - i2c_wait_busy(); - I2C_SCR = I2C_SCR_STOP; -} - -static uint8_t i2c_write (uint8_t data) { - i2c_wait_busy(); - I2C_SCR = 0; - I2C_DR = data; - i2c_wait_busy(); - return i2c_has_ack(); -} - -static void i2c_read (uint8_t *data, uint8_t cfg) { - i2c_wait_busy(); - I2C_SCR = cfg; - I2C_DR = 0xFF; - i2c_wait_busy(); - *data = I2C_DR; -} - -static uint8_t i2c_tx (uint8_t address, uint8_t *data, size_t length) { - uint8_t result = 0; - - i2c_start(); - result |= i2c_write(RTC_ADDR); - result |= i2c_write(address); - for (size_t i = 0; i < length; i++) { - result |= i2c_write(*data++); - } - i2c_stop(); - - return result; -} - -static uint8_t i2c_rx (uint8_t address, uint8_t *data, size_t length) { - uint8_t result = 0; - - i2c_start(); - result |= i2c_write(RTC_ADDR); - result |= i2c_write(address); - i2c_start(); - result |= i2c_write(RTC_ADDR | I2C_ADDR_READ); - for (size_t i = 0; i < length; i++) { - i2c_read(data++, (i == (length - 1)) ? 0 : I2C_SCR_MACK); - } - i2c_stop(); - - return result; -} - -static void rtc_sanitize_data (uint8_t *rtc_data) { - for (int i = 0; i < 7; i++) { - rtc_data[i] &= rtc_bit_mask[i]; - } -} - -uint8_t rtc_set_time (uint8_t *rtc_data) { - uint8_t result = 0; - uint8_t tmp; - - rtc_sanitize_data(rtc_data); - - rtc_data[RTC_RTCSEC] |= RTC_RTCSEC_ST; - rtc_data[RTC_RTCWKDAY] |= RTC_RTCWKDAY_VBAT; - - result |= i2c_tx(RTC_RTCSEC, 0x00, 1); - result |= i2c_tx(RTC_RTCMIN, rtc_data + 1, 6); - result |= i2c_tx(RTC_RTCSEC, rtc_data, 1); - - do { - result |= i2c_rx(RTC_RTCWKDAY, &tmp, 7); - } while ((!(tmp & RTC_RTCWKDAY_OSCRUN)) || !result); - - return result; -} - -uint8_t rtc_get_time (uint8_t *rtc_data) { - uint8_t result = i2c_rx(RTC_RTCSEC, rtc_data, 7); - - rtc_sanitize_data(rtc_data); - - return result; -} - -void rtc_init (void) { - uint8_t result; - uint8_t rtc_data[7]; - - result = i2c_rx(RTC_RTCSEC, rtc_data, 1); - - if ((!(rtc_data[0] & RTC_RTCSEC_ST)) && (!result)) { - rtc_get_time(rtc_data); - rtc_set_time(rtc_data); - } -} diff --git a/fw/cpu/controller/rtc.h b/fw/cpu/controller/rtc.h deleted file mode 100644 index c56f1dc..0000000 --- a/fw/cpu/controller/rtc.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef RTC_H__ -#define RTC_H__ - - -#include "sys.h" - - -#define RTC_ADDR (0xDE) - -#define RTC_RTCSEC (0x00) -#define RTC_RTCSEC_ST (1 << 7) -#define RTC_RTCMIN (0x01) -#define RTC_RTCWKDAY (0x03) -#define RTC_RTCWKDAY_OSCRUN (1 << 5) -#define RTC_RTCWKDAY_VBAT (1 << 3) - - -uint8_t rtc_set_time (uint8_t *rtc_data); -uint8_t rtc_get_time (uint8_t *rtc_data); -void rtc_init (void); - - -#endif diff --git a/fw/rtl/cpu/cpu_bootloader.sv b/fw/rtl/cpu/cpu_bootloader.sv index 33c7d59..8700cbd 100644 --- a/fw/rtl/cpu/cpu_bootloader.sv +++ b/fw/rtl/cpu/cpu_bootloader.sv @@ -18,7 +18,7 @@ module cpu_bootloader ( 1: bus.rdata = 32'h00000713; 2: bus.rdata = 32'h50000637; 3: bus.rdata = 32'h02000593; - 4: bus.rdata = 32'h00064683; + 4: bus.rdata = 32'h00062683; 5: bus.rdata = 32'h0016f693; 6: bus.rdata = 32'hfe068ce3; 7: bus.rdata = 32'h00464683; @@ -27,24 +27,20 @@ module cpu_bootloader ( 10: bus.rdata = 32'h00d76733; 11: bus.rdata = 32'hfeb792e3; 12: bus.rdata = 32'h00000793; - 13: bus.rdata = 32'h50000537; - 14: bus.rdata = 32'h70000637; - 15: bus.rdata = 32'h80000837; - 16: bus.rdata = 32'h00054683; - 17: bus.rdata = 32'h0016f693; - 18: bus.rdata = 32'hfe068ce3; - 19: bus.rdata = 32'h00454683; - 20: bus.rdata = 32'h00178593; - 21: bus.rdata = 32'h0ff6f693; - 22: bus.rdata = 32'h00d78023; - 23: bus.rdata = 32'h00e59c63; - 24: bus.rdata = 32'h00062783; - 25: bus.rdata = 32'h0107e7b3; - 26: bus.rdata = 32'h00f62023; - 27: bus.rdata = 32'hf0000097; - 28: bus.rdata = 32'hf94080e7; - 29: bus.rdata = 32'h00058793; - 30: bus.rdata = 32'hfc9ff06f; + 13: bus.rdata = 32'h500005b7; + 14: bus.rdata = 32'h0005a683; + 15: bus.rdata = 32'h0016f693; + 16: bus.rdata = 32'hfe068ce3; + 17: bus.rdata = 32'h0045c683; + 18: bus.rdata = 32'h00178613; + 19: bus.rdata = 32'h0ff6f693; + 20: bus.rdata = 32'h00d78023; + 21: bus.rdata = 32'h00e61863; + 22: bus.rdata = 32'hf0000297; + 23: bus.rdata = 32'hfa828293; + 24: bus.rdata = 32'h00028067; + 25: bus.rdata = 32'h00060793; + 26: bus.rdata = 32'hfd1ff06f; default: bus.rdata = 32'd0; endcase end diff --git a/fw/rtl/cpu/cpu_cfg.sv b/fw/rtl/cpu/cpu_cfg.sv index 6668dd0..55d3485 100644 --- a/fw/rtl/cpu/cpu_cfg.sv +++ b/fw/rtl/cpu/cpu_cfg.sv @@ -10,7 +10,8 @@ module cpu_cfg ( R_SAVE_OFFSET, R_COMMAND, R_DATA_0, - R_DATA_1 + R_DATA_1, + R_VERSION } e_reg_id; always_ff @(posedge sys.clk) begin @@ -27,7 +28,9 @@ module cpu_cfg ( R_SCR: bus.rdata = { cfg.cpu_ready, cfg.cpu_busy, - 24'd0, + cfg.usb_waiting, + cfg.cmd_error, + 22'd0, cfg.flashram_enabled, cfg.sram_banked, cfg.sram_enabled, @@ -40,6 +43,7 @@ module cpu_cfg ( R_COMMAND: bus.rdata = {24'd0, cfg.cmd}; R_DATA_0: bus.rdata = cfg.data[0]; R_DATA_1: bus.rdata = cfg.data[1]; + R_VERSION: bus.rdata = sc64::SC64_VER; default: bus.rdata = 32'd0; endcase end @@ -58,6 +62,8 @@ module cpu_cfg ( if (sys.reset) begin cfg.cpu_ready <= 1'b0; cfg.cpu_busy <= 1'b0; + cfg.usb_waiting <= 1'b0; + cfg.cmd_error <= 1'b0; cfg.sdram_switch <= 1'b0; cfg.sdram_writable <= 1'b0; cfg.dd_enabled <= 1'b0; @@ -78,8 +84,12 @@ module cpu_cfg ( case (bus.address[4:2]) R_SCR: begin if (bus.wmask[3]) begin - cfg.cpu_ready <= bus.wdata[31]; - cfg.cpu_busy <= bus.wdata[30]; + { + cfg.cpu_ready, + cfg.cpu_busy, + cfg.usb_waiting, + cfg.cmd_error + } <= bus.wdata[31:28]; end if (bus.wmask[0]) begin { diff --git a/fw/rtl/intel/flash/intel_flash.qsys b/fw/rtl/intel/flash/intel_flash.qsys index 2d52889..17afbc8 100644 --- a/fw/rtl/intel/flash/intel_flash.qsys +++ b/fw/rtl/intel/flash/intel_flash.qsys @@ -71,8 +71,8 @@ Read only,Read only,Hidden,Read only,Read only $${FILENAME}_onchip_flash_0 - ../sw/bootloader/build/SummerLoader64.hex - ../sw/bootloader/build/SummerLoader64.hex + ../sw/n64/bootloader/build/SummerLoader64.hex + ../sw/n64/bootloader/build/SummerLoader64.hex diff --git a/fw/rtl/n64/n64_cfg.sv b/fw/rtl/n64/n64_cfg.sv index 08bf8be..49d6023 100644 --- a/fw/rtl/n64/n64_cfg.sv +++ b/fw/rtl/n64/n64_cfg.sv @@ -26,7 +26,13 @@ module n64_cfg ( bus.rdata = 16'd0; if (bus.ack) begin case (bus.address[3:1]) - R_SR: bus.rdata = {cfg.cpu_ready, cfg.cpu_busy, 14'd0}; + R_SR: bus.rdata = { + cfg.cpu_ready, + cfg.cpu_busy, + cfg.usb_waiting, + cfg.cmd_error, + 12'd0 + }; R_COMMAND: bus.rdata = {8'd0, cfg.cmd}; R_DATA_0_H: bus.rdata = cfg.data[0][31:16]; R_DATA_0_L: bus.rdata = cfg.data[0][15:0]; diff --git a/fw/rtl/n64/n64_flashram.sv b/fw/rtl/n64/n64_flashram.sv index 8f13e36..dc76434 100644 --- a/fw/rtl/n64/n64_flashram.sv +++ b/fw/rtl/n64/n64_flashram.sv @@ -169,12 +169,13 @@ module n64_flashram ( end endcase end - end else begin - if (flashram_state == FS_STATUS) begin - flashram_status[B_ERASE_DONE] <= bus.wdata[B_ERASE_DONE]; - flashram_status[B_WRITE_DONE] <= bus.wdata[B_WRITE_DONE]; - end end + // else begin + // if (bus.address[1] && flashram_state == FS_STATUS) begin + // flashram_status[B_ERASE_DONE] <= bus.wdata[B_ERASE_DONE]; + // flashram_status[B_WRITE_DONE] <= bus.wdata[B_WRITE_DONE]; + // end + // end end end end diff --git a/fw/rtl/system/config.sv b/fw/rtl/system/config.sv index f89f49c..fa4b8e3 100644 --- a/fw/rtl/system/config.sv +++ b/fw/rtl/system/config.sv @@ -2,6 +2,8 @@ interface if_config (); logic cpu_ready; logic cpu_busy; + logic usb_waiting; + logic cmd_error; logic cmd_request; logic [7:0] cmd; logic [31:0] data [0:1]; @@ -36,6 +38,8 @@ interface if_config (); modport n64 ( input cpu_ready, input cpu_busy, + input usb_waiting, + input cmd_error, output cmd_request, output cmd, output data, @@ -46,6 +50,8 @@ interface if_config (); modport cpu ( output cpu_ready, output cpu_busy, + output usb_waiting, + output cmd_error, input cmd_request, input cmd, input data, diff --git a/sw/bootloader/.gitignore b/sw/n64/.gitignore similarity index 100% rename from sw/bootloader/.gitignore rename to sw/n64/.gitignore diff --git a/sw/bootloader/Makefile b/sw/n64/Makefile similarity index 100% rename from sw/bootloader/Makefile rename to sw/n64/Makefile diff --git a/sw/bootloader/build.sh b/sw/n64/build.sh old mode 100755 new mode 100644 similarity index 100% rename from sw/bootloader/build.sh rename to sw/n64/build.sh diff --git a/sw/bootloader/src/boot/boot.c b/sw/n64/src/boot/boot.c similarity index 100% rename from sw/bootloader/src/boot/boot.c rename to sw/n64/src/boot/boot.c diff --git a/sw/bootloader/src/boot/boot.h b/sw/n64/src/boot/boot.h similarity index 100% rename from sw/bootloader/src/boot/boot.h rename to sw/n64/src/boot/boot.h diff --git a/sw/bootloader/src/boot/crc32.c b/sw/n64/src/boot/crc32.c similarity index 100% rename from sw/bootloader/src/boot/crc32.c rename to sw/n64/src/boot/crc32.c diff --git a/sw/bootloader/src/boot/crc32.h b/sw/n64/src/boot/crc32.h similarity index 100% rename from sw/bootloader/src/boot/crc32.h rename to sw/n64/src/boot/crc32.h diff --git a/sw/bootloader/src/boot/n64_regs.h b/sw/n64/src/boot/n64_regs.h similarity index 100% rename from sw/bootloader/src/boot/n64_regs.h rename to sw/n64/src/boot/n64_regs.h diff --git a/sw/bootloader/src/main.c b/sw/n64/src/main.c similarity index 100% rename from sw/bootloader/src/main.c rename to sw/n64/src/main.c diff --git a/sw/bootloader/src/platform.h b/sw/n64/src/platform.h similarity index 100% rename from sw/bootloader/src/platform.h rename to sw/n64/src/platform.h diff --git a/sw/bootloader/src/sc64.c b/sw/n64/src/sc64.c similarity index 93% rename from sw/bootloader/src/sc64.c rename to sw/n64/src/sc64.c index e552634..35f7ba2 100644 --- a/sw/bootloader/src/sc64.c +++ b/sw/n64/src/sc64.c @@ -21,7 +21,7 @@ void sc64_wait_cpu_ready(void) { uint32_t sr; do { sr = platform_pi_io_read(&SC64_CFG->SR_CMD); - } while (sr & SC64_CFG_SCR_CPU_READY); + } while (!(sr & SC64_CFG_SCR_CPU_READY)); } void sc64_wait_cpu_busy(void) { diff --git a/sw/bootloader/src/sc64.h b/sw/n64/src/sc64.h similarity index 100% rename from sw/bootloader/src/sc64.h rename to sw/n64/src/sc64.h diff --git a/sw/dumpy/.gitignore b/sw/pc/.gitignore similarity index 100% rename from sw/dumpy/.gitignore rename to sw/pc/.gitignore diff --git a/sw/dumpy/dum.py b/sw/pc/dum.py similarity index 79% rename from sw/dumpy/dum.py rename to sw/pc/dum.py index ab14921..4c75d19 100644 --- a/sw/dumpy/dum.py +++ b/sw/pc/dum.py @@ -7,19 +7,25 @@ import sys class SC64: __SDRAM_SIZE = 64 * 1024 * 1024 + __CONFIG_QUERY_SAVE_TYPE = 1 + __CONFIG_QUERY_SAVE_OFFSET = 4 + def __init__(self, port): self.__serial = serial.Serial(port) - self.__query_config() + self.__save_type = self.__query_config(self.__CONFIG_QUERY_SAVE_TYPE) + self.__save_offset = self.__query_config(self.__CONFIG_QUERY_SAVE_OFFSET) + print('{:08X}'.format(self.__save_type)) + print('{:08X}'.format(self.__save_offset)) - def __query_config(self): + def __query_config(self, query): self.__serial.write(b'CMDQ') - self.__serial.write(bytes(8)) - config_raw = self.__serial.read(12) + self.__serial.write(query.to_bytes(4, byteorder='big')) + self.__serial.write(bytes(4)) + value = self.__serial.read(4) if (self.__serial.read(4).decode() != 'CMPQ'): raise Exception('Bad query response') - self.__save_type = config_raw[2] & 0x07 - self.__save_offset = int.from_bytes(config_raw[4:8], byteorder='big') + return int.from_bytes(value, byteorder='big') def __save_length(self): @@ -83,7 +89,7 @@ class SC64: mode = 'r' file = 'save.dat' -port = 'COM5' +port = 'COM7' if (len(sys.argv) >= 2): mode = sys.argv[1] diff --git a/sw/riscv/.gitignore b/sw/riscv/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/sw/riscv/.gitignore @@ -0,0 +1 @@ +/build diff --git a/sw/riscv/Makefile b/sw/riscv/Makefile new file mode 100644 index 0000000..9919549 --- /dev/null +++ b/sw/riscv/Makefile @@ -0,0 +1,50 @@ +TOOLCHAIN = riscv64-unknown-elf- +CC = $(TOOLCHAIN)gcc +OBJCOPY = $(TOOLCHAIN)objcopy +SIZE = $(TOOLCHAIN)size + +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 +BOOTLOADER_DIR = ../../fw/rtl/cpu + +SRCS = $(wildcard $(patsubst %, %/*.c, . $(SRC_DIR))) +OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(SRCS:.c=.o))) +DEPS = $(OBJS:.o=.d) + +VPATH = $(SRC_DIR) + +all: make_output_dir $(BOOTLOADER_DIR)/cpu_bootloader.sv $(BUILD_DIR)/controller.rom + +$(BUILD_DIR)/%.o: %.c + $(CC) $(FLAGS) $(CFLAGS) -c $< -o $@ + +$(BUILD_DIR)/uc.elf: $(OBJS) SC64.ld + $(CC) $(FLAGS) $(LDFLAGS) -TSC64.ld $(OBJS) -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 + python3 tools/bin2rom.py $@ < $(BUILD_DIR)/controller.bin + @echo 'Size of controller:' + @$(SIZE) -B build/controller.elf + +$(BOOTLOADER_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/bootloader.elf + +make_output_dir: + @$(shell mkdir ./$(BUILD_DIR) 2> /dev/null) + +clean: + rm -rf build + +.PHONY: all make_output_dir clean + +-include $(DEPS) diff --git a/sw/riscv/SC64.ld b/sw/riscv/SC64.ld new file mode 100644 index 0000000..d7302a4 --- /dev/null +++ b/sw/riscv/SC64.ld @@ -0,0 +1,52 @@ +MEMORY { + RAM (rwx) : org = 0x00000000, len = 16k + ROM (rx) : org = 0x10000000, len = 128 +} + +__stack_pointer = ORIGIN(RAM) + LENGTH(RAM) - 4; + +ENTRY(reset_handler) + +SECTIONS { + .text : { + PROVIDE(__app_entry_point = .); + *(.text.app_handler) + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } > RAM + + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } > RAM + + .data : { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE(__global_pointer = . + 0x800); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } > RAM + + .bss : ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } > RAM + + .bootloader : { + *(.text.reset_handler) + } > ROM +} diff --git a/sw/riscv/src/controller.c b/sw/riscv/src/controller.c new file mode 100644 index 0000000..6a65eab --- /dev/null +++ b/sw/riscv/src/controller.c @@ -0,0 +1,248 @@ +#include "sys.h" +#include "driver.h" + + +static e_cfg_save_type_t save_type = CFG_SAVE_TYPE_NONE; +static uint16_t cic_seed = 0xFFFF; +static uint8_t tv_type = 0xFF; + + +void process_usb (void); +void process_cfg (void); +void process_flashram (void); + +void config_update (uint32_t *args); +void config_query (uint32_t *args); + + +void main (void) { + UART->DR = 'X'; + GPIO->ODR = 0; + GPIO->OER = (1 << 0); + + dma_abort(); + usb_flush_rx(); + usb_flush_tx(); + + cfg_set_sdram_switch(true); + cfg_set_save_type(CFG_SAVE_TYPE_NONE); + cfg_set_dd_offset(CFG_DEFAULT_DD_OFFSET); + cfg_set_cpu_ready(true); + + while (1) { + process_usb(); + process_cfg(); + process_flashram(); + } +} + + +typedef enum { + USB_STATE_IDLE, + USB_STATE_ARGS, + USB_STATE_DATA, + USB_STATE_RESPONSE, +} e_usb_state_t; + +#define USB_CMD_TOKEN (0x434D4400) +#define USB_CMP_TOKEN (0x434D5000) +#define USB_ERR_TOKEN (0x45525200) + +void process_usb (void) { + static e_usb_state_t state = USB_STATE_IDLE; + static uint8_t cmd; + static uint32_t args[2]; + static bool error = false; + static bool processing = false; + static uint8_t current_word = 0; + + switch (state) { + case USB_STATE_IDLE: + if (usb_rx_word(&args[0])) { + if ((args[0] & 0xFFFFFF00) == USB_CMD_TOKEN) { + state = USB_STATE_ARGS; + cmd = args[0] & 0xFF; + error = false; + processing = false; + current_word = 0; + } else { + state = USB_STATE_RESPONSE; + error = true; + } + } + break; + + case USB_STATE_ARGS: + if (usb_rx_word(&args[current_word])) { + current_word += 1; + if (current_word == 2) { + state = USB_STATE_DATA; + } + } + break; + + case USB_STATE_DATA: + switch (cmd) { + case 'C': + config_update(args); + state = USB_STATE_RESPONSE; + break; + + case 'Q': + if (!processing) { + config_query(args); + processing = true; + } else if (usb_tx_word(args[1])) { + state = USB_STATE_RESPONSE; + } + break; + + case 'R': + case 'W': + if (!dma_busy()) { + if (!processing) { + e_dma_id_t id = args[1] >> 30; + e_dma_dir_t dir = cmd == 'W' ? DMA_DIR_TO_SDRAM : DMA_DIR_FROM_SDRAM; + dma_start(args[0], args[1], id, dir); + processing = true; + } else { + state = USB_STATE_RESPONSE; + } + } + break; + + case 'D': + break; + + default: + state = USB_STATE_RESPONSE; + error = true; + break; + } + break; + + case USB_STATE_RESPONSE: + if (usb_tx_word(error ? USB_ERR_TOKEN : (USB_CMP_TOKEN | cmd))) { + state = USB_STATE_IDLE; + } + break; + + default: + state = USB_STATE_IDLE; + break; + } +} + +void process_cfg (void) { + uint8_t cmd; + uint32_t args[2]; + + if (cfg_get_command(&cmd, args)) { + switch (cmd) { + case 'C': + config_update(args); + cfg_set_response(args, false); + break; + + case 'Q': + config_query(args); + cfg_set_response(args, false); + break; + + case 'D': + break; + + default: + cfg_set_response(args, true); + return; + } + } +} + +void process_flashram (void) { + e_flashram_op_t op = flashram_get_pending_operation(); + + if (op != FLASHRAM_OP_NONE) { + uint32_t length = flashram_get_operation_length(op); + uint32_t page = flashram_get_page(); + uint32_t offset = cfg_get_save_offset() + (page * FLASHRAM_PAGE_SIZE); + volatile uint32_t *src = flashram_get_page_buffer(); + volatile uint32_t *dst = (uint32_t *) (SDRAM_BASE + offset); + + for (uint32_t i = 0; i < (length / 4); i++) { + if (op == FLASHRAM_OP_WRITE_PAGE) { + dst[i] &= src[i]; + } else { + dst[i] = FLASHRAM_ERASE_VALUE; + } + } + + flashram_set_operation_done(); + } +} + + +typedef enum { + CONFIG_UPDATE_SDRAM_SWITCH, + CONFIG_UPDATE_SDRAM_WRITABLE, + CONFIG_UPDATE_DD_ENABLE, + CONFIG_UPDATE_SAVE_TYPE, + CONFIG_UPDATE_CIC_SEED, + CONFIG_UPDATE_TV_TYPE +} e_config_update_t; + +void config_update (uint32_t *args) { + switch (args[0]) { + case CONFIG_UPDATE_SDRAM_SWITCH: + cfg_set_sdram_switch(args[1]); + break; + case CONFIG_UPDATE_SDRAM_WRITABLE: + cfg_set_sdram_writable(args[1]); + break; + case CONFIG_UPDATE_DD_ENABLE: + cfg_set_dd_enable(args[1]); + break; + case CONFIG_UPDATE_SAVE_TYPE: + save_type = args[1] & 0x07; + cfg_set_save_type(save_type); + break; + case CONFIG_UPDATE_CIC_SEED: + cic_seed = args[1] & 0xFFFF; + break; + case CONFIG_UPDATE_TV_TYPE: + tv_type = args[1] & 0xFF; + break; + } +} + +typedef enum { + CONFIG_QUERY_STATUS, + CONFIG_QUERY_SAVE_TYPE, + CONFIG_QUERY_CIC_SEED, + CONFIG_QUERY_TV_TYPE, + CONFIG_QUERY_SAVE_OFFSET, + CONFIG_QUERY_DD_OFFSET, +} e_config_query_t; + +void config_query (uint32_t *args) { + switch (args[0]) { + case CONFIG_QUERY_STATUS: + args[1] = cfg_get_status(); + break; + case CONFIG_QUERY_SAVE_TYPE: + args[1] = save_type; + break; + case CONFIG_QUERY_CIC_SEED: + args[1] = cic_seed; + break; + case CONFIG_QUERY_TV_TYPE: + args[1] = tv_type; + break; + case CONFIG_QUERY_SAVE_OFFSET: + args[1] = cfg_get_save_offset(); + break; + case CONFIG_QUERY_DD_OFFSET: + args[1] = cfg_get_dd_offset(); + break; + } +} diff --git a/sw/riscv/src/driver.c b/sw/riscv/src/driver.c new file mode 100644 index 0000000..5216089 --- /dev/null +++ b/sw/riscv/src/driver.c @@ -0,0 +1,257 @@ +#include "driver.h" +#include "sys.h" + + +// DMA + +bool dma_start (uint32_t address, uint32_t length, e_dma_id_t id, e_dma_dir_t dir) { + if (DMA->SCR & DMA_SCR_BUSY) { + return false; + } + + DMA->MADDR = address; + DMA->ID_LEN = ((id & 0x03) << 30) | (length & 0x3FFFFFFF); + DMA->SCR = ((dir == DMA_DIR_TO_SDRAM) ? DMA_SCR_DIR : 0) | DMA_SCR_START; + + return true; +} + +void dma_abort (void) { + DMA->SCR = DMA_SCR_STOP; +} + +bool dma_busy (void) { + return DMA->SCR & DMA_SCR_BUSY; +} + + +// FLASHRAM + +e_flashram_op_t flashram_get_pending_operation (void) { + uint32_t scr = FLASHRAM->SCR; + + if (!(scr & FLASHRAM_OPERATION_PENDING)) { + return FLASHRAM_OP_NONE; + } + + if (scr & FLASHRAM_WRITE_OR_ERASE) { + if (scr & FLASHRAM_SECTOR_OR_ALL) { + return FLASHRAM_OP_ERASE_ALL; + } else { + return FLASHRAM_OP_ERASE_SECTOR; + } + } else { + return FLASHRAM_OP_WRITE_PAGE; + } +} + +uint32_t flashram_get_operation_length (e_flashram_op_t op) { + switch (op) { + case FLASHRAM_OP_ERASE_ALL: return FLASHRAM_SIZE; + case FLASHRAM_OP_ERASE_SECTOR: return FLASHRAM_SECTOR_SIZE; + case FLASHRAM_OP_WRITE_PAGE: return FLASHRAM_PAGE_SIZE; + default: return 0; + } +} + +void flashram_set_operation_done (void) { + FLASHRAM->SCR = FLASHRAM_OPERATION_DONE; +} + +uint32_t flashram_get_page (void) { + return (FLASHRAM->SCR >> FLASHRAM_PAGE_BIT); +} + +volatile uint32_t * flashram_get_page_buffer (void) { + return FLASHRAM->BUFFER; +} + + +// USB + +bool usb_rx_byte (uint8_t *data) { + if (!(USB->SCR & USB_SCR_RXNE)) { + return false; + } + + *data = USB->DR; + + return true; +} + +bool usb_rx_word (uint32_t *data) { + static uint8_t current_byte = 0; + static uint32_t buffer = 0; + uint8_t tmp; + + while (usb_rx_byte(&tmp)) { + buffer = (buffer << 8) | tmp; + current_byte += 1; + if (current_byte == 4) { + current_byte = 0; + *data = buffer; + buffer = 0; + + return true; + } + } + + return false; +} + +bool usb_tx_byte (uint8_t data) { + if (!(USB->SCR & USB_SCR_TXE)) { + return false; + } + + USB->DR = data; + + return true; +} + +bool usb_tx_word (uint32_t data) { + static uint8_t current_byte = 0; + while (usb_tx_byte(data >> ((3 - current_byte) * 8))) { + current_byte += 1; + if (current_byte == 4) { + current_byte = 0; + + return true; + } + } + + return false; +} + +void usb_flush_rx (void) { + USB->SCR = USB_SCR_FLUSH_RX; +} + +void usb_flush_tx (void) { + USB->SCR = USB_SCR_FLUSH_TX; +} + + +// CFG + +uint32_t cfg_get_status (void) { + return CFG->SCR; +} + +void cfg_set_cpu_ready (bool enabled) { + if (enabled) { + CFG->SCR |= CFG_SCR_CPU_READY; + } else { + CFG->SCR &= ~CFG_SCR_CPU_READY; + } +} + +void cfg_set_sdram_switch (bool enabled) { + if (enabled) { + CFG->SCR |= CFG_SCR_SDRAM_SWITCH; + } else { + CFG->SCR &= ~CFG_SCR_SDRAM_SWITCH; + } +} + +void cfg_set_sdram_writable (bool enabled) { + if (enabled) { + CFG->SCR |= CFG_SCR_SDRAM_WRITABLE; + } else { + CFG->SCR &= ~CFG_SCR_SDRAM_WRITABLE; + } +} + +void cfg_set_dd_enable (bool enabled) { + if (enabled) { + CFG->SCR |= CFG_SCR_DD_EN; + } else { + CFG->SCR &= ~CFG_SCR_DD_EN; + } +} + +void cfg_set_usb_waiting (bool enabled) { + if (enabled) { + CFG->SCR |= CFG_SCR_USB_WAITING; + } else { + CFG->SCR &= ~CFG_SCR_USB_WAITING; + } +} + +void cfg_set_save_type (e_cfg_save_type_t save_type) { + uint32_t save_offset = 0; + + CFG->SCR &= ~(CFG_SCR_FLASHRAM_EN | CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN); + + switch (save_type) { + case CFG_SAVE_TYPE_NONE: + break; + case CFG_SAVE_TYPE_EEPROM_4K: + save_offset = SDRAM_SIZE - CFG_SAVE_SIZE_EEPROM_4K; + break; + case CFG_SAVE_TYPE_EEPROM_16K: + save_offset = SDRAM_SIZE - CFG_SAVE_SIZE_EEPROM_16K; + break; + case CFG_SAVE_TYPE_SRAM: + save_offset = SDRAM_SIZE - CFG_SAVE_SIZE_SRAM; + CFG->SCR |= CFG_SCR_SRAM_EN; + break; + case CFG_SAVE_TYPE_FLASHRAM: + save_offset = SDRAM_SIZE - CFG_SAVE_SIZE_FLASHRAM; + CFG->SCR |= CFG_SCR_FLASHRAM_EN; + break; + case CFG_SAVE_TYPE_SRAM_BANKED: + save_offset = SDRAM_SIZE - CFG_SAVE_SIZE_SRAM_BANKED; + CFG->SCR |= CFG_SCR_SRAM_BANKED | CFG_SCR_SRAM_EN; + break; + case CFG_SAVE_TYPE_FLASHRAM_PKST2: + save_offset = CFG_SAVE_OFFSET_PKST2; + CFG->SCR |= CFG_SCR_FLASHRAM_EN; + break; + default: + break; + } + + CFG->SAVE_OFFSET = save_offset; +} + +void cfg_set_save_offset (uint32_t offset) { + CFG->SAVE_OFFSET = offset; +} + +uint32_t cfg_get_save_offset (void) { + return CFG->SAVE_OFFSET; +} + +void cfg_set_dd_offset (uint32_t offset) { + CFG->DD_OFFSET = offset; +} + +uint32_t cfg_get_dd_offset (void) { + return CFG->DD_OFFSET; +} + +bool cfg_get_command (uint8_t *cmd, uint32_t *args) { + if (!(CFG->SCR & CFG_SCR_CPU_BUSY)) { + return false; + } + + *cmd = CFG->CMD; + for (size_t i = 0; i < 2; i++) { + args[i] = CFG->DATA[i]; + } + + return true; +} + +void cfg_set_response (uint32_t *args, bool error) { + for (size_t i = 0; i < 2; i++) { + CFG->DATA[i] = args[i]; + } + if (error) { + CFG->SCR |= CFG_SCR_CMD_ERROR; + } else { + CFG->SCR &= ~CFG_SCR_CMD_ERROR; + } + CFG->SCR &= ~(CFG_SCR_CPU_BUSY); +} diff --git a/sw/riscv/src/driver.h b/sw/riscv/src/driver.h new file mode 100644 index 0000000..d745b46 --- /dev/null +++ b/sw/riscv/src/driver.h @@ -0,0 +1,95 @@ +#ifndef DRIVER_H__ +#define DRIVER_H__ + + +#include +#include +#include + + +// DMA + +typedef enum { + DMA_DIR_TO_SDRAM, + DMA_DIR_FROM_SDRAM, +} e_dma_dir_t; + +typedef enum { + DMA_ID_USB = 0, + DMA_ID_SD = 1, +} e_dma_id_t; + +bool dma_start (uint32_t address, uint32_t length, e_dma_id_t id, e_dma_dir_t dir); +void dma_abort (void); +bool dma_busy (void); + + +// USB + +bool usb_rx_byte (uint8_t *data); +bool usb_rx_word (uint32_t *data); +bool usb_tx_byte (uint8_t data); +bool usb_tx_word (uint32_t data); +void usb_flush_rx (void); +void usb_flush_tx (void); + + +// FLASHRAM + +#define FLASHRAM_SIZE (128 * 1024) +#define FLASHRAM_SECTOR_SIZE (16 * 1024) +#define FLASHRAM_PAGE_SIZE (128) +#define FLASHRAM_ERASE_VALUE (0xFFFFFFFF) + +typedef enum { + FLASHRAM_OP_NONE, + FLASHRAM_OP_ERASE_ALL, + FLASHRAM_OP_ERASE_SECTOR, + FLASHRAM_OP_WRITE_PAGE +} e_flashram_op_t; + +e_flashram_op_t flashram_get_pending_operation (void); +uint32_t flashram_get_operation_length (e_flashram_op_t op); +void flashram_set_operation_done (void); +uint32_t flashram_get_page (void); +volatile uint32_t * flashram_get_page_buffer (void); + + +// CFG + +#define CFG_SAVE_SIZE_EEPROM_4K (512) +#define CFG_SAVE_SIZE_EEPROM_16K (2048) +#define CFG_SAVE_SIZE_SRAM (32 * 1024) +#define CFG_SAVE_SIZE_FLASHRAM (128 * 1024) +#define CFG_SAVE_SIZE_SRAM_BANKED (3 * 32 * 1024) + +#define CFG_SAVE_OFFSET_PKST2 (0x01608000UL) + +#define CFG_DEFAULT_DD_OFFSET (0x03BE0000UL) + +typedef enum { + CFG_SAVE_TYPE_NONE = 0, + CFG_SAVE_TYPE_EEPROM_4K = 1, + CFG_SAVE_TYPE_EEPROM_16K = 2, + CFG_SAVE_TYPE_SRAM = 3, + CFG_SAVE_TYPE_FLASHRAM = 4, + CFG_SAVE_TYPE_SRAM_BANKED = 5, + CFG_SAVE_TYPE_FLASHRAM_PKST2 = 6, +} e_cfg_save_type_t; + +uint32_t cfg_get_status (void); +void cfg_set_cpu_ready (bool enabled); +void cfg_set_sdram_switch (bool enabled); +void cfg_set_sdram_writable (bool enabled); +void cfg_set_usb_waiting (bool value); +void cfg_set_dd_enable (bool enabled); +void cfg_set_save_type (e_cfg_save_type_t save_type); +void cfg_set_save_offset (uint32_t offset); +uint32_t cfg_get_save_offset (void); +void cfg_set_dd_offset (uint32_t offset); +uint32_t cfg_get_dd_offset (void); +bool cfg_get_command (uint8_t *cmd, uint32_t *args); +void cfg_set_response (uint32_t *args, bool error); + + +#endif diff --git a/sw/riscv/src/handlers.c b/sw/riscv/src/handlers.c new file mode 100644 index 0000000..36f0c45 --- /dev/null +++ b/sw/riscv/src/handlers.c @@ -0,0 +1,51 @@ +#include +#include "sys.h" + + +#define BOOT_UART + + +__attribute__ ((naked, section(".bootloader"))) int reset_handler (void) { + register uint32_t length = 0; + +#if defined(BOOT_UART) + volatile uint8_t *pointer = (volatile uint8_t *) &RAM; + for (int i = 0; i < 4; i++) { + while (!(UART->SCR & UART_SCR_RXNE)); + length |= (UART->DR << (i * 8)); + } +#elif defined(BOOT_N64) + volatile uint32_t *pointer = (volatile uint32_t *) &RAM; + while (!(CFG->SCR & CFG_SCR_CPU_BUSY)); + length = CFG->DATA[0]; + CFG->SCR &= ~(CFG_SCR_CPU_READY); +#endif + + while (1) { +#if defined(BOOT_UART) + while (!(UART->SCR & UART_SCR_RXNE)); + *pointer++ = UART->DR; + length = length - 1; +#elif defined(BOOT_N64) + while (!(CFG->SCR & CFG_SCR_CPU_BUSY)); + *pointer++ = CFG->DATA[0]; + CFG->SCR &= ~(CFG_SCR_CPU_READY); + length = length - 4; +#endif + if (length == 0) { + __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/fw/cpu/controller/sys.h b/sw/riscv/src/sys.h similarity index 92% rename from fw/cpu/controller/sys.h rename to sw/riscv/src/sys.h index 1ed8aba..bdc4286 100644 --- a/fw/cpu/controller/sys.h +++ b/sw/riscv/src/sys.h @@ -98,7 +98,7 @@ typedef volatile struct cfg_regs { io32_t SAVE_OFFSET; io8_t CMD; io8_t __padding[3]; - io32_t DATA[3]; + io32_t DATA[2]; } cfg_regs_t; #define CFG_BASE (0x70000000UL) @@ -110,6 +110,8 @@ typedef volatile struct cfg_regs { #define CFG_SCR_SRAM_EN (1 << 3) #define CFG_SCR_SRAM_BANKED (1 << 4) #define CFG_SCR_FLASHRAM_EN (1 << 5) +#define CFG_SCR_CMD_ERROR (1 << 28) +#define CFG_SCR_USB_WAITING (1 << 29) #define CFG_SCR_CPU_BUSY (1 << 30) #define CFG_SCR_CPU_READY (1 << 31) @@ -132,7 +134,7 @@ typedef volatile struct flashram_regs { #define FLASHRAM_OPERATION_DONE (1 << 1) #define FLASHRAM_WRITE_OR_ERASE (1 << 2) #define FLASHRAM_SECTOR_OR_ALL (1 << 3) -#define FLASHRAM_SECTOR_BIT (8) +#define FLASHRAM_PAGE_BIT (8) #endif diff --git a/sw/riscv/tools/bin2rom.py b/sw/riscv/tools/bin2rom.py new file mode 100644 index 0000000..390f3cb --- /dev/null +++ b/sw/riscv/tools/bin2rom.py @@ -0,0 +1,22 @@ +#!/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/fw/cpu/bootloader/bin2sv.py b/sw/riscv/tools/bin2sv.py similarity index 70% rename from fw/cpu/bootloader/bin2sv.py rename to sw/riscv/tools/bin2sv.py index 44ddc49..bee77f6 100644 --- a/fw/cpu/bootloader/bin2sv.py +++ b/sw/riscv/tools/bin2sv.py @@ -2,16 +2,13 @@ import struct import sys -binary = None sv_template = None sv_code = None -binary_name = sys.argv[1] or 'binary.bin' -template_name = sys.argv[2] or 'binary_template.sv' -code_name = sys.argv[3] or 'binary.sv' +template_name = sys.argv[1] or 'template.sv' +code_name = sys.argv[2] or 'result.sv' try: - binary = open(binary_name, mode='rb') sv_template = open(template_name, mode='r') sv_code = open(code_name, mode='w') @@ -19,7 +16,7 @@ try: rom_formatted = '' index = 0 - for line in iter(lambda: binary.read(4), ''): + for line in iter(lambda: sys.stdin.buffer.read(4), ''): if (not line): break value = format(struct.unpack('