mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-21 21:49:15 +01:00
[SC64][SW] Update: allow firmware update from the Flash memory
This commit is contained in:
parent
0e868b5ad5
commit
cf19dc6151
@ -8,10 +8,13 @@
|
||||
|
||||
|
||||
bool flash_program (uint32_t src, uint32_t dst, uint32_t length) {
|
||||
if (((src + length) > FLASH_ADDRESS) && (src < (FLASH_ADDRESS + FLASH_SIZE))) {
|
||||
if ((dst < FLASH_ADDRESS) || ((dst + length) > (FLASH_ADDRESS + FLASH_SIZE))) {
|
||||
return true;
|
||||
}
|
||||
if ((dst < FLASH_ADDRESS) || ((dst + length) > (FLASH_ADDRESS + FLASH_SIZE))) {
|
||||
if ((src <= dst) && ((src + length) > dst)) {
|
||||
return true;
|
||||
}
|
||||
if ((dst <= src) && ((dst + length) > src)) {
|
||||
return true;
|
||||
}
|
||||
while (length > 0) {
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#define SDRAM_ADDRESS (0x00000000UL)
|
||||
#define SDRAM_LENGTH (64 * 1024 * 1024)
|
||||
#define FLASH_USABLE_LENGTH (14 * 1024 * 1024)
|
||||
#define UPDATE_ADDRESS_END (SDRAM_ADDRESS + SDRAM_LENGTH + FLASH_USABLE_LENGTH)
|
||||
|
||||
#define UPDATE_MAGIC_START (0x54535055UL)
|
||||
#define BOOTLOADER_ADDRESS (0x04E00000UL)
|
||||
@ -234,10 +236,10 @@ update_error_t update_prepare (uint32_t address, uint32_t length) {
|
||||
uint32_t data_address;
|
||||
uint32_t data_length;
|
||||
|
||||
if ((address >= (SDRAM_ADDRESS + SDRAM_LENGTH)) || (length > SDRAM_LENGTH)) {
|
||||
if ((address >= UPDATE_ADDRESS_END) || (length > (SDRAM_LENGTH + FLASH_USABLE_LENGTH))) {
|
||||
return UPDATE_ERROR_ADDRESS;
|
||||
}
|
||||
if (end_address > (SDRAM_ADDRESS + SDRAM_LENGTH)) {
|
||||
if (end_address > UPDATE_ADDRESS_END) {
|
||||
return UPDATE_ERROR_ADDRESS;
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ enum FirmwareCommands {
|
||||
Backup(FirmwareArgs),
|
||||
|
||||
/// Update SC64 firmware from provided file
|
||||
Update(FirmwareArgs),
|
||||
Update(FirmwareUpdateArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
@ -221,6 +221,16 @@ struct FirmwareArgs {
|
||||
firmware: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
struct FirmwareUpdateArgs {
|
||||
/// Path to the firmware file
|
||||
firmware: PathBuf,
|
||||
|
||||
/// Put firmware update in the Flash memory instead of SDRAM
|
||||
#[arg(long)]
|
||||
use_flash_memory: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
struct ServerArgs {
|
||||
/// Listen on provided address:port
|
||||
@ -738,8 +748,14 @@ fn handle_info_command(connection: Connection) -> Result<(), sc64::Error> {
|
||||
println!(" LED blink: {}", state.led_enable);
|
||||
println!(" IS-Viewer 64 offset: 0x{:08X}", state.isv_address);
|
||||
println!("{}", "SummerCart64 diagnostic information:".bold());
|
||||
println!(" Last PI address: 0x{:08X}", state.fpga_debug_data.last_pi_address);
|
||||
println!(" PI FIFO flags: {}", state.fpga_debug_data.pi_fifo_flags);
|
||||
println!(
|
||||
" Last PI address: 0x{:08X}",
|
||||
state.fpga_debug_data.last_pi_address
|
||||
);
|
||||
println!(
|
||||
" PI FIFO flags: {}",
|
||||
state.fpga_debug_data.pi_fifo_flags
|
||||
);
|
||||
println!(" Current CIC step: {}", state.fpga_debug_data.cic_step);
|
||||
println!(" Diagnostic data: {}", state.diagnostic_data);
|
||||
|
||||
@ -835,6 +851,12 @@ fn handle_firmware_command(
|
||||
println!("{}", "Firmware metadata:".bold());
|
||||
println!("{}", format!("{}", metadata).bright_blue().to_string());
|
||||
println!("{}", "Firmware file verification was successful".green());
|
||||
if args.use_flash_memory {
|
||||
println!(
|
||||
"{}",
|
||||
"Warning: using Flash memory to perform firmware update".yellow()
|
||||
);
|
||||
}
|
||||
let answer = prompt(format!("{}", "Continue with update process? [y/N] ".bold()));
|
||||
if answer.to_ascii_lowercase() != "y" {
|
||||
println!("{}", "Firmware update process aborted".red());
|
||||
@ -847,7 +869,7 @@ fn handle_firmware_command(
|
||||
|
||||
log_wait(
|
||||
format!("Updating firmware, this might take a while [{update_name}]"),
|
||||
|| sc64.update_firmware(&firmware),
|
||||
|| sc64.update_firmware(&firmware, args.use_flash_memory),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -89,7 +89,8 @@ const SRAM_1M_LENGTH: usize = 128 * 1024;
|
||||
|
||||
const BOOTLOADER_ADDRESS: u32 = 0x04E0_0000;
|
||||
|
||||
const FIRMWARE_ADDRESS: u32 = 0x0010_0000; // Arbitrary offset in SDRAM memory
|
||||
const FIRMWARE_ADDRESS_SDRAM: u32 = 0x0010_0000; // Arbitrary offset in SDRAM memory
|
||||
const FIRMWARE_ADDRESS_FLASH: u32 = 0x0410_0000; // Arbitrary offset in Flash memory
|
||||
const FIRMWARE_UPDATE_TIMEOUT: Duration = Duration::from_secs(90);
|
||||
|
||||
const ISV_BUFFER_LENGTH: usize = 64 * 1024;
|
||||
@ -668,19 +669,43 @@ impl SC64 {
|
||||
|
||||
pub fn backup_firmware(&mut self) -> Result<Vec<u8>, Error> {
|
||||
self.command_state_reset()?;
|
||||
let (status, length) = self.command_firmware_backup(FIRMWARE_ADDRESS)?;
|
||||
let (status, length) = self.command_firmware_backup(FIRMWARE_ADDRESS_SDRAM)?;
|
||||
if !matches!(status, FirmwareStatus::Ok) {
|
||||
return Err(Error::new(
|
||||
format!("Firmware backup error: {}", status).as_str(),
|
||||
));
|
||||
}
|
||||
self.command_memory_read(FIRMWARE_ADDRESS, length as usize)
|
||||
self.command_memory_read(FIRMWARE_ADDRESS_SDRAM, length as usize)
|
||||
}
|
||||
|
||||
pub fn update_firmware(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||
pub fn update_firmware(&mut self, data: &[u8], use_flash_memory: bool) -> Result<(), Error> {
|
||||
const FLASH_UPDATE_SUPPORTED_MINOR_VERSION: u16 = 19;
|
||||
let status = if use_flash_memory {
|
||||
let unsupported_version_error = Error::new(format!(
|
||||
"Your firmware doesn't support updating from Flash memory, minimum required version: {}.{}.x",
|
||||
SUPPORTED_MAJOR_VERSION, FLASH_UPDATE_SUPPORTED_MINOR_VERSION
|
||||
).as_str());
|
||||
self.command_version_get()
|
||||
.and_then(|(major, minor, revision)| {
|
||||
if major != SUPPORTED_MAJOR_VERSION
|
||||
|| minor < FLASH_UPDATE_SUPPORTED_MINOR_VERSION
|
||||
{
|
||||
return Err(unsupported_version_error.clone());
|
||||
} else {
|
||||
Ok((major, minor, revision))
|
||||
}
|
||||
})
|
||||
.map_err(|_| unsupported_version_error.clone())?;
|
||||
self.command_state_reset()?;
|
||||
self.command_memory_write(FIRMWARE_ADDRESS, data)?;
|
||||
let status = self.command_firmware_update(FIRMWARE_ADDRESS, data.len())?;
|
||||
self.flash_erase(FIRMWARE_ADDRESS_FLASH, data.len())?;
|
||||
self.command_memory_write(FIRMWARE_ADDRESS_FLASH, data)?;
|
||||
self.command_flash_wait_busy(true)?;
|
||||
self.command_firmware_update(FIRMWARE_ADDRESS_FLASH, data.len())?
|
||||
} else {
|
||||
self.command_state_reset()?;
|
||||
self.command_memory_write(FIRMWARE_ADDRESS_SDRAM, data)?;
|
||||
self.command_firmware_update(FIRMWARE_ADDRESS_SDRAM, data.len())?
|
||||
};
|
||||
if !matches!(status, FirmwareStatus::Ok) {
|
||||
return Err(Error::new(
|
||||
format!("Firmware update verify error: {}", status).as_str(),
|
||||
|
Loading…
Reference in New Issue
Block a user