419 lines
13 KiB
C
419 lines
13 KiB
C
/***************************************************************************
|
|
*
|
|
* Copyright 2015-2019 BES.
|
|
* All rights reserved. All unpublished rights reserved.
|
|
*
|
|
* No part of this work may be used or reproduced in any form or by any
|
|
* means, or stored in a database or retrieval system, without prior written
|
|
* permission of BES.
|
|
*
|
|
* Use of this work is governed by a license granted by BES.
|
|
* This work contains confidential and proprietary information of
|
|
* BES. which is protected by copyright, trade secret,
|
|
* trademark and other intellectual property rights.
|
|
*
|
|
****************************************************************************/
|
|
#ifdef CHIP_HAS_CP
|
|
|
|
#include "cp_accel.h"
|
|
#include "cmsis.h"
|
|
#include "cmsis_os.h"
|
|
#include "hal_cmu.h"
|
|
#include "hal_location.h"
|
|
#include "hal_mcu2cp.h"
|
|
#include "hal_timer.h"
|
|
#include "hal_trace.h"
|
|
#include "mpu.h"
|
|
#include "stdarg.h"
|
|
#include "system_cp.h"
|
|
#include "hal_memsc.h"
|
|
#include "string.h"
|
|
#include "app_utils.h"
|
|
|
|
#ifdef CP_ACCEL_DEBUG
|
|
#define CP_ACCEL_TRACE(s, ...) TRACE(s, ##__VA_ARGS__)
|
|
#else
|
|
#define CP_ACCEL_TRACE(s, ...)
|
|
#endif
|
|
|
|
#define CP_NO_FLASH_ACCESS
|
|
|
|
#define CP_CRASH_START_TIMEOUT MS_TO_TICKS(100)
|
|
#define CP_TRACE_FLUSH_TIMEOUT MS_TO_TICKS(200)
|
|
#define CP_CRASH_DUMP_TIMEOUT MS_TO_TICKS(500)
|
|
#define CP_TRACE_BUF_FULL_INTVL MS_TO_TICKS(50)
|
|
|
|
enum CP_SYS_EVENT_T {
|
|
CP_SYS_EVENT_NONE = 0,
|
|
CP_SYS_EVENT_CRASH_START,
|
|
CP_SYS_EVENT_CRASH_END,
|
|
CP_SYS_EVENT_TRACE_FLUSH,
|
|
CP_SYS_EVENT_TRACE_BUF_FULL,
|
|
};
|
|
|
|
static bool ram_inited;
|
|
static bool cp_accel_inited = false;
|
|
static struct cp_task_env_tag cp_task_env;
|
|
static CP_BSS_LOC volatile struct cp_env_tag cp_env;
|
|
|
|
static CP_BSS_LOC volatile enum CP_SYS_EVENT_T cp_sys_evt;
|
|
static CP_BSS_LOC bool cp_in_crash;
|
|
static CP_BSS_LOC volatile uint8_t cp_in_sleep;
|
|
static CP_BSS_LOC uint32_t cp_buf_full_time;
|
|
static CP_BSS_LOC uint8_t req_event = 0, pending_event = 0;
|
|
|
|
static CP_TEXT_SRAM_LOC int send_sys_ctrl_cp2mcu(uint32_t event)
|
|
{
|
|
return hal_mcu2cp_send_cp(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0, (unsigned char *)event, 0);
|
|
}
|
|
|
|
static CP_TEXT_SRAM_LOC void cp_trace_crash_notify(enum HAL_TRACE_STATE_T state)
|
|
{
|
|
uint32_t time;
|
|
|
|
if (state == HAL_TRACE_STATE_CRASH_ASSERT_START || state == HAL_TRACE_STATE_CRASH_FAULT_START) {
|
|
cp_in_crash = true;
|
|
cp_sys_evt = CP_SYS_EVENT_CRASH_START;
|
|
mpu_close();
|
|
send_sys_ctrl_cp2mcu(0);
|
|
|
|
time = hal_sys_timer_get();
|
|
while (cp_sys_evt == CP_SYS_EVENT_CRASH_START &&
|
|
hal_sys_timer_get() - time < CP_CRASH_START_TIMEOUT);
|
|
} else {
|
|
cp_sys_evt = CP_SYS_EVENT_CRASH_END;
|
|
}
|
|
}
|
|
|
|
static CP_TEXT_SRAM_LOC void cp_trace_buffer_ctrl(enum HAL_TRACE_BUF_STATE_T buf_state)
|
|
{
|
|
uint32_t time;
|
|
|
|
if (cp_sys_evt != CP_SYS_EVENT_NONE) {
|
|
return;
|
|
}
|
|
|
|
time = hal_sys_timer_get();
|
|
|
|
if (buf_state == HAL_TRACE_BUF_STATE_FLUSH) {
|
|
cp_sys_evt = CP_SYS_EVENT_TRACE_FLUSH;
|
|
if (!cp_in_crash) {
|
|
send_sys_ctrl_cp2mcu(0);
|
|
}
|
|
|
|
while (cp_sys_evt == CP_SYS_EVENT_TRACE_FLUSH &&
|
|
hal_sys_timer_get() - time < CP_TRACE_FLUSH_TIMEOUT);
|
|
} else if (buf_state == HAL_TRACE_BUF_STATE_FULL || buf_state == HAL_TRACE_BUF_STATE_NEAR_FULL) {
|
|
if (time - cp_buf_full_time >= CP_TRACE_BUF_FULL_INTVL) {
|
|
cp_buf_full_time = time;
|
|
if (!cp_in_crash) {
|
|
cp_sys_evt = CP_SYS_EVENT_TRACE_BUF_FULL;
|
|
send_sys_ctrl_cp2mcu(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static SRAM_TEXT_LOC unsigned int cp2mcu_sys_arrived(const unsigned char *data, unsigned int len)
|
|
{
|
|
uint32_t time;
|
|
uint8_t task_id = 0;
|
|
|
|
if (cp_sys_evt == CP_SYS_EVENT_TRACE_FLUSH) {
|
|
TRACE_FLUSH();
|
|
cp_sys_evt = CP_SYS_EVENT_NONE;
|
|
} else if (cp_sys_evt == CP_SYS_EVENT_TRACE_BUF_FULL) {
|
|
TRACE(0," ");
|
|
cp_sys_evt = CP_SYS_EVENT_NONE;
|
|
} else if (cp_sys_evt == CP_SYS_EVENT_CRASH_START) {
|
|
cp_sys_evt = CP_SYS_EVENT_NONE;
|
|
|
|
TRACE(0," ");
|
|
TRACE(0,"CP Crash starts ...");
|
|
UNLOCK_CP_PROCESS(); //Forced release lock
|
|
|
|
// Wait CP crash dump finishes in interrupt context
|
|
time = hal_sys_timer_get();
|
|
while (cp_sys_evt != CP_SYS_EVENT_CRASH_END &&
|
|
hal_sys_timer_get() - time < CP_CRASH_DUMP_TIMEOUT) {
|
|
if (cp_sys_evt == CP_SYS_EVENT_TRACE_FLUSH) {
|
|
TRACE_FLUSH();
|
|
cp_sys_evt = CP_SYS_EVENT_NONE;
|
|
}
|
|
}
|
|
|
|
for (task_id=0; task_id<CP_TASK_MAX; task_id++) {
|
|
if (cp_task_env.p_desc[task_id].mcu_sys_ctrl_hdlr) {
|
|
cp_task_env.p_desc[task_id].mcu_sys_ctrl_hdlr(CP_SYS_EVENT_CRASH_END);
|
|
}
|
|
}
|
|
|
|
TRACE(0,"CP Crash ends ...");
|
|
TRACE(0," ");
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
static CP_TEXT_SRAM_LOC unsigned int mcu2cp_msg_arrived(const unsigned char *data, unsigned int len)
|
|
{
|
|
uint8_t task_id = CP_TASK_ID_GET(*data);
|
|
uint8_t event_type = CP_EVENT_GET(*data);
|
|
|
|
cp_env.cp_msg[task_id][event_type] = 1;
|
|
cp_env.cp_msg_recv = true;
|
|
|
|
if (cp_task_env.p_desc[task_id].cp_evt_hdlr) {
|
|
cp_task_env.p_desc[task_id].cp_evt_hdlr((uint32_t)data);
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
static CP_TEXT_SRAM_LOC void mcu2cp_msg_sent(const unsigned char *data, unsigned int len)
|
|
{
|
|
// TRACE(1, "mcu2cp_msg_sent,pending count = %d", cp_env.mcu2cp_tx_count);
|
|
|
|
if (cp_env.mcu2cp_tx_count > 1) {
|
|
cp_env.mcu2cp_tx_count--;
|
|
pending_event = cp_env.mcu2cp_tx_pending[0];
|
|
hal_mcu2cp_send_mcu(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, &pending_event, 1);
|
|
|
|
for (uint8_t index = 0;index < cp_env.mcu2cp_tx_count-1;index++) {
|
|
cp_env.mcu2cp_tx_pending[index] = cp_env.mcu2cp_tx_pending[index+1];
|
|
}
|
|
} else {
|
|
cp_env.mcu2cp_tx_count = 0;
|
|
}
|
|
}
|
|
|
|
#if defined(__ARM_ARCH_8M_MAIN__)
|
|
|
|
#define CP_CODE_MAP_BASE (ROM_BASE + 0x800)
|
|
#define CP_CODE_MAP_SIZE (RAMX_BASE + RAM_TOTAL_SIZE - CP_CODE_MAP_BASE)
|
|
|
|
static CP_DATA_LOC const mpu_regions_t mpu_table_cp[] = {
|
|
{CP_CODE_MAP_BASE, CP_CODE_MAP_SIZE, MPU_ATTR_EXEC, MAIR_ATTR_INT_SRAM},
|
|
{RAM_BASE, RAM_TOTAL_SIZE, MPU_ATTR_READ_WRITE, MAIR_ATTR_INT_SRAM},
|
|
{CMU_BASE, 0x01000000, MPU_ATTR_READ_WRITE, MAIR_ATTR_DEVICE},
|
|
};
|
|
#else
|
|
static CP_DATA_LOC const mpu_regions_t mpu_table_cp[] = {
|
|
{0, 0x800, MPU_ATTR_NO_ACCESS},
|
|
{FLASHX_BASE, 0x4000000, MPU_ATTR_NO_ACCESS},
|
|
{FLASH_BASE, 0x4000000, MPU_ATTR_NO_ACCESS},
|
|
{FLASH_NC_BASE, 0x4000000, MPU_ATTR_NO_ACCESS},
|
|
};
|
|
#endif
|
|
|
|
static CP_TEXT_SRAM_LOC NOINLINE void accel_loop(void)
|
|
{
|
|
uint32_t lock;
|
|
uint8_t task_index = 0, event_index = 0;
|
|
bool msg_flag = false;
|
|
uint8_t msg[CP_TASK_MAX][CP_EVENT_MAX];
|
|
|
|
mpu_setup_cp(mpu_table_cp, ARRAY_SIZE(mpu_table_cp));
|
|
|
|
while (1) {
|
|
lock = int_lock_global();
|
|
msg_flag = cp_env.cp_msg_recv;
|
|
cp_env.cp_msg_recv = false;
|
|
memcpy(msg, (uint8_t *)cp_env.cp_msg, sizeof(cp_env.cp_msg));
|
|
memset((uint8_t *)cp_env.cp_msg, 0, sizeof(cp_env.cp_msg));
|
|
if (false == msg_flag) {
|
|
cp_in_sleep = true;
|
|
__WFI();
|
|
cp_in_sleep = false;
|
|
}
|
|
int_unlock_global(lock);
|
|
|
|
if (msg_flag) {
|
|
for (task_index = 0;task_index < CP_TASK_MAX;task_index++) {
|
|
for (event_index = 0;event_index < CP_EVENT_MAX;event_index++) {
|
|
LOCK_CP_PROCESS();
|
|
if ((msg[task_index][event_index]) && (cp_task_env.p_desc[task_index].cp_work_main)) {
|
|
cp_task_env.p_desc[task_index].cp_work_main(event_index);
|
|
}
|
|
UNLOCK_CP_PROCESS();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void accel_main(void)
|
|
{
|
|
system_cp_init(!ram_inited);
|
|
TRACE(1, "%s", __func__);
|
|
|
|
ram_inited = true;
|
|
|
|
memset((uint8_t *)&cp_env, 0, sizeof(cp_env));
|
|
|
|
hal_trace_open_cp();
|
|
|
|
hal_mcu2cp_open_cp(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, mcu2cp_msg_arrived, NULL, false);
|
|
hal_mcu2cp_open_cp(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0, NULL, NULL, false);
|
|
|
|
hal_mcu2cp_start_recv_cp(HAL_MCU2CP_ID_0);
|
|
//hal_mcu2cp_start_recv_cp(HAL_MCU2CP_ID_1);
|
|
|
|
cp_accel_inited = true;
|
|
|
|
accel_loop();
|
|
}
|
|
|
|
static SRAM_TEXT_LOC unsigned int cp2mcu_msg_arrived(const unsigned char *data, unsigned int len)
|
|
{
|
|
uint8_t task_id = CP_TASK_ID_GET((uint32_t)data);
|
|
// TRACE(2, "%s, task_id = %d", __func__, task_id);
|
|
|
|
if (task_id >= CP_TASK_MAX) {
|
|
return -1;
|
|
}
|
|
|
|
if (cp_task_env.p_desc[task_id].mcu_evt_hdlr) {
|
|
cp_task_env.p_desc[task_id].mcu_evt_hdlr((uint32_t)data);
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
int cp_accel_open(enum CP_TASK_TYPE task_id, struct cp_task_desc const * p_task_desc)
|
|
{
|
|
TRACE(4, "%s, task id = %d, cp_state = %d init %d", __func__, task_id, cp_task_env.p_desc[task_id].cp_accel_state, cp_accel_inited);
|
|
|
|
if ((task_id >= CP_TASK_MAX) || (p_task_desc == NULL)) {
|
|
TRACE(1, "%s task id error", __func__);
|
|
return -1;
|
|
}
|
|
|
|
if (cp_task_env.p_desc[task_id].cp_accel_state != CP_ACCEL_STATE_CLOSED) {
|
|
TRACE(1, "%s cp_accel_state error", __func__);
|
|
return -1;
|
|
}
|
|
|
|
cp_task_env.p_desc[task_id].cp_accel_state = CP_ACCEL_STATE_OPENING;
|
|
cp_task_env.p_desc[task_id].cp_work_main = p_task_desc->cp_work_main;
|
|
cp_task_env.p_desc[task_id].cp_evt_hdlr = p_task_desc->cp_evt_hdlr;
|
|
cp_task_env.p_desc[task_id].mcu_evt_hdlr = p_task_desc->mcu_evt_hdlr;
|
|
cp_task_env.p_desc[task_id].mcu_sys_ctrl_hdlr = p_task_desc->mcu_sys_ctrl_hdlr;
|
|
|
|
if (false == cp_accel_inited) {
|
|
hal_trace_cp_register(cp_trace_crash_notify, cp_trace_buffer_ctrl);
|
|
|
|
hal_cmu_cp_enable(RAMCP_BASE + RAMCP_SIZE, (uint32_t)accel_main);
|
|
|
|
hal_mcu2cp_open_mcu(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, cp2mcu_msg_arrived, mcu2cp_msg_sent, false);
|
|
hal_mcu2cp_open_mcu(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0, cp2mcu_sys_arrived, NULL, false);
|
|
|
|
hal_mcu2cp_start_recv_mcu(HAL_MCU2CP_ID_0);
|
|
hal_mcu2cp_start_recv_mcu(HAL_MCU2CP_ID_1);
|
|
}
|
|
cp_task_env.p_desc[task_id].cp_accel_state = CP_ACCEL_STATE_OPENED;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cp_accel_close(enum CP_TASK_TYPE task_id)
|
|
{
|
|
uint8_t i = 0;
|
|
|
|
TRACE(4, "%s, task id = %d, cp_state = %d init %d", __func__,
|
|
task_id, cp_task_env.p_desc[task_id].cp_accel_state, cp_accel_inited);
|
|
LOCK_CP_PROCESS(); // avoid hangup
|
|
|
|
if (cp_task_env.p_desc[task_id].cp_accel_state == CP_ACCEL_STATE_CLOSED) {
|
|
goto accel_close_end;
|
|
}
|
|
|
|
cp_task_env.p_desc[task_id].cp_accel_state = CP_ACCEL_STATE_CLOSING;
|
|
cp_task_env.p_desc[task_id].cp_work_main = NULL;
|
|
cp_task_env.p_desc[task_id].cp_evt_hdlr = NULL;
|
|
cp_task_env.p_desc[task_id].mcu_evt_hdlr = NULL;
|
|
|
|
for (i=0; i<CP_TASK_MAX; i++) {
|
|
if (cp_task_env.p_desc[i].cp_accel_state == CP_ACCEL_STATE_OPENED || \
|
|
cp_task_env.p_desc[i].cp_accel_state == CP_ACCEL_STATE_OPENING) {
|
|
goto accel_close_end;
|
|
}
|
|
}
|
|
|
|
if (cp_accel_inited) {
|
|
cp_accel_inited = false;
|
|
|
|
hal_mcu2cp_close_mcu(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0);
|
|
hal_mcu2cp_close_mcu(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0);
|
|
|
|
hal_cmu_cp_disable();
|
|
|
|
system_cp_term();
|
|
|
|
hal_mcu2cp_close_cp(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0);
|
|
hal_mcu2cp_close_cp(HAL_MCU2CP_ID_1, HAL_MCU2CP_MSG_TYPE_0);
|
|
|
|
hal_trace_cp_register(NULL, NULL);
|
|
}
|
|
|
|
accel_close_end:
|
|
cp_task_env.p_desc[task_id].cp_accel_state = CP_ACCEL_STATE_CLOSED;
|
|
UNLOCK_CP_PROCESS();
|
|
return 0;
|
|
}
|
|
|
|
int SRAM_TEXT_LOC cp_accel_init_done(void)
|
|
{
|
|
// TRACE(2, "%s, cp_inited = %d", __func__, cp_accel_inited);
|
|
return cp_accel_inited;
|
|
}
|
|
|
|
int cp_accel_send_event_mcu2cp(uint8_t event)
|
|
{
|
|
if ((false == cp_accel_inited) || (cp_env.mcu2cp_tx_count > MAX_CP_MSG_NUM)) {
|
|
TRACE(2,
|
|
"send_evt error, cp_accel_inited = %d, event pending count = %d",
|
|
cp_accel_inited,
|
|
cp_env.mcu2cp_tx_count);
|
|
|
|
TRACE(2,
|
|
"send evt task_id = %d, event = %d",
|
|
CP_TASK_ID_GET(event),
|
|
CP_EVENT_GET(event));
|
|
return -1;
|
|
}
|
|
|
|
// TRACE(1, "current CP tx count:%d", cp_env.mcu2cp_tx_count);
|
|
if (cp_env.mcu2cp_tx_count > 0) {
|
|
cp_env.mcu2cp_tx_pending[cp_env.mcu2cp_tx_count - 1] = event;
|
|
cp_env.mcu2cp_tx_count++;
|
|
} else {
|
|
req_event = event;
|
|
cp_env.mcu2cp_tx_count = 1;
|
|
hal_mcu2cp_send_mcu(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, &req_event, 1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CP_TEXT_SRAM_LOC cp_accel_send_event_cp2mcu(uint8_t event)
|
|
{
|
|
return hal_mcu2cp_send_cp(HAL_MCU2CP_ID_0, HAL_MCU2CP_MSG_TYPE_0, (unsigned char *)(uint32_t)event, 0);
|
|
}
|
|
|
|
int SRAM_TEXT_LOC cp_accel_busy(enum CP_TASK_TYPE task_id)
|
|
{
|
|
if (cp_task_env.p_desc[task_id].cp_accel_state != CP_ACCEL_STATE_CLOSED) {
|
|
if (cp_task_env.p_desc[task_id].cp_accel_state == CP_ACCEL_STATE_OPENED && cp_in_sleep &&
|
|
!hal_mcu2cp_local_irq_pending_cp(HAL_MCU2CP_ID_0)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|