static int32_t MONITOR_CmdM7Reboot(int32_t argc, const char * const argv[])
{
if (argc < 1)
{
printf(" Usage: m7_reboot <hex_boot_vector>\n");
return SM_ERR_INVALID_PARAMETERS;
}
/* 1. Парсим вектор старта (например, 0x80000000) */
uint32_t boot_vector = (uint32_t) strtoul(argv[0], NULL, 16);
/* ID логической машины для M7 (LM1).
* Так как А55 у вас управляется через 2U, М7 гарантированно сидит на 1U */
uint32_t m7_lm_id = 1U;
printf("M33 MONITOR: Hard resetting M7 (LM%u) to vector: 0x%08X\n", m7_lm_id, boot_vector);
int32_t status = SM_ERR_SUCCESS;
lmm_rst_rec_t rstRec = {0}; // Пустая запись причины сброса
/* 2. ШТАТНОЕ ВЫКЛЮЧЕНИЕ: Принудительно гасим логическую машину М7.
* Передаем параметры согласно сигнатуре вашей функции:
* lmId = 0U (вызывает M33/System)
* agentId = 0U (вызывает System)
* shutdownLm = m7_lm_id (целевая машина)
* graceful = false (жесткое выключение без ожидания согласия от ОС на М7)
* shutdownRec = &rstRec */
status = LMM_SystemLmShutdown(0U, 0U, m7_lm_id, false, &rstRec);
if (status != SM_ERR_SUCCESS)
{
printf("M33 MONITOR: LM Shutdown notification bypass or idle (status: %d)\n", status);
}
/* 3. СБРОС ИНТЕРФЕЙСОВ: Очищаем RPC каналы связи */
(void) LMM_RpcReset(m7_lm_id);
/* 4. СМЕНА ВЕКТОРА: Теперь, когда ядро остановлено, а автомат перешел в LMM_STATE_LM_OFF,
* безопасно записываем новый адрес старта в аппаратные регистры SRC */
status = DEV_SM_CpuResetVectorSet(m7_lm_id, boot_vector, true);
if (status != SM_ERR_SUCCESS)
{
printf("M33 MONITOR: Vector set failed! Status: %d\n", status);
return status;
}
/* 5. ЧИСТЫЙ СТАРТ: Запускаем официальный конвейер загрузки через SWI.
* Поскольку машина находится в состоянии OFF, планировщик честно вызовет LMM_DoBoot(),
* с нуля откроет доступы к DDR/TCM на уровне TRDC и запустит М7 по новому вектору. */
status = LMM_Boot_core(m7_lm_id);
if (status == SM_ERR_SUCCESS)
{
printf("M33 MONITOR: M7 Boot pipeline successfully triggered.\n");
}
else
{
printf("M33 MONITOR: LMM Boot failed! Status: %d\n", status);
}
return status;
}