Загрузка данных


#define IPC_MAGIC_VALID   0x4D375542U

void tcm_bootloader_main(void) {
    volatile struct rproc_update_ipc *ipc = (struct rproc_update_ipc *)M7_LOCAL_IPC_BASE;
    
    /* 1. Инициализация при холодном старте: полностью очищаем структуру, 
          чтобы стереть возможный мусор в DTCM */
    memset((void *)ipc, 0, offsetof(struct rproc_update_ipc, buffer));
    
    /* 2. Прописываем валидный Magic Word. Теперь U-Boot, прочитав память, 
          поймет, что загрузчик запущен, работает и готов к общению */
    ipc->magic_word = IPC_MAGIC_VALID;
    ipc->command = 0;
    ipc->status = STAT_IDLE;
    
    uint32_t current_ddr_ptr = 0x80000000U;
    uint32_t calculated_total_crc = 0x00000000U;

    while(1) {
        /* Безопасное чтение полей */
        uint32_t current_magic = ipc->magic_word;
        uint32_t cmd = ipc->command;

        /* 3. КРИТИЧЕСКАЯ ПРОВЕРКА: Если в памяти мусор или U-Boot еще не 
              инициализировал сессию — игнорируем любые команды */
        if (current_magic != IPC_MAGIC_VALID) {
            /* Ошибка целостности памяти IPC. Выставляем статус ошибки, 
               если это возможно, и засыпаем */
            ipc->status = STAT_ERROR;
            __WFI();
            continue; 
        }

        if (cmd == CMD_DATA_READY) {
            ipc->status = STAT_BUSY;
            __DSB();
            
            memcpy((void *)current_ddr_ptr, (const void *)ipc->buffer, ipc->chunk_size);
            calculated_total_crc = calculate_crc32(calculated_total_crc, (const uint8_t *)ipc->buffer, ipc->chunk_size);
            current_ddr_ptr += ipc->chunk_size;
            
            __DSB(); __ISB();
            ipc->command = 0;
            ipc->status = STAT_ACK;
            __DSB();
        } 
        else if (cmd == CMD_VERIFY_CRC) {
            // ... (логика верификации CRC32 и перехода, разработанная ранее) ...
        }
        else {
            /* Если команд нет, спокойно спим до прихода прерывания от U-Boot */
            __WFI(); 
        }
    }
}