Move bootconfig to mcu free regs & copy boot.firm to NAND with each upgrade

This commit is contained in:
TuxSH 2022-03-27 21:04:23 +01:00
parent fcdb6a7ab5
commit d798ff0efc
6 changed files with 122 additions and 11 deletions

View File

@ -159,8 +159,8 @@ $(OUTPUT).elf : $(OFILES)
$(OFILES_SRC) : $(HFILES_BIN)
memory.o strings.o: CFLAGS += -O3
config.o: CFLAGS += -DCONFIG_TITLE="\"$(APP_TITLE) $(REVISION) configuration\""
patches.o: CFLAGS += -DVERSION_MAJOR="$(VERSION_MAJOR)" -DVERSION_MINOR="$(VERSION_MINOR)"\
patches.o config.o: CFLAGS += -DCONFIG_TITLE="\"$(APP_TITLE) $(REVISION) configuration\""\
-DVERSION_MAJOR="$(VERSION_MAJOR)" -DVERSION_MINOR="$(VERSION_MINOR)"\
-DVERSION_BUILD="$(VERSION_BUILD)" -DISRELEASE="$(IS_RELEASE)" -DCOMMIT_HASH="0x$(COMMIT)"
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data

View File

@ -24,6 +24,7 @@
* reasonable ways as different from the original version.
*/
#include <assert.h>
#include "config.h"
#include "memory.h"
#include "fs.h"
@ -33,26 +34,97 @@
#include "emunand.h"
#include "buttons.h"
#include "pin.h"
#include "i2c.h"
#define MAKE_LUMA_VERSION_MCU(major, minor, build) (u16)(((major) & 0xFF) << 8 | ((minor) & 0x1F) << 5 | ((build) & 7))
CfgData configData;
ConfigurationStatus needConfig;
static CfgData oldConfig;
static CfgDataMcu configDataMcu;
static_assert(sizeof(CfgDataMcu) > 0, "wrong data size");
static void writeConfigMcu(void)
{
u8 data[sizeof(CfgDataMcu)];
// Set Luma version
configDataMcu.lumaVersion = MAKE_LUMA_VERSION_MCU(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
// Set bootconfig from CfgData
configDataMcu.bootCfg = configData.bootConfig;
memcpy(data, &configDataMcu, sizeof(CfgDataMcu));
// Fix checksum
u8 checksum = 0;
for (u32 i = 0; i < sizeof(CfgDataMcu) - 1; i++)
checksum += data[i];
checksum = ~checksum;
data[sizeof(CfgDataMcu) - 1] = checksum;
configDataMcu.checksum = checksum;
I2C_writeReg(I2C_DEV_MCU, 0x60, 200 - sizeof(CfgDataMcu));
I2C_writeRegBuf(I2C_DEV_MCU, 0x61, data, sizeof(CfgDataMcu));
}
static bool readConfigMcu(void)
{
u8 data[sizeof(CfgDataMcu)];
u16 curVer = MAKE_LUMA_VERSION_MCU(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
// Select free reg id, then access the data regs
I2C_writeReg(I2C_DEV_MCU, 0x60, 200 - sizeof(CfgDataMcu));
I2C_readRegBuf(I2C_DEV_MCU, 0x61, data, sizeof(CfgDataMcu));
memcpy(&configDataMcu, data, sizeof(CfgDataMcu));
u8 checksum = 0;
for (u32 i = 0; i < sizeof(CfgDataMcu) - 1; i++)
checksum += data[i];
checksum = ~checksum;
if (checksum != configDataMcu.checksum || configDataMcu.lumaVersion < MAKE_LUMA_VERSION_MCU(10, 3, 0))
{
// Invalid data stored in MCU...
configData.bootConfig = 0;
// Perform upgrade process (ignoring failures)
doLumaUpgradeProcess();
writeConfigMcu();
return false;
}
if (configDataMcu.lumaVersion < curVer)
{
// Perform upgrade process (ignoring failures)
doLumaUpgradeProcess();
writeConfigMcu();
}
return true;
}
bool readConfig(void)
{
bool ret;
ret = readConfigMcu();
if (!ret)
return false;
if(fileRead(&configData, CONFIG_FILE, sizeof(CfgData)) != sizeof(CfgData) ||
memcmp(configData.magic, "CONF", 4) != 0 ||
configData.formatVersionMajor != CONFIG_VERSIONMAJOR ||
configData.formatVersionMinor != CONFIG_VERSIONMINOR)
{
memset(&configData, 0, sizeof(CfgData));
ret = false;
}
else ret = true;
else
ret = true;
configData.bootConfig = configDataMcu.bootCfg;
oldConfig = configData;
return ret;
@ -73,7 +145,9 @@ void writeConfig(bool isConfigOptions)
needConfig = MODIFY_CONFIGURATION;
}
if(!fileWrite(&configData, CONFIG_FILE, sizeof(CfgData)))
if (!isConfigOptions)
writeConfigMcu();
else if(!fileWrite(&configData, CONFIG_FILE, sizeof(CfgData)))
error("Error writing the configuration file");
}

View File

@ -34,7 +34,7 @@
#define CONFIG_FILE "config.bin"
#define CONFIG_VERSIONMAJOR 2
#define CONFIG_VERSIONMINOR 4
#define CONFIG_VERSIONMINOR 5
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)

View File

@ -60,8 +60,19 @@ static bool switchToMainDir(bool isSd)
bool mountFs(bool isSd, bool switchToCtrNand)
{
return isSd ? f_mount(&sdFs, "0:", 1) == FR_OK && switchToMainDir(true) :
f_mount(&nandFs, "1:", 1) == FR_OK && (!switchToCtrNand || (f_chdrive("1:") == FR_OK && switchToMainDir(false)));
static bool sdInitialized = false, nandInitialized = false;
if (isSd)
{
if (!sdInitialized)
sdInitialized = f_mount(&sdFs, "0:", 1) == FR_OK;
return sdInitialized && switchToMainDir(true);
}
else
{
if (!nandInitialized)
nandInitialized = f_mount(&nandFs, "1:", 1) == FR_OK;
return nandInitialized && (!switchToCtrNand || (f_chdrive("1:") == FR_OK && switchToMainDir(false)));
}
}
u32 fileRead(void *dest, const char *path, u32 maxSize)
@ -385,8 +396,9 @@ void findDumpFile(const char *folderPath, char *fileName)
if(result == FR_OK) f_closedir(&dir);
}
static u8 fileCopyBuffer[0x1000];
bool backupEssentialFiles(void)
static u8 fileCopyBuffer[0x10000];
static bool backupEssentialFiles(void)
{
size_t sz = sizeof(fileCopyBuffer);
@ -420,3 +432,20 @@ bool backupEssentialFiles(void)
return ok;
}
bool doLumaUpgradeProcess(void)
{
// Ensure CTRNAND is mounted
bool ok = mountFs(false, false), ok2 = true;
if (!ok)
return false;
// Try to boot.firm to CTRNAND, when applicable
if (isSdMode)
ok = fileCopy("0:/boot.firm", "1:/boot.firm", true, fileCopyBuffer, sizeof(fileCopyBuffer));
// Try to backup essential files
ok2 = backupEssentialFiles();
return ok && ok2;
}

View File

@ -41,4 +41,4 @@ bool payloadMenu(char *path, bool *hasDisplayedMenu);
u32 firmRead(void *dest, u32 firmType);
void findDumpFile(const char *folderPath, char *fileName);
bool backupEssentialFiles(void);
bool doLumaUpgradeProcess(void);

View File

@ -71,6 +71,14 @@ typedef struct __attribute__((packed, aligned(4)))
u32 rosalinaMenuCombo;
} CfgData;
typedef struct
{
u16 lumaVersion;
u8 bootCfg;
u8 reserved[2];
u8 checksum;
} CfgDataMcu;
typedef struct
{
char magic[4];