#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();
}
}
}