<commit_before>#include <algorithm>
#include <bitset>
#include "base/crc.h"
#include "bsp/bsp_uart.h"
#include "main.hpp"
#include "program_flash/boot_table.hpp"

static void CheckBootSettings()
{
    auto settingsValid = Bootloader.Settings.CheckMagicNumber();

    if (settingsValid)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Boot settings tagged with magic number\n");
    }
    else
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[FAIL] Boot settings tagged with magic number\n");
    }

    auto primaryBootSlots = Bootloader.Settings.BootSlots();

    if (primaryBootSlots == 0b111)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Primary boot slots set to 0,1,2\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Primary boot slots set to 0,1,2 (actual: 0x%X)\n", primaryBootSlots);
    }

    auto failsafeBootSlots = Bootloader.Settings.FailsafeBootSlots();

    if (failsafeBootSlots == 0b111000)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Failsafe boot slots set to 3,4,5\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Failsafe boot slots set to 3,4,5 (actual: 0x%X)\n", failsafeBootSlots);
    }

    auto bootCounter = Bootloader.Settings.BootCounter();

    if (bootCounter == 0)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Boot counter set to 0\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Boot counter set to 0 (actual: %ld)\n", bootCounter);
    }

    auto lastConfirmedBootCounter = Bootloader.Settings.LastConfirmedBootCounter();

    if (lastConfirmedBootCounter == 0)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Last confirmed boot counter set to 0\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Last confirmed boot counter set to 0 (actual: %ld)\n", lastConfirmedBootCounter);
    }
}

static std::array<uint8_t, 3> DecodeSlotsMask(std::uint8_t mask)
{
    std::array<uint8_t, 3> result{0, 0, 0};
    std::bitset<program_flash::BootTable::EntriesCount> slots(mask);

    auto j = 0;
    for (std::uint8_t i = 0; i < program_flash::BootTable::EntriesCount; i++)
    {
        if (slots[i])
        {
            result[j] = i;
            j++;
        }
        if (j == 3)
            break;
    }

    return result;
}

static void CheckBootSlots()
{
    std::array<bool, 6> slotValid;
    std::array<std::uint16_t, 6> crc;

    for (auto i = 0; i < program_flash::BootTable::EntriesCount; i++)
    {
        slotValid[i] = false;
        auto entry = Bootloader.BootTable.Entry(i);

        if (!entry.IsValid())
        {
            BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Boot slot %d: Not valid\n", i);
            continue;
        }
        else
        {
            BSP_UART_Printf<40>(BSP_UART_DEBUG, "[OK  ] Boot slot %d: Valid\n", i);
        }

        auto expectedCrc = entry.Crc();
        auto actualCrc = entry.CalculateCrc();

        if (expectedCrc != actualCrc)
        {
            BSP_UART_Printf<40>(
                BSP_UART_DEBUG, "[FAIL] Boot slot %d: CRC mismatch (expected: 0x%X, actual: 0x%X)\n", i, expectedCrc, actualCrc);
            continue;
        }
        else
        {
            BSP_UART_Printf<40>(BSP_UART_DEBUG, "[OK  ] Boot slot %d: CRC match (0x%X)\n", i, expectedCrc);
        }

        crc[i] = actualCrc;
        slotValid[i] = true;
    }

    auto slots = DecodeSlotsMask(Bootloader.Settings.BootSlots());

    auto allValid = slotValid[slots[0]] && slotValid[slots[1]] && slotValid[slots[2]];
    auto crcMatch = (crc[slots[0]] == crc[slots[1]]) && (crc[slots[1]] == crc[slots[2]]);

    if (allValid && crcMatch)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Primary boot slots valid & CRC match\n");<commit_msg>[boot] Fix boot loader hang in health check on boot slot CRC mismatch.<commit_after>#include <algorithm>
#include <bitset>
#include "base/crc.h"
#include "bsp/bsp_uart.h"
#include "main.hpp"
#include "program_flash/boot_table.hpp"

static void CheckBootSettings()
{
    auto settingsValid = Bootloader.Settings.CheckMagicNumber();

    if (settingsValid)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Boot settings tagged with magic number\n");
    }
    else
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[FAIL] Boot settings tagged with magic number\n");
    }

    auto primaryBootSlots = Bootloader.Settings.BootSlots();

    if (primaryBootSlots == 0b111)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Primary boot slots set to 0,1,2\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Primary boot slots set to 0,1,2 (actual: 0x%X)\n", primaryBootSlots);
    }

    auto failsafeBootSlots = Bootloader.Settings.FailsafeBootSlots();

    if (failsafeBootSlots == 0b111000)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Failsafe boot slots set to 3,4,5\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Failsafe boot slots set to 3,4,5 (actual: 0x%X)\n", failsafeBootSlots);
    }

    auto bootCounter = Bootloader.Settings.BootCounter();

    if (bootCounter == 0)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Boot counter set to 0\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Boot counter set to 0 (actual: %ld)\n", bootCounter);
    }

    auto lastConfirmedBootCounter = Bootloader.Settings.LastConfirmedBootCounter();

    if (lastConfirmedBootCounter == 0)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Last confirmed boot counter set to 0\n");
    }
    else
    {
        BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Last confirmed boot counter set to 0 (actual: %ld)\n", lastConfirmedBootCounter);
    }
}

static std::array<uint8_t, 3> DecodeSlotsMask(std::uint8_t mask)
{
    std::array<uint8_t, 3> result{0, 0, 0};
    std::bitset<program_flash::BootTable::EntriesCount> slots(mask);

    auto j = 0;
    for (std::uint8_t i = 0; i < program_flash::BootTable::EntriesCount; i++)
    {
        if (slots[i])
        {
            result[j] = i;
            j++;
        }
        if (j == 3)
            break;
    }

    return result;
}

static void CheckBootSlots()
{
    std::array<bool, 6> slotValid;
    std::array<std::uint16_t, 6> crc;

    for (auto i = 0; i < program_flash::BootTable::EntriesCount; i++)
    {
        slotValid[i] = false;
        auto entry = Bootloader.BootTable.Entry(i);

        if (!entry.IsValid())
        {
            BSP_UART_Printf<40>(BSP_UART_DEBUG, "[FAIL] Boot slot %d: Not valid\n", i);
            continue;
        }
        else
        {
            BSP_UART_Printf<40>(BSP_UART_DEBUG, "[OK  ] Boot slot %d: Valid\n", i);
        }

        auto expectedCrc = entry.Crc();
        auto actualCrc = entry.CalculateCrc();

        if (expectedCrc != actualCrc)
        {
            BSP_UART_Printf<80>(
                BSP_UART_DEBUG, "[FAIL] Boot slot %d: CRC mismatch (expected: 0x%X, actual: 0x%X)\n", i, expectedCrc, actualCrc);
            continue;
        }
        else
        {
            BSP_UART_Printf<40>(BSP_UART_DEBUG, "[OK  ] Boot slot %d: CRC match (0x%X)\n", i, expectedCrc);
        }

        crc[i] = actualCrc;
        slotValid[i] = true;
    }

    auto slots = DecodeSlotsMask(Bootloader.Settings.BootSlots());

    auto allValid = slotValid[slots[0]] && slotValid[slots[1]] && slotValid[slots[2]];
    auto crcMatch = (crc[slots[0]] == crc[slots[1]]) && (crc[slots[1]] == crc[slots[2]]);

    if (allValid && crcMatch)
    {
        BSP_UART_Puts(BSP_UART_DEBUG, "[OK  ] Primary boot slots valid & CRC match\n");
{'fraction_non_alphanumeric': 0.13543452459448768, 'fraction_numerical': 0.01951734142160095, 'mean_word_length': 2.6779825412221143, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4975149', 'n_tokens_mistral': 2884, 'n_tokens_neox': 2693, 'n_words': 569}