diff --git a/src/platform/SaveBootReasonDFUSuit.h b/src/platform/SaveBootReasonDFUSuit.h new file mode 100644 index 0000000000..9d0f8e3ed4 --- /dev/null +++ b/src/platform/SaveBootReasonDFUSuit.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef NRF_SAVE_BOOT_REASON_H__ +#define NRF_SAVE_BOOT_REASON_H__ + +inline int SoftwareBootReasonSUIT __attribute__((section(".noinit"))); + +inline int getSoftwareRebootReasonSUIT() +{ + return SoftwareBootReasonSUIT; +} + +inline void setSoftwareRebootReasonSUIT(int reason) +{ + SoftwareBootReasonSUIT = reason; +} + +#endif \ No newline at end of file diff --git a/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp b/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp index 3c0a106aea..98dcd8b8a1 100644 --- a/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp +++ b/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp @@ -52,6 +52,11 @@ const size_t kMaxHeapSize = CONFIG_SRAM_BASE_ADDRESS + KB(CONFIG_SRAM_SIZE) - PO #endif +#ifdef CONFIG_SOC_SERIES_NRF54HX +#include +#include +#endif + namespace chip { namespace DeviceLayer { @@ -59,9 +64,54 @@ namespace { BootReasonType DetermineBootReason() { -#ifdef CONFIG_HWINFO + +#if defined(CONFIG_SOC_SERIES_NRF54HX) || defined(CONFIG_HWINFO) uint32_t reason; +#endif + +#ifdef CONFIG_SOC_SERIES_NRF54HX + + bool isSoftwareBootReasonSUITInitialized = false; + if (!isSoftwareBootReasonSUITInitialized) + { + setSoftwareRebootReasonSUIT(0); + isSoftwareBootReasonSUITInitialized = true; + } + + reason = nrf_resetinfo_resetreas_global_get(NRF_RESETINFO); + + if (reason == RESETINFO_RESETREAS_GLOBAL_ResetValue) + { + return BootReasonType::kSoftwareReset; + } + + if (reason & RESETINFO_RESETREAS_GLOBAL_RESETPORONLY_Msk) + { + return BootReasonType::kBrownOutReset; + } + if (reason & RESETINFO_RESETREAS_GLOBAL_DOG_Msk) + { + return BootReasonType::kHardwareWatchdogReset; + } + + if ((reason & (RESETINFO_RESETREAS_GLOBAL_RESETPIN_Msk | RESETINFO_RESETREAS_GLOBAL_RESETPOR_Msk)) == + (RESETINFO_RESETREAS_GLOBAL_RESETPIN_Msk | RESETINFO_RESETREAS_GLOBAL_RESETPOR_Msk)) + { + return BootReasonType::kPowerOnReboot; + } + + if ((reason & (RESETINFO_RESETREAS_GLOBAL_RESETPOR_Msk | RESETINFO_RESETREAS_GLOBAL_SECSREQ_Msk)) == + (RESETINFO_RESETREAS_GLOBAL_RESETPOR_Msk | RESETINFO_RESETREAS_GLOBAL_SECSREQ_Msk)) + { + if (GetSoftwareRebootReason() == SoftwareRebootReason::kSoftwareUpdate) + { + return BootReasonType::kSoftwareUpdateCompleted; + } + } +#endif + +#ifdef CONFIG_HWINFO if (hwinfo_get_reset_cause(&reason) != 0) { return BootReasonType::kUnspecified; diff --git a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp index 2274fefbc3..c755b15690 100644 --- a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp +++ b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp @@ -46,6 +46,10 @@ #include #include +#ifdef CONFIG_SOC_SERIES_NRF54HX +#include +#endif + namespace chip { namespace { #ifdef CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE @@ -182,6 +186,7 @@ CHIP_ERROR OTAImageProcessorImpl::Apply() PlatformMgr().HandleServerShuttingDown(); k_msleep(CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS); #ifdef CONFIG_DFU_TARGET_SUIT + SetSoftwareRebootReason(SoftwareRebootReason::kSoftwareUpdate); dfu_target_suit_reboot(); #else Reboot(SoftwareRebootReason::kSoftwareUpdate); diff --git a/src/platform/nrfconnect/Reboot.cpp b/src/platform/nrfconnect/Reboot.cpp index 47bff8c185..0d25af9f17 100644 --- a/src/platform/nrfconnect/Reboot.cpp +++ b/src/platform/nrfconnect/Reboot.cpp @@ -25,10 +25,12 @@ #include #endif +#include + namespace chip { namespace DeviceLayer { -#if defined(CONFIG_ARCH_POSIX) || defined(CONFIG_SOC_SERIES_NRF54HX) +#if defined(CONFIG_ARCH_POSIX) void Reboot(SoftwareRebootReason reason) { @@ -40,7 +42,7 @@ SoftwareRebootReason GetSoftwareRebootReason() return SoftwareRebootReason::kOther; } -#else +#elif !(defined(CONFIG_SOC_SERIES_NRF54HX)) using RetainedReason = decltype(nrf_power_gpregret_get(NRF_POWER, 0)); @@ -73,6 +75,35 @@ SoftwareRebootReason GetSoftwareRebootReason() } } +#else + +using RetainedReason = decltype(getSoftwareRebootReasonSUIT()); + +constexpr RetainedReason EncodeReason(SoftwareRebootReason reason) +{ + // Set MSB to avoid collission with Zephyr's pre-defined reboot reasons. + constexpr RetainedReason kCustomReasonFlag = 0x80; + + return static_cast(reason) | kCustomReasonFlag; +} + +void SetSoftwareRebootReason(SoftwareRebootReason reason) +{ + const RetainedReason retainedReason = EncodeReason(reason); + setSoftwareRebootReasonSUIT(retainedReason); +} + +SoftwareRebootReason GetSoftwareRebootReason() +{ + switch (getSoftwareRebootReasonSUIT()) + { + case EncodeReason(SoftwareRebootReason::kSoftwareUpdate): + setSoftwareRebootReasonSUIT(0); + return SoftwareRebootReason::kSoftwareUpdate; + default: + return SoftwareRebootReason::kOther; + } +} #endif } // namespace DeviceLayer diff --git a/src/platform/nrfconnect/Reboot.h b/src/platform/nrfconnect/Reboot.h index 09f5493ebf..b1465bd0c5 100644 --- a/src/platform/nrfconnect/Reboot.h +++ b/src/platform/nrfconnect/Reboot.h @@ -30,6 +30,7 @@ enum class SoftwareRebootReason : uint8_t [[noreturn]] void Reboot(SoftwareRebootReason reason); SoftwareRebootReason GetSoftwareRebootReason(); +void SetSoftwareRebootReason(SoftwareRebootReason reason); } // namespace DeviceLayer } // namespace chip