From e1112f190332fd2640a1f6e55b60465a1cf0ace3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 1 Mar 2022 14:44:50 +0100 Subject: [PATCH] extension for additional safety --- bsp_q7s/core/CoreController.cpp | 104 ++++++++----- bsp_q7s/core/CoreController.h | 10 +- unittest/rebootLogic/src/CoreController.cpp | 76 ++++++---- unittest/rebootLogic/src/CoreController.h | 10 +- unittest/rebootLogic/src/main.cpp | 158 ++++++++++++++++++-- 5 files changed, 270 insertions(+), 88 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 554eb4d9..e1c6a430 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -131,24 +131,26 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } return HasActionsIF::EXECUTION_FINISHED; } - case (RESET_ALL_REBOOT_COUNTERS): { - resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY); + case (RESET_REBOOT_COUNTERS): { + if (size == 0) { + resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY); + } else if (size == 2) { + if (data[0] > 1 or data[1] > 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + resetRebootCount(static_cast(data[0]), static_cast(data[1])); + } return HasActionsIF::EXECUTION_FINISHED; } - case (RESET_REBOOT_COUNTER_00): { - resetRebootCount(xsc::CHIP_0, xsc::COPY_0); - return HasActionsIF::EXECUTION_FINISHED; - } - case (RESET_REBOOT_COUNTER_01): { - resetRebootCount(xsc::CHIP_0, xsc::COPY_1); - return HasActionsIF::EXECUTION_FINISHED; - } - case (RESET_REBOOT_COUNTER_10): { - resetRebootCount(xsc::CHIP_1, xsc::COPY_0); - return HasActionsIF::EXECUTION_FINISHED; - } - case (RESET_REBOOT_COUNTER_11): { - resetRebootCount(xsc::CHIP_1, xsc::COPY_1); + case (SWITCH_IMG_LOCK): { + if (size != 3) { + return HasActionsIF::INVALID_PARAMETERS; + } + if (data[1] > 1 or data[2] > 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + setRebootMechanismLock(data[0], static_cast(data[1]), + static_cast(data[2])); return HasActionsIF::EXECUTION_FINISHED; } case (SET_MAX_REBOOT_CNT): { @@ -1184,6 +1186,22 @@ void CoreController::performWatchdogControlOperation() { } } +void CoreController::performMountedSdCardOperations() { + if (doPerformMountedSdCardOps) { + bool sdCardMounted = false; + sdCardMounted = sdcMan->isSdCardMounted(sdInfo.pref); + if (sdCardMounted) { + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + "/" + CONF_FOLDER; + if (not std::filesystem::exists(path)) { + std::filesystem::create_directory(path); + } + initVersionFile(); + performRebootFileHandling(true); + doPerformMountedSdCardOps = false; + } + } +} + void CoreController::performRebootFileHandling(bool recreateFile) { using namespace std; std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; @@ -1240,10 +1258,10 @@ void CoreController::performRebootFileHandling(bool recreateFile) { rebootFile.mechanismNextCopy != xsc::NO_COPY) { if (CURRENT_CHIP != rebootFile.mechanismNextChip or CURRENT_COPY != rebootFile.mechanismNextCopy) { - std::string infoString = static_cast(rebootFile.mechanismNextChip) + " " + - static_cast(rebootFile.mechanismNextCopy); - sif::warning << "CoreController::performRebootFileHandling: Expected to be on image" - << infoString << " but currently on other image. Locking" << infoString + std::string infoString = std::to_string(rebootFile.mechanismNextChip) + " " + + std::to_string(rebootFile.mechanismNextCopy); + sif::warning << "CoreController::performRebootFileHandling: Expected to be on image " + << infoString << " but currently on other image. Locking " << infoString << std::endl; // Firmware or other component might be corrupt and we are on another image then the target // image specified by the mechanism. We can't really trust the target image anymore. @@ -1264,6 +1282,8 @@ void CoreController::performRebootFileHandling(bool recreateFile) { } } + rebootFile.lastChip = CURRENT_CHIP; + rebootFile.lastCopy = CURRENT_COPY; // Only reboot if the reboot functionality is enabled. // The handler will still increment the boot counts if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) { @@ -1278,8 +1298,6 @@ void CoreController::performRebootFileHandling(bool recreateFile) { sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY << " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl; #endif - rebootFile.lastChip = CURRENT_CHIP; - rebootFile.lastCopy = CURRENT_COPY; rebootFile.mechanismNextChip = tgtChip; rebootFile.mechanismNextCopy = tgtCopy; rewriteRebootFile(rebootFile); @@ -1287,8 +1305,10 @@ void CoreController::performRebootFileHandling(bool recreateFile) { static_cast(tgtCopy)); } } else { - rewriteRebootFile(rebootFile); + rebootFile.mechanismNextChip = xsc::NO_CHIP; + rebootFile.mechanismNextCopy = xsc::NO_COPY; } + rewriteRebootFile(rebootFile); } void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot, @@ -1589,22 +1609,6 @@ void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) { rewriteRebootFile(rebootFile); } -void CoreController::performMountedSdCardOperations() { - if (doPerformMountedSdCardOps) { - bool sdCardMounted = false; - sdCardMounted = sdcMan->isSdCardMounted(sdInfo.pref); - if (sdCardMounted) { - std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + "/" + CONF_FOLDER; - if (not std::filesystem::exists(path)) { - std::filesystem::create_directory(path); - } - initVersionFile(); - performRebootFileHandling(true); - doPerformMountedSdCardOps = false; - } - } -} - void CoreController::rewriteRebootFile(RebootFile file) { std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; std::ofstream rebootFile(path); @@ -1614,10 +1618,30 @@ void CoreController::rewriteRebootFile(RebootFile file) { << "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt << "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt << "\nimg00lock: " << file.img00Lock << "\nimg01lock: " << file.img01Lock - << "\nimg10lock: " << file.img01Lock << "\nimg11lock: " << file.img11Lock + << "\nimg10lock: " << file.img10Lock << "\nimg11lock: " << file.img11Lock << "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast(file.lastChip) << " " << static_cast(file.lastCopy) << "\nnext: " << static_cast(file.mechanismNextChip) << " " << static_cast(file.mechanismNextCopy) << "\n"; } } + +void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) { + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + // Disable the reboot file mechanism + parseRebootFile(path, rebootFile); + if (tgtChip == xsc::CHIP_0) { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img00Lock = lock; + } else { + rebootFile.img01Lock = lock; + } + } else { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img10Lock = lock; + } else { + rebootFile.img11Lock = lock; + } + } + rewriteRebootFile(rebootFile); +} diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index f6835afa..37f5395d 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -59,12 +59,9 @@ class CoreController : public ExtendedControllerBase { static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5; - static constexpr ActionId_t RESET_ALL_REBOOT_COUNTERS = 6; - static constexpr ActionId_t RESET_REBOOT_COUNTER_00 = 7; - static constexpr ActionId_t RESET_REBOOT_COUNTER_01 = 8; - static constexpr ActionId_t RESET_REBOOT_COUNTER_10 = 9; - static constexpr ActionId_t RESET_REBOOT_COUNTER_11 = 10; - static constexpr ActionId_t SET_MAX_REBOOT_CNT = 11; + static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6; + static constexpr ActionId_t SWITCH_IMG_LOCK = 7; + static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8; static constexpr ActionId_t REBOOT_OBC = 32; static constexpr ActionId_t MOUNT_OTHER_COPY = 33; @@ -220,6 +217,7 @@ class CoreController : public ExtendedControllerBase { void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip, xsc::Copy& tgtCopy); void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy); + void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy); bool parseRebootFile(std::string path, RebootFile& file); void rewriteRebootFile(RebootFile file); }; diff --git a/unittest/rebootLogic/src/CoreController.cpp b/unittest/rebootLogic/src/CoreController.cpp index b9ba84be..c01d61f8 100644 --- a/unittest/rebootLogic/src/CoreController.cpp +++ b/unittest/rebootLogic/src/CoreController.cpp @@ -74,10 +74,10 @@ void CoreController::performRebootFileHandling(bool recreateFile) { rebootFile.mechanismNextCopy != xsc::NO_COPY) { if (CURRENT_CHIP != rebootFile.mechanismNextChip or CURRENT_COPY != rebootFile.mechanismNextCopy) { - std::string infoString = static_cast(rebootFile.mechanismNextChip) + " " + - static_cast(rebootFile.mechanismNextCopy); - sif::warning << "CoreController::performRebootFileHandling: Expected to be on image" - << infoString << " but currently on other image. Locking" << infoString + std::string infoString = std::to_string(rebootFile.mechanismNextChip) + " " + + std::to_string(rebootFile.mechanismNextCopy); + sif::warning << "CoreController::performRebootFileHandling: Expected to be on image " + << infoString << " but currently on other image. Locking " << infoString << std::endl; // Firmware or other component might be corrupt and we are on another image then the target // image specified by the mechanism. We can't really trust the target image anymore. @@ -98,6 +98,8 @@ void CoreController::performRebootFileHandling(bool recreateFile) { } } + rebootFile.lastChip = CURRENT_CHIP; + rebootFile.lastCopy = CURRENT_COPY; // Only reboot if the reboot functionality is enabled. // The handler will still increment the boot counts if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) { @@ -112,8 +114,6 @@ void CoreController::performRebootFileHandling(bool recreateFile) { sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY << " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl; #endif - rebootFile.lastChip = CURRENT_CHIP; - rebootFile.lastCopy = CURRENT_COPY; rebootFile.mechanismNextChip = tgtChip; rebootFile.mechanismNextCopy = tgtCopy; rewriteRebootFile(rebootFile); @@ -121,8 +121,10 @@ void CoreController::performRebootFileHandling(bool recreateFile) { static_cast(tgtCopy)); } } else { - rewriteRebootFile(rebootFile); - } + rebootFile.mechanismNextChip = xsc::NO_CHIP; + rebootFile.mechanismNextCopy = xsc::NO_COPY; + } + rewriteRebootFile(rebootFile); } void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot, @@ -432,7 +434,7 @@ void CoreController::rewriteRebootFile(RebootFile file) { << "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt << "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt << "\nimg00lock: " << file.img00Lock << "\nimg01lock: " << file.img01Lock - << "\nimg10lock: " << file.img01Lock << "\nimg11lock: " << file.img11Lock + << "\nimg10lock: " << file.img10Lock << "\nimg11lock: " << file.img11Lock << "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast(file.lastChip) << " " << static_cast(file.lastCopy) << "\nnext: " << static_cast(file.mechanismNextChip) << " " @@ -461,24 +463,26 @@ switch (actionId) { } return HasActionsIF::EXECUTION_FINISHED; } - case (RESET_ALL_REBOOT_COUNTERS): { - resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY); + case (RESET_REBOOT_COUNTERS): { + if(size == 0) { + resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY); + } else if (size == 2) { + if(data[0] > 1 or data[1] > 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + resetRebootCount(static_cast(data[0]), static_cast(data[1])); + } return HasActionsIF::EXECUTION_FINISHED; } - case (RESET_REBOOT_COUNTER_00): { - resetRebootCount(xsc::CHIP_0, xsc::COPY_0); - return HasActionsIF::EXECUTION_FINISHED; - } - case (RESET_REBOOT_COUNTER_01): { - resetRebootCount(xsc::CHIP_0, xsc::COPY_1); - return HasActionsIF::EXECUTION_FINISHED; - } - case (RESET_REBOOT_COUNTER_10): { - resetRebootCount(xsc::CHIP_1, xsc::COPY_0); - return HasActionsIF::EXECUTION_FINISHED; - } - case (RESET_REBOOT_COUNTER_11): { - resetRebootCount(xsc::CHIP_1, xsc::COPY_1); + case (SWITCH_IMG_LOCK): { + if(size != 3) { + return HasActionsIF::INVALID_PARAMETERS; + } + if(data[1] > 1 or data[2] > 1) { + return HasActionsIF::INVALID_PARAMETERS; + } + setRebootMechanismLock(data[0], static_cast(data[1]), + static_cast(data[2])); return HasActionsIF::EXECUTION_FINISHED; } case(SET_MAX_REBOOT_CNT): { @@ -498,7 +502,27 @@ switch (actionId) { } } +void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) { + std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE; + // Disable the reboot file mechanism + parseRebootFile(path, rebootFile); + if (tgtChip == xsc::CHIP_0) { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img00Lock = lock; + } else { + rebootFile.img01Lock = lock; + } + } else { + if (tgtCopy == xsc::COPY_0) { + rebootFile.img10Lock = lock; + } else { + rebootFile.img11Lock = lock; + } + } + rewriteRebootFile(rebootFile); +} + void CoreController::setCurrentBootCopy(xsc::Chip chip, xsc::Copy copy) { CURRENT_CHIP = chip; CURRENT_COPY = copy; -} \ No newline at end of file +} diff --git a/unittest/rebootLogic/src/CoreController.h b/unittest/rebootLogic/src/CoreController.h index e5b56595..737d550d 100644 --- a/unittest/rebootLogic/src/CoreController.h +++ b/unittest/rebootLogic/src/CoreController.h @@ -49,12 +49,9 @@ public: static xsc::Copy CURRENT_COPY; static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5; - static constexpr ActionId_t RESET_ALL_REBOOT_COUNTERS = 6; - static constexpr ActionId_t RESET_REBOOT_COUNTER_00 = 7; - static constexpr ActionId_t RESET_REBOOT_COUNTER_01 = 8; - static constexpr ActionId_t RESET_REBOOT_COUNTER_10 = 9; - static constexpr ActionId_t RESET_REBOOT_COUNTER_11 = 10; - static constexpr ActionId_t SET_MAX_REBOOT_CNT = 11; + static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6; + static constexpr ActionId_t SWITCH_IMG_LOCK = 7; + static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8; CoreController(); @@ -64,6 +61,7 @@ public: void performRebootFileHandling(bool recreateFile); void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip, xsc::Copy& tgtCopy); + void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy); void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy); bool parseRebootFile(std::string path, RebootFile& file); void rewriteRebootFile(RebootFile file); diff --git a/unittest/rebootLogic/src/main.cpp b/unittest/rebootLogic/src/main.cpp index 57470861..b24b4014 100644 --- a/unittest/rebootLogic/src/main.cpp +++ b/unittest/rebootLogic/src/main.cpp @@ -25,7 +25,7 @@ TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) { std::filesystem::create_directory(CONF_PATH); } CoreController ctrl; - + std::array cmdData = {}; SECTION ("Primary") { xsc_libnor_chip_t chip; @@ -99,7 +99,7 @@ TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) { // Flag was cleared when event was thrown REQUIRE(rf.bootFlag == false); REQUIRE(rf.lastChip == xsc::CHIP_0); - REQUIRE(rf.lastCopy == xsc::COPY_0); + REQUIRE(rf.lastCopy == xsc::COPY_1); ctrl.performRebootFileHandling(false); ctrl.performRebootFileHandling(false); ctrl.parseRebootFile(REBOOT_FILE, rf); @@ -169,26 +169,27 @@ TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) { CHECK(((info.p2 >> 16) & 0xFF) == 3); CHECK(((info.p2 >> 8) & 0xFF) == 3); CHECK((info.p2 & 0xFF) == 3); - // No reboot was triggered ctrl.parseRebootFile(REBOOT_FILE, rf); - REQUIRE(rf.img00Cnt == 3); + REQUIRE(rf.img00Cnt == 4); REQUIRE(rf.img01Cnt == 3); REQUIRE(rf.img10Cnt == 3); REQUIRE(rf.img11Cnt == 3); // Reset a specific reboot counter - ctrl.executeAction(CoreController::RESET_REBOOT_COUNTER_01, 0, nullptr, 0); + cmdData[0] = 0; + cmdData[1] = 1; + ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2); // Reboot to 0 0 again ctrl.performRebootFileHandling(false); ctrl.parseRebootFile(REBOOT_FILE, rf); REQUIRE(rf.enabled == 1); - REQUIRE(rf.img00Cnt == 4); + REQUIRE(rf.img00Cnt == 5); REQUIRE(rf.img01Cnt == 0); REQUIRE(rf.img10Cnt == 3); REQUIRE(rf.img11Cnt == 3); CHECK(CoreController::CURRENT_CHIP == xsc::CHIP_0); CHECK(CoreController::CURRENT_COPY == xsc::COPY_1); - ctrl.executeAction(CoreController::RESET_ALL_REBOOT_COUNTERS, 0, nullptr, 0); + ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, nullptr, 0); ctrl.parseRebootFile(REBOOT_FILE, rf); REQUIRE(rf.enabled == 1); REQUIRE(rf.img00Cnt == 0); @@ -248,15 +249,152 @@ TEST_CASE( "Core Controller Reboot File Handling", "[reboot-file]" ) { REQUIRE(rf.img11Cnt == 3); // Now reset all reboot counters manually - ctrl.executeAction(CoreController::RESET_REBOOT_COUNTER_00, 0, nullptr, 0); - ctrl.executeAction(CoreController::RESET_REBOOT_COUNTER_10, 0, nullptr, 0); - ctrl.executeAction(CoreController::RESET_REBOOT_COUNTER_11, 0, nullptr, 0); + cmdData[0] = 0; + cmdData[1] = 0; + ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2); + cmdData[0] = 1; + cmdData[1] = 0; + ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2); + cmdData[0] = 1; + cmdData[1] = 1; + ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2); ctrl.parseRebootFile(REBOOT_FILE, rf); REQUIRE(rf.enabled == 1); REQUIRE(rf.img00Cnt == 0); REQUIRE(rf.img01Cnt == 0); REQUIRE(rf.img10Cnt == 0); REQUIRE(rf.img11Cnt == 0); + + // Reset lock on 0 1 + cmdData[0] = false; + cmdData[1] = 0; + cmdData[2] = 1; + ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3); + CHECK(CoreController::CURRENT_CHIP == xsc::CHIP_0); + CHECK(CoreController::CURRENT_COPY == xsc::COPY_0); + ctrl.performRebootFileHandling(false); + ctrl.performRebootFileHandling(false); + ctrl.performRebootFileHandling(false); + // Now should be on 0 1 + ctrl.parseRebootFile(REBOOT_FILE, rf); + CHECK(CoreController::CURRENT_CHIP == xsc::CHIP_0); + CHECK(CoreController::CURRENT_COPY == xsc::COPY_1); + REQUIRE(rf.enabled == 1); + REQUIRE(rf.img00Cnt == 3); + REQUIRE(rf.img01Cnt == 0); + REQUIRE(rf.img10Cnt == 0); + REQUIRE(rf.img11Cnt == 0); + REQUIRE(rf.img00Lock == false); + REQUIRE(rf.img01Lock == false); + REQUIRE(rf.img10Lock == false); + REQUIRE(rf.img11Lock == false); + // Now simulate failure in kernel boot or reboot from ProASIC3 + ctrl.setCurrentBootCopy(xsc::CHIP_0, xsc::COPY_0); + ctrl.performRebootFileHandling(false); + // Image 0 1 should have been marked as invalid now. Reboot will be triggered + // on 1 0 instead of 0 1 because 0 1 is marked as locked + ctrl.parseRebootFile(REBOOT_FILE, rf); + REQUIRE(rf.enabled == 1); + REQUIRE(rf.img00Cnt == 4); + REQUIRE(rf.img01Cnt == 0); + REQUIRE(rf.img10Cnt == 0); + REQUIRE(rf.img11Cnt == 0); + REQUIRE(rf.img00Lock == false); + REQUIRE(rf.img01Lock == true); + REQUIRE(rf.img10Lock == false); + REQUIRE(rf.img11Lock == false); + ctrl.performRebootFileHandling(false); + ctrl.parseRebootFile(REBOOT_FILE, rf); + REQUIRE(rf.enabled == 1); + REQUIRE(rf.img00Cnt == 4); + REQUIRE(rf.img01Cnt == 0); + REQUIRE(rf.img10Cnt == 1); + REQUIRE(rf.img11Cnt == 0); + REQUIRE(rf.img00Lock == false); + REQUIRE(rf.img01Lock == true); + REQUIRE(rf.img10Lock == false); + REQUIRE(rf.img11Lock == false); + // Reset lock on 0 1 again + cmdData[0] = false; + cmdData[1] = 0; + cmdData[2] = 1; + ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3); + // Lock 1 1 manually + // Reset lock on 0 1 again + cmdData[0] = true; + cmdData[1] = 1; + cmdData[2] = 1; + ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3); + ctrl.performRebootFileHandling(false); + ctrl.performRebootFileHandling(false); + // Should be on 0 1 now + ctrl.performRebootFileHandling(false); + ctrl.parseRebootFile(REBOOT_FILE, rf); + REQUIRE(rf.enabled == 1); + REQUIRE(rf.img00Cnt == 4); + REQUIRE(rf.img01Cnt == 1); + REQUIRE(rf.img10Cnt == 3); + REQUIRE(rf.img11Cnt == 0); + REQUIRE(rf.img00Lock == false); + REQUIRE(rf.img01Lock == false); + REQUIRE(rf.img10Lock == false); + REQUIRE(rf.img11Lock == true); + // Lock everything except 0 0 + cmdData[0] = true; + cmdData[1] = 0; + cmdData[2] = 1; + ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3); + cmdData[0] = true; + cmdData[1] = 1; + cmdData[2] = 0; + ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3); + ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, nullptr, 0); + ctrl.parseRebootFile(REBOOT_FILE, rf); + REQUIRE(rf.enabled == 1); + REQUIRE(rf.img00Cnt == 0); + REQUIRE(rf.img01Cnt == 0); + REQUIRE(rf.img10Cnt == 0); + REQUIRE(rf.img11Cnt == 0); + REQUIRE(rf.img00Lock == false); + REQUIRE(rf.img01Lock == true); + REQUIRE(rf.img10Lock == true); + REQUIRE(rf.img11Lock == true); + // Switch to 0 0 + ctrl.setCurrentBootCopy(xsc::CHIP_0, xsc::COPY_0); + ctrl.performRebootFileHandling(false); + ctrl.performRebootFileHandling(false); + ctrl.performRebootFileHandling(false); + // Should still be on 0 0 + ctrl.performRebootFileHandling(false); + ctrl.parseRebootFile(REBOOT_FILE, rf); + REQUIRE(rf.enabled == 1); + REQUIRE(rf.img00Cnt == 4); + REQUIRE(rf.img01Cnt == 0); + REQUIRE(rf.img10Cnt == 0); + REQUIRE(rf.img11Cnt == 0); + REQUIRE(rf.img00Lock == false); + REQUIRE(rf.img01Lock == true); + REQUIRE(rf.img10Lock == true); + REQUIRE(rf.img11Lock == true); + // Unlock 1 0 + cmdData[0] = false; + cmdData[1] = 1; + cmdData[2] = 0; + ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3); + // Reboots to 1 0 now + ctrl.performRebootFileHandling(false); + ctrl.parseRebootFile(REBOOT_FILE, rf); + REQUIRE(rf.enabled == 1); + REQUIRE(rf.img00Cnt == 5); + REQUIRE(rf.img01Cnt == 0); + REQUIRE(rf.img10Cnt == 0); + REQUIRE(rf.img11Cnt == 0); + REQUIRE(rf.img00Lock == false); + REQUIRE(rf.img01Lock == true); + REQUIRE(rf.img10Lock == false); + REQUIRE(rf.img11Lock == true); + REQUIRE(CoreController::CURRENT_CHIP == xsc::CHIP_1); + REQUIRE(CoreController::CURRENT_COPY == xsc::COPY_0); } if(std::filesystem::exists(CONF_PATH)) { std::uintmax_t n = std::filesystem::remove_all(CONF_PATH);