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) $(OFILES_SRC) : $(HFILES_BIN)
memory.o strings.o: CFLAGS += -O3 memory.o strings.o: CFLAGS += -O3
config.o: CFLAGS += -DCONFIG_TITLE="\"$(APP_TITLE) $(REVISION) configuration\"" patches.o config.o: CFLAGS += -DCONFIG_TITLE="\"$(APP_TITLE) $(REVISION) configuration\""\
patches.o: CFLAGS += -DVERSION_MAJOR="$(VERSION_MAJOR)" -DVERSION_MINOR="$(VERSION_MINOR)"\ -DVERSION_MAJOR="$(VERSION_MAJOR)" -DVERSION_MINOR="$(VERSION_MINOR)"\
-DVERSION_BUILD="$(VERSION_BUILD)" -DISRELEASE="$(IS_RELEASE)" -DCOMMIT_HASH="0x$(COMMIT)" -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 # 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. * reasonable ways as different from the original version.
*/ */
#include <assert.h>
#include "config.h" #include "config.h"
#include "memory.h" #include "memory.h"
#include "fs.h" #include "fs.h"
@ -33,26 +34,97 @@
#include "emunand.h" #include "emunand.h"
#include "buttons.h" #include "buttons.h"
#include "pin.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; CfgData configData;
ConfigurationStatus needConfig; ConfigurationStatus needConfig;
static CfgData oldConfig; 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 readConfig(void)
{ {
bool ret; bool ret;
ret = readConfigMcu();
if (!ret)
return false;
if(fileRead(&configData, CONFIG_FILE, sizeof(CfgData)) != sizeof(CfgData) || if(fileRead(&configData, CONFIG_FILE, sizeof(CfgData)) != sizeof(CfgData) ||
memcmp(configData.magic, "CONF", 4) != 0 || memcmp(configData.magic, "CONF", 4) != 0 ||
configData.formatVersionMajor != CONFIG_VERSIONMAJOR || configData.formatVersionMajor != CONFIG_VERSIONMAJOR ||
configData.formatVersionMinor != CONFIG_VERSIONMINOR) configData.formatVersionMinor != CONFIG_VERSIONMINOR)
{ {
memset(&configData, 0, sizeof(CfgData)); memset(&configData, 0, sizeof(CfgData));
ret = false; ret = false;
} }
else ret = true; else
ret = true;
configData.bootConfig = configDataMcu.bootCfg;
oldConfig = configData; oldConfig = configData;
return ret; return ret;
@ -73,7 +145,9 @@ void writeConfig(bool isConfigOptions)
needConfig = MODIFY_CONFIGURATION; 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"); error("Error writing the configuration file");
} }

View File

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

View File

@ -60,8 +60,19 @@ static bool switchToMainDir(bool isSd)
bool mountFs(bool isSd, bool switchToCtrNand) bool mountFs(bool isSd, bool switchToCtrNand)
{ {
return isSd ? f_mount(&sdFs, "0:", 1) == FR_OK && switchToMainDir(true) : static bool sdInitialized = false, nandInitialized = false;
f_mount(&nandFs, "1:", 1) == FR_OK && (!switchToCtrNand || (f_chdrive("1:") == FR_OK && switchToMainDir(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) 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); if(result == FR_OK) f_closedir(&dir);
} }
static u8 fileCopyBuffer[0x1000]; static u8 fileCopyBuffer[0x10000];
bool backupEssentialFiles(void)
static bool backupEssentialFiles(void)
{ {
size_t sz = sizeof(fileCopyBuffer); size_t sz = sizeof(fileCopyBuffer);
@ -420,3 +432,20 @@ bool backupEssentialFiles(void)
return ok; 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); u32 firmRead(void *dest, u32 firmType);
void findDumpFile(const char *folderPath, char *fileName); 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; u32 rosalinaMenuCombo;
} CfgData; } CfgData;
typedef struct
{
u16 lumaVersion;
u8 bootCfg;
u8 reserved[2];
u8 checksum;
} CfgDataMcu;
typedef struct typedef struct
{ {
char magic[4]; char magic[4];