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;
 | 
						|
} |