diff --git a/build.sh b/build.sh index 067a28a..1fada7e 100755 --- a/build.sh +++ b/build.sh @@ -71,6 +71,9 @@ build_update () { build_fpga pushd sw/update > /dev/null + if [ "$FORCE_CLEAN" = true ]; then + rm -f ./sc64.upd + fi INFO="" if [ ! -z "${GIT_BRANCH+x}" ]; then INFO+=" $GIT_BRANCH"; fi if [ ! -z "${GIT_TAG+x}" ]; then INFO+=" $GIT_TAG"; fi diff --git a/sw/bootloader/src/startup.S b/sw/bootloader/src/startup.S index 73f1e78..04f640b 100644 --- a/sw/bootloader/src/startup.S +++ b/sw/bootloader/src/startup.S @@ -19,7 +19,7 @@ header_crc: .org 0x20, 0x00 header_text_info: - .ascii "n64boot SummerCart64" + .ascii "SC64 bootloader" .org 0x40, 0x00 diff --git a/sw/controller/build.sh b/sw/controller/build.sh index b2345b3..18a31a8 100755 --- a/sw/controller/build.sh +++ b/sw/controller/build.sh @@ -1,6 +1,8 @@ #!/bin/bash +set -e + case "$1" in all) make all -j -f loader.mk USER_FLAGS="$USER_FLAGS" diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index de94aa5..193025b 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -194,7 +194,7 @@ bool cfg_query (uint32_t *args) { args[1] = p.tv_type; break; case CFG_ID_FLASH_ERASE_BLOCK: - args[1] = 0xFFFFFFFF; + args[1] = FLASH_ERASE_BLOCK_SIZE; break; case CFG_ID_DD_DRIVE_TYPE: args[1] = dd_get_drive_type(); diff --git a/sw/controller/src/update.c b/sw/controller/src/update.c index f36d160..52ab791 100644 --- a/sw/controller/src/update.c +++ b/sw/controller/src/update.c @@ -44,7 +44,7 @@ static uint32_t update_align (uint32_t value) { } static uint32_t update_checksum (uint32_t address, uint32_t length) { - uint8_t buffer[32]; + uint8_t buffer[128]; uint32_t block_size; uint32_t checksum = 0; hw_crc32_reset(); @@ -145,6 +145,40 @@ static void update_status_notify (update_status_t status) { } } +static bool mcu_update (uint32_t address, uint32_t length) { + hw_flash_t buffer; + hw_flash_erase(); + for (uint32_t offset = 0; offset < length; offset += sizeof(hw_flash_t)) { + fpga_mem_read(address + offset, sizeof(hw_flash_t), (uint8_t *) (&buffer)); + hw_flash_program(offset, buffer); + if (hw_flash_read(offset) != buffer) { + return true; + } + } + return false; +} + +static bool bootloader_update (uint32_t address, uint32_t length) { + uint8_t update_buffer[FPGA_MAX_MEM_TRANSFER]; + uint8_t verify_buffer[FPGA_MAX_MEM_TRANSFER]; + for (uint32_t offset = 0; offset < BOOTLOADER_LENGTH; offset += FLASH_ERASE_BLOCK_SIZE) { + flash_erase_block(BOOTLOADER_ADDRESS + offset); + } + for (uint32_t offset = 0; offset < length; offset += FPGA_MAX_MEM_TRANSFER) { + fpga_mem_copy(address + offset, BOOTLOADER_ADDRESS + offset, FPGA_MAX_MEM_TRANSFER); + } + for (uint32_t offset = 0; offset < length; offset += sizeof(verify_buffer)) { + fpga_mem_read(address + offset, sizeof(update_buffer), update_buffer); + fpga_mem_read(BOOTLOADER_ADDRESS + offset, sizeof(verify_buffer), verify_buffer); + for (int i = 0; i < sizeof(verify_buffer); i++) { + if (update_buffer[i] != verify_buffer[i]) { + return true; + } + } + } + return false; +} + update_error_t update_backup (uint32_t address, uint32_t *length) { uint32_t mcu_length; @@ -247,17 +281,11 @@ void update_perform (void) { uint32_t length; if (parameters.flags & LOADER_FLAGS_UPDATE_MCU) { - hw_flash_t buffer; update_status_notify(UPDATE_STATUS_MCU); fpga_mem_read(parameters.mcu_address - 4, sizeof(length), (uint8_t *) (&length)); - hw_flash_erase(); - for (uint32_t offset = 0; offset < length; offset += sizeof(hw_flash_t)) { - fpga_mem_read(parameters.mcu_address + offset, sizeof(hw_flash_t), (uint8_t *) (&buffer)); - hw_flash_program(offset, buffer); - if (hw_flash_read(offset) != buffer) { - update_status_notify(UPDATE_STATUS_ERROR); - while (1); - } + if (mcu_update(parameters.mcu_address, length)) { + update_status_notify(UPDATE_STATUS_ERROR); + while (1); } } @@ -273,11 +301,9 @@ void update_perform (void) { if (parameters.flags & LOADER_FLAGS_UPDATE_BOOTLOADER) { update_status_notify(UPDATE_STATUS_BOOTLOADER); fpga_mem_read(parameters.bootloader_address - 4, sizeof(length), (uint8_t *) (&length)); - for (uint32_t offset = 0; offset < BOOTLOADER_LENGTH; offset += FLASH_ERASE_BLOCK_SIZE) { - flash_erase_block(BOOTLOADER_ADDRESS + offset); - } - for (uint32_t offset = 0; offset < length; offset += FPGA_MAX_MEM_TRANSFER) { - fpga_mem_copy(parameters.bootloader_address + offset, BOOTLOADER_ADDRESS + offset, FPGA_MAX_MEM_TRANSFER); + if (bootloader_update(parameters.bootloader_address, length)) { + update_status_notify(UPDATE_STATUS_ERROR); + while (1); } } diff --git a/sw/update/update.py b/sw/update/update.py index ecae801..e0a41c3 100644 --- a/sw/update/update.py +++ b/sw/update/update.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import argparse import math import os @@ -7,6 +9,7 @@ from datetime import datetime from io import BufferedRandom + class JedecError(Exception): pass