/**************************************************************************** * * Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. * * This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT * be copied by any method or incorporated into another program without * the express written consent of Aerospace C.Power. This Information or any portion * thereof remains the property of Aerospace C.Power. The Information contained herein * is believed to be accurate and Aerospace C.Power assumes no responsibility or * liability for its use in any way and conveys no license or title under * any patent or copyright and makes no representation or warranty that this * Information is free from patent or copyright infringement. * * ****************************************************************************/ /* os shim includes */ #include #include "os_types.h" #include "iot_system_api.h" #include "iot_config.h" #include "iot_irq.h" #include "iot_wdg.h" #include "iot_clock.h" #include "ledc.h" #include "efuse.h" #include "iot_gptmr.h" #include "iot_system.h" #include "iot_power_mgmt.h" #include "iot_io.h" #include "iot_board.h" #include "os_mem.h" #include "cpu.h" #include "os_task.h" #include "platform.h" #include "encoding.h" #include "sec_glb.h" #include "ahb.h" #include "iot_spinlock.h" #include "intc.h" #include "clk.h" ////////////////////////////////////////////// typedef void (*func_ptr)(void); extern func_ptr __init_array_start[0]; extern func_ptr __init_array_end[0]; /** * @brief Execute initialization routines referenced in .init_array section * * @return N/A */ void __do_init_array_aux(void) { for (func_ptr *func = __init_array_start; func < __init_array_end; func++) { (*func)(); } } /* What a constructor function pointer looks like */ typedef void (*CtorFuncPtr)(void); /* Constructor function pointer list is generated by the linker script. */ extern CtorFuncPtr __CTOR_LIST__[]; extern CtorFuncPtr __CTOR_END__[]; /** * * @brief Invoke all C++ style global object constructors * * This routine is invoked by the kernel prior to the execution of the * application's main(). */ void __do_global_ctors_aux(void) { unsigned int nCtors; nCtors = (unsigned int)__CTOR_LIST__[0]; while (nCtors >= 1) { __CTOR_LIST__[nCtors--](); } } ////////////////////////////////////////////// extern void def_trap_entry(); extern void intc_handler(uint32_t cpu); extern void trigger_zero_addr_access_detect(); extern exception_cb_t exception; extern void ahb_core0_enable(); static uint32_t g_exception_nesting = 0; extern uint8_t g_app_reg_done; uintptr_t IRAM_ATTR handle_trap(uintptr_t mcause, uintptr_t epc, saved_registers *reg) { if ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT) { intc_handler(cpu_get_mhartid()); } else { uint8_t toggle = 0; g_exception_nesting++; if( g_exception_nesting == 1) { #if IOT_EXCEPTION_DEBUG iot_led_gpio_on(IOT_PLC_TX_LED); iot_led_gpio_off(IOT_PLC_RX_LED); iot_led_gpio_on(IOT_RS485_LED); iot_led_gpio_off(IOT_PLC_TR_LED); #endif exception.handler(mcause, epc, reg); #if IOT_FULL_DUMP_DEBUG exception.full_dump(); #endif #if IOT_EXCEPTION_DEBUG wdg_deinit(HAL_WDG_CPU_0); #if DUAL_WDG_ON_ONE_CPU_ENABLE wdg_deinit(HAL_WDG_CPU_1); #endif iot_power_mgmt_stop_charge(); #else wdg_cpu_reset(HAL_WDG_CPU_0); #endif } else { #if IOT_EXCEPTION_DEBUG iot_led_gpio_on(IOT_PLC_TX_LED); iot_led_gpio_off(IOT_PLC_RX_LED); iot_led_gpio_on(IOT_RS485_LED); iot_led_gpio_off(IOT_PLC_TR_LED); #endif #if IOT_EXCEPTION_DEBUG wdg_deinit(HAL_WDG_CPU_0); #if DUAL_WDG_ON_ONE_CPU_ENABLE wdg_deinit(HAL_WDG_CPU_1); #endif iot_power_mgmt_stop_charge(); #else wdg_cpu_reset(HAL_WDG_CPU_0); #endif } while (1) { volatile uint32_t i = 0; if (g_exception_nesting == 1) { /* 1s delay */ for(i = 0; i < 10000000; i++); } else { /* 5s delay */ for(i = 0; i < 50000000; i++); } if (!toggle) { iot_led_gpio_on(IOT_PLC_RX_LED); iot_led_gpio_on(IOT_PLC_TR_LED); } else { iot_led_gpio_off(IOT_PLC_RX_LED); iot_led_gpio_off(IOT_PLC_TR_LED); } toggle = !toggle; } } return epc; } #if RISCV_SMP_ENABLE void core2_init() { cpu_early_init(); intc_init(cpu_get_mhartid()); } int app_core2_start() { ahb_core2_set_start((uint32_t)&(_start)); //boot init is not necessary, so just jump to app init ahb_core2_enable(); ahb_core2_reset(); return 0; } int get_main_core_status() { return g_app_reg_done; } void main_2() { core2_init(); while(1) { __asm volatile ("nop"); if( get_main_core_status()) break; } os_start_scheduler(); } #endif #if RUN_ON_CPU_1 extern void _start_2(); static const uint8_t sp_applet_bin[] = { #include "sp_applet.txt" }; #define SP_APPLET_WAIT_COUNT 10 #define SP_APPLET_WAIT_UNIT_TIME 500 int sp_applet_start() { uint8_t *dst = (uint8_t *)_start_2; uint8_t *src = (uint8_t *)sp_applet_bin; uint32_t len = sizeof(sp_applet_bin); volatile int delay_cnt = SP_APPLET_WAIT_COUNT; /* clean buffer of g_cpu1_state. */ os_mem_set(&g_cpu1_state, 0, sizeof(g_cpu1_state)); sec_glb_core1_disable(); os_mem_cpy(dst, src, len); sec_glb_core1_set_start((uint32_t)_start_2); sec_glb_core1_reset(1); sec_glb_core1_enable(); /* wait until cpu1 running. */ while(delay_cnt--) { if (CPU_FLAG_RUNNING == g_cpu1_state.flags) { break; } iot_delay_us_cpu_cycle(SP_APPLET_WAIT_UNIT_TIME); } return 0; } #else int sp_applet_start() { g_cpu1_state.flags = CPU_FLAG_INVALID; return 0; } #endif void _init() { /* get and set reset reason */ iot_board_reset_get_and_set(); /* sp's applet load */ sp_applet_start(); // disable cpu1 branch prediction sec_glb_core1_branch_pred_enable(0); //disable cpu0, cpu2 instruction master access to dmc cache slave sec_glb_mtx_mst_acc(19, 14, 0); sec_glb_mtx_mst_acc(19, 16, 0); sec_glb_mtx_mst_acc(20, 14, 0); sec_glb_mtx_mst_acc(20, 16, 0); write_csr(mtvec, &def_trap_entry); clear_csr(mie, MIP_MEIP); clear_csr(mie, MIP_MTIP); iot_interrupt_init(cpu_get_mhartid()); set_csr(mie, MIP_MEIP); // Enable interrupts in general. set_csr(mstatus, MSTATUS_MIE); //iot_gp_timer_init(); clk_core_freq_set(CPU_FREQ_150M); // Enable trigger registers to detech zero address access trigger_zero_addr_access_detect(); /* init global constructor for C++ */ __do_global_ctors_aux(); __do_init_array_aux(); /* enable log print */ iot_print_config(true); /* spinlock init */ iot_spinlock_init(); #if RISCV_SMP_ENABLE app_core2_start(); #endif } void _fini() { }