401 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			401 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | 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 "os_types.h"
 | ||
|  | #include "os_task.h"
 | ||
|  | #include "os_utils.h"
 | ||
|  | 
 | ||
|  | /* common includes */ | ||
|  | #include "iot_io.h"
 | ||
|  | #include "iot_bitops.h"
 | ||
|  | #include "iot_pkt.h"
 | ||
|  | #include "iot_ipc.h"
 | ||
|  | #include "iot_dbglog_api.h"
 | ||
|  | #include "iot_config.h"
 | ||
|  | #include "iot_version.h"
 | ||
|  | #include "iot_app.h"
 | ||
|  | #include "iot_share_task.h"
 | ||
|  | #include "iot_socket.h"
 | ||
|  | #include "iot_img_hdr.h"
 | ||
|  | 
 | ||
|  | /* pib includes */ | ||
|  | #include "iot_pib.h"
 | ||
|  | #include "iot_oem.h"
 | ||
|  | 
 | ||
|  | /* driver includes */ | ||
|  | #include "apb.h"
 | ||
|  | #include "ahb.h"
 | ||
|  | #include "efuse.h"
 | ||
|  | #include "cpu.h"
 | ||
|  | #include "wdt_hw.h"
 | ||
|  | #include "flash.h"
 | ||
|  | #include "decomp.h"
 | ||
|  | #include "iot_mem_org.h"
 | ||
|  | #include "iot_system.h"
 | ||
|  | #include "iot_clock.h"
 | ||
|  | #include "iot_uart.h"
 | ||
|  | #include "iot_wdg.h"
 | ||
|  | #include "iot_mtd.h"
 | ||
|  | #include "iot_crypto.h"
 | ||
|  | #include "iot_board.h"
 | ||
|  | #include "iot_led.h"
 | ||
|  | #include "iot_log_api.h"
 | ||
|  | #include "upgrade.h"
 | ||
|  | #include "snapshot.h"
 | ||
|  | #include "iot_gptmr.h"
 | ||
|  | #include "iot_power_mgmt.h"
 | ||
|  | #include "iot_energe_meter.h"
 | ||
|  | #include "iot_rtc.h"
 | ||
|  | #include "iot_dma.h"
 | ||
|  | #include "iot_eth.h"
 | ||
|  | #include "iot_uart_h.h"
 | ||
|  | 
 | ||
|  | /* debug includes*/ | ||
|  | #include "dbg_io.h"
 | ||
|  | #include "iot_dbglog.h"
 | ||
|  | 
 | ||
|  | #include "iot_cal_data.h"
 | ||
|  | #include "platform.h"
 | ||
|  | #include "iot_lwip.h"
 | ||
|  | #include "iot_upgrade_api.h"
 | ||
|  | #include "iot_busmon.h"
 | ||
|  | #include "iot_gpio_api.h"
 | ||
|  | #include "spi_flash.h"
 | ||
|  | #include "iot_oem_api.h"
 | ||
|  | #include "iot_plc_led.h"
 | ||
|  | #include "iot_plc_pm.h"
 | ||
|  | 
 | ||
|  | uint8_t g_app_reg_done = 0; | ||
|  | extern void iot_board_info_init(); | ||
|  | 
 | ||
|  | #if RUN_IN_PSRAM
 | ||
|  | /* Just use bt pkt config, TODO. */ | ||
|  | #define CUS_SMALL_BUF_SIZE  256
 | ||
|  | #define CUS_SMALL_BUF_COUNT 32
 | ||
|  | 
 | ||
|  | #define CUS_SHORT_BUF_SIZE  512
 | ||
|  | #define CUS_SHORT_BUF_COUNT 16
 | ||
|  | 
 | ||
|  | #define CUS_LONG_BUF_SIZE   (1024 + 46)
 | ||
|  | #define CUS_LONG_BUF_COUNT  8
 | ||
|  | 
 | ||
|  | #define CUS_LARGE_BUF_SIZE  (2048 + 92)
 | ||
|  | #define CUS_LARGE_BUF_COUNT 8
 | ||
|  | 
 | ||
|  | #else
 | ||
|  | 
 | ||
|  | #define CUS_SMALL_BUF_SIZE  256
 | ||
|  | #define CUS_SMALL_BUF_COUNT 16
 | ||
|  | 
 | ||
|  | #define CUS_SHORT_BUF_SIZE  512
 | ||
|  | #define CUS_SHORT_BUF_COUNT 18
 | ||
|  | 
 | ||
|  | #define CUS_LONG_BUF_SIZE   (1024 + 46)
 | ||
|  | #define CUS_LONG_BUF_COUNT  4
 | ||
|  | 
 | ||
|  | #define CUS_LARGE_BUF_SIZE  (2048 + 92)
 | ||
|  | #define CUS_LARGE_BUF_COUNT 1
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | const iot_pkt_config_t g_pkt_config = | ||
|  | { | ||
|  |     { | ||
|  |         { | ||
|  |             CUS_SMALL_BUF_SIZE, | ||
|  |             CUS_SMALL_BUF_COUNT, | ||
|  |             PKT_OWNER_ALL, | ||
|  |         }, | ||
|  |         /* reserve IOT_SG_UPGRADE_BLOCK block for upgrading */ | ||
|  |         { | ||
|  |             CUS_SHORT_BUF_SIZE, | ||
|  |             (CUS_SHORT_BUF_COUNT + IOT_SG_UPGRADE_BLOCK_CNT), | ||
|  |             PKT_OWNER_ALL, | ||
|  |         }, | ||
|  |         { | ||
|  |             CUS_LONG_BUF_SIZE, | ||
|  |             CUS_LONG_BUF_COUNT, | ||
|  |             PKT_OWNER_ALL, | ||
|  |         }, | ||
|  |         { | ||
|  |             CUS_LARGE_BUF_SIZE, | ||
|  |             CUS_LARGE_BUF_COUNT + DBGLOG_MAX_BUFFER_CNT, | ||
|  |             PKT_OWNER_ALL, | ||
|  |         }, | ||
|  |         { | ||
|  |             0, | ||
|  |             0, | ||
|  |             PKT_OWNER_ALL, | ||
|  |         }, | ||
|  |         { | ||
|  |             0, | ||
|  |             0, | ||
|  |             PKT_OWNER_ALL, | ||
|  |         }, | ||
|  |         { | ||
|  |             0, | ||
|  |             0, | ||
|  |             PKT_OWNER_NONE, | ||
|  |         }, | ||
|  |         { | ||
|  |             0, | ||
|  |             0, | ||
|  |             PKT_OWNER_NONE, | ||
|  |         }, | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | /* plc mission mode initialization second half */ | ||
|  | static void plc_mm_init2(iot_msg_entry_t *entry) | ||
|  | { | ||
|  |     uint8_t ret; | ||
|  |     (void)entry; | ||
|  |     (void)ret; | ||
|  | 
 | ||
|  |     extern os_task_h _init_handle; | ||
|  |     os_delete_task(_init_handle); | ||
|  |     os_delay(100); | ||
|  | 
 | ||
|  |     /* launch applications */ | ||
|  |     ret = iot_app_start(); | ||
|  | 
 | ||
|  |     g_app_reg_done = 1; | ||
|  | } | ||
|  | 
 | ||
|  | static void plc_mm_init2_cancel(iot_msg_entry_t *entry) | ||
|  | { | ||
|  |     IOT_ASSERT(0); | ||
|  | } | ||
|  | 
 | ||
|  | void iot_mode_set(int fw_mode) | ||
|  | { | ||
|  |     (void)fw_mode; | ||
|  | } | ||
|  | 
 | ||
|  | void iot_hw_init() | ||
|  | { | ||
|  |     iot_board_info_init(); | ||
|  | 
 | ||
|  |     iot_crypto_init(); | ||
|  | 
 | ||
|  |     /*resource initializations;*/ | ||
|  |     mtd_device_init(0); | ||
|  | 
 | ||
|  |     /* call efuse_init() to enable efuse clk, but rom is done that */ | ||
|  | 
 | ||
|  |     /* init oem module load oem cfg from file */ | ||
|  | #if (PLC_SUPPORT_CCO_ROLE)
 | ||
|  |     iot_oem_init(1); | ||
|  | #else
 | ||
|  |     iot_oem_init(0); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if (IOT_FLASH_BUILD == 1)
 | ||
|  |     /* board info config*/ | ||
|  |     iot_board_cfg_init(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     system_clock_init(); | ||
|  |     system_uart_init(); | ||
|  | 
 | ||
|  | #if (!defined(DISABLE_PRINT)) || (HW_PLATFORM == HW_PLATFORM_FPGA)
 | ||
|  |     dbg_uart_init_port(iot_board_get_uart(UART_PRINT), 1); | ||
|  |     dbg_uart_stage1_init(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if (IOT_FLASH_BUILD == 1)
 | ||
|  |     iot_board_cfg_dump(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /*platform intialization*/ | ||
|  |     platform_init(); | ||
|  | 
 | ||
|  |     iot_wdg_enable(); | ||
|  | } | ||
|  | 
 | ||
|  | void iot_sub_system_init() | ||
|  | { | ||
|  |     /* init common modules */ | ||
|  |     iot_bitops_init(); | ||
|  | 
 | ||
|  |     /* init os related modules and utilities */ | ||
|  |     os_utils_init(); | ||
|  | 
 | ||
|  |     /* rtc init */ | ||
|  |     iot_rtc_init(); | ||
|  | 
 | ||
|  |     /* init pkt module */ | ||
|  |     iot_pkt_init(&g_pkt_config); | ||
|  | 
 | ||
|  |     /* init shared background task. It shall be ahead of pib init. */ | ||
|  |     iot_share_task_init(); | ||
|  | 
 | ||
|  |     /* init dbglog module */ | ||
|  |     iot_dbglog_init(); | ||
|  | 
 | ||
|  |     /* init dma module */ | ||
|  |     iot_dma_init(); | ||
|  | 
 | ||
|  |     /* init gpio module */ | ||
|  |     iot_gpio_module_init(); | ||
|  | 
 | ||
|  |     /* init uart module */ | ||
|  |     iot_uart_init(0); | ||
|  | 
 | ||
|  |     /* init ipc module */ | ||
|  |     iot_ipc_init(); | ||
|  | } | ||
|  | 
 | ||
|  | /* plc mission mode initialization first half */ | ||
|  | void proto_mm_init() | ||
|  | { | ||
|  | 
 | ||
|  | #if IOT_ETH_ENABLE
 | ||
|  |     iot_eth_init(); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* init tcpip stack */ | ||
|  |     iot_lwip_init(); | ||
|  | 
 | ||
|  |     /* init plc led module */ | ||
|  |     iot_plc_led_init(0); | ||
|  | 
 | ||
|  |     /* init power management module */ | ||
|  |     iot_plc_pm_init(); | ||
|  | 
 | ||
|  |     /* create task for socket to receive data. */ | ||
|  |     iot_socket_task_init(); | ||
|  | 
 | ||
|  |     /*  gp timer callback to share task. */ | ||
|  |     iot_gp_timer_task_register(); | ||
|  | 
 | ||
|  |     /* start bottom half init in shared task context to free current task
 | ||
|  |      * to save memory. | ||
|  |      */ | ||
|  |     iot_share_task_msg_register(IOT_SHARE_TASK_MT_BH_INIT, | ||
|  |         plc_mm_init2, plc_mm_init2_cancel); | ||
|  |     iot_share_task_post_msg(IOT_SHARE_TASK_QUEUE_HP, IOT_SHARE_TASK_MT_BH_INIT, | ||
|  |         0, 0, NULL); | ||
|  |     /* delay enough time to allow bottom half init to delete init task
 | ||
|  |      * to free memory quickly | ||
|  |      */ | ||
|  |     os_delay(10000); | ||
|  | } | ||
|  | 
 | ||
|  | /* plc factory test mode initialization */ | ||
|  | void proto_ftm_init() | ||
|  | { | ||
|  |     return; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t plc_core_start(void) | ||
|  | { | ||
|  |     uint32_t cpu, ret = 0; | ||
|  |     uint32_t start_part = 0, last_part = 0, boot_part = 0, part_offset = 0; | ||
|  |     uint32_t fw_addr, run_addr, run_offset, need_compress = 0; | ||
|  |     uint8_t *dst, *src, i = 10; | ||
|  |     imgHdr hdr = {0}; | ||
|  |     char hdr_buf[HEADER_TOLTAL_SIZE]; | ||
|  | 
 | ||
|  |     dev_param_get_start_flag(&start_part); | ||
|  |     dev_param_get_last_flag(&last_part); | ||
|  |     dev_param_get_boot_flag(&boot_part); | ||
|  | 
 | ||
|  | #if RUN_IN_PSRAM
 | ||
|  |     run_offset = MEM_CFG_RAM_CORE1_RUN_OFFSET; | ||
|  |     run_addr = run_offset + HEADER_TOLTAL_SIZE + PSRAM_CORE1_BASE_ADDRESS; | ||
|  |     /* plc fw always need decompress to psram */ | ||
|  |     need_compress = 1; | ||
|  | #else
 | ||
|  |     iot_layout_get_part_offset(PART_NUM_RUN, &run_offset); | ||
|  |     run_addr = run_offset + HEADER_TOLTAL_SIZE + FLASH_BASE_ADDRESS; | ||
|  |     /* plc fw need decompress to flash when boot_part is 1 */ | ||
|  |     need_compress = boot_part; | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     ahb_core2_reset_hold(); | ||
|  |     /* need to compress fw. */ | ||
|  |     if (need_compress == 1) { | ||
|  |         if (last_part) { | ||
|  |             iot_layout_get_part_offset(PART_NUM_FW2, &part_offset); | ||
|  |         } else { | ||
|  |             iot_layout_get_part_offset(PART_NUM_FW1, &part_offset); | ||
|  |         } | ||
|  |         if (part_offset == 0) { | ||
|  |             IOT_ASSERT(0); | ||
|  |         } | ||
|  | 
 | ||
|  |         /* check image header information */ | ||
|  |         fw_addr = flash_get_dev_base() + part_offset; | ||
|  |         os_mem_cpy(hdr_buf, (void*)fw_addr, HEADER_TOLTAL_SIZE); | ||
|  |         img_header_construct(&hdr, hdr_buf); | ||
|  |         if (hdr.v1.guard != IMAGE_GUARD || hdr.v1.devType != devV1Kunlun3 || | ||
|  |             hdr.v1.hdrVer != hdrVer_10) { | ||
|  |             /* image header invalid */ | ||
|  |             ret = 1; | ||
|  |             goto out; | ||
|  |         } | ||
|  | 
 | ||
|  |         /* decompressed */ | ||
|  |         if (hdr.v1.zipType != zipType_defult) { | ||
|  |             /* cus+plc fw is compressed firmware */ | ||
|  |             ret = 2; | ||
|  |             goto out; | ||
|  |         } | ||
|  |         /* extend wdg0 timeout */ | ||
|  |         cpu = cpu_get_mhartid(); | ||
|  |         wdg_set_timeout_cmp(cpu, SET_WDG_TIMEOUT_CMP * 10); | ||
|  |         wdg_feed_dog(cpu); | ||
|  | 
 | ||
|  |         dst = (uint8_t*)(run_addr - HEADER_TOLTAL_SIZE); | ||
|  |         src = (uint8_t*)(fw_addr + HEADER_TOLTAL_SIZE); | ||
|  |         /* adding Prompt Information. */ | ||
|  |         iot_printf("starting to dcompress fw, [%p ->> %p] ...\n", src, dst); | ||
|  |         if (lzma_fw_image_decompress(src, dst, hdr.v1.imgSize, | ||
|  |             (uint8_t *)MEM_CFG_DECOMPRESS_RAM)) { | ||
|  |             ret = 3; | ||
|  |             goto recovery_wdg0; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     /* enable wdg1 to monitor plc app running state */ | ||
|  |     cpu = 1; | ||
|  |     apb_enable(APB_WDG1); | ||
|  |     wdg_set_cmp(cpu, SET_WDG_INTC_CMP * 10); | ||
|  |     wdg_set_timeout_cmp(cpu, SET_WDG_TIMEOUT_CMP); | ||
|  |     wdg_set_cpurst_cmp(cpu, SET_WDG_CPURST_CMP); | ||
|  |     wdg_set_fullrst_cmp(cpu, 2); | ||
|  |     wdg_cnt_enable(cpu); | ||
|  |     wdg_enable(cpu); | ||
|  | 
 | ||
|  |     /* enable core1 */ | ||
|  |     ahb_core1_set_start(run_addr); | ||
|  |     ahb_core1_enable(); | ||
|  | 
 | ||
|  |     do { | ||
|  |         __asm volatile ("nop"); | ||
|  |     } while (i--); | ||
|  |     ahb_core1_reset_release(); | ||
|  | 
 | ||
|  |     iot_printf("plc core running address:0x%08x, start:%d, last:%d, boot:%d\n", | ||
|  |         run_addr, start_part, last_part, boot_part); | ||
|  | 
 | ||
|  | recovery_wdg0: | ||
|  |     cpu = cpu_get_mhartid(); | ||
|  |     wdg_feed_dog(cpu); | ||
|  |     wdg_set_timeout_cmp(cpu, SET_WDG_TIMEOUT_CMP); | ||
|  | 
 | ||
|  | out: | ||
|  |     return ret; | ||
|  | } |