349 lines
8.6 KiB
C
349 lines
8.6 KiB
C
|
/**
|
||
|
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
||
|
* Copyright (c) 2016 BEKEN Inc.
|
||
|
*
|
||
|
* The contents of this file may not be disclosed to third parties, copied or
|
||
|
* duplicated in any form, in whole or in part, without the prior written
|
||
|
* permission of BEKEN Corporation.
|
||
|
*
|
||
|
*/
|
||
|
#include <stdlib.h>
|
||
|
#include "sys_rtos.h"
|
||
|
#include <os/os.h>
|
||
|
#include <common/bk_kernel_err.h>
|
||
|
|
||
|
#include "bk_cli.h"
|
||
|
#include "stdarg.h"
|
||
|
#include <common/bk_include.h>
|
||
|
#include <os/mem.h>
|
||
|
#include <os/str.h>
|
||
|
#include "bk_phy.h"
|
||
|
#include "cli.h"
|
||
|
#include "cli_config.h"
|
||
|
#include <components/log.h>
|
||
|
#include <driver/uart.h>
|
||
|
#include "bk_rtos_debug.h"
|
||
|
#if CONFIG_SHELL_ASYNCLOG
|
||
|
#include "components/shell_task.h"
|
||
|
#endif
|
||
|
#include "bk_api_cli.h"
|
||
|
#include "boot.h"
|
||
|
|
||
|
#define TAG "debug"
|
||
|
|
||
|
static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
|
||
|
#if (CONFIG_CPU_CNT > 1) && CONFIG_MAILBOX
|
||
|
#include "mb_ipc_cmd.h"
|
||
|
|
||
|
#include "amp_lock_api.h"
|
||
|
|
||
|
#include "spinlock.h"
|
||
|
|
||
|
static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
static void debug_rpc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
static void debug_rpc_gpio_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
static void debug_spinlock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
|
||
|
static u8 ipc_inited = 0;
|
||
|
|
||
|
spinlock_t gpio_spinlock;
|
||
|
spinlock_t * gpio_spinlock_ptr;
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#if CONFIG_ARCH_RISCV
|
||
|
static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
#endif
|
||
|
|
||
|
//#define CORE_MARK_ENABLED
|
||
|
|
||
|
#ifdef CORE_MARK_ENABLED
|
||
|
static void debug_core_mark(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
|
||
|
#endif
|
||
|
|
||
|
const struct cli_command debug_cmds[] = {
|
||
|
{"help", "list debug cmds", debug_help_command},
|
||
|
#if (CONFIG_CPU_CNT > 1) && CONFIG_MAILBOX
|
||
|
{"ipc", "ipc [spinlock addr]", debug_ipc_command},
|
||
|
{"cpu_lock", "cpu_lock [timeout 1~20]", debug_cpulock_command},
|
||
|
{"spin_lock", "spin_lock [timeout 1~20]", debug_spinlock_command},
|
||
|
#endif
|
||
|
|
||
|
#if CONFIG_ARCH_RISCV
|
||
|
{"perfmon", "perfmon(calc MIPS)", debug_perfmon_command},
|
||
|
{"boottime", "boottime(show boot mtime info)", debug_show_boot_time},
|
||
|
#endif
|
||
|
|
||
|
#ifdef CORE_MARK_ENABLED
|
||
|
#if CONFIG_SYS_CPU0
|
||
|
{"core_mark", "core_mark [seed1 seed2 seed3 iteration Algorithms]", debug_core_mark},
|
||
|
#endif
|
||
|
#endif /* CORE_MARK_ENABLED */
|
||
|
};
|
||
|
|
||
|
const int cli_debug_table_size = ARRAY_SIZE(debug_cmds);
|
||
|
|
||
|
void print_cmd_table(const struct cli_command *cmd_table, int table_items)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < table_items; i++)
|
||
|
{
|
||
|
if (cmd_table[i].name)
|
||
|
{
|
||
|
if (cmd_table[i].help)
|
||
|
os_printf("%s: %s\r\n", cmd_table[i].name, cmd_table[i].help);
|
||
|
else
|
||
|
os_printf("%s\r\n", cmd_table[i].name);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void print_cmd_help(const struct cli_command *cmd_table, int table_items, void *func)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < table_items; i++)
|
||
|
{
|
||
|
if(cmd_table[i].function == func)
|
||
|
{
|
||
|
if (cmd_table[i].help)
|
||
|
os_printf("%s\r\n", cmd_table[i].help);
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
||
|
{
|
||
|
os_printf("====Debug Commands====\r\n");
|
||
|
|
||
|
print_cmd_table(debug_cmds, ARRAY_SIZE(debug_cmds));
|
||
|
}
|
||
|
|
||
|
#if (CONFIG_CPU_CNT > 1)
|
||
|
static void print_debug_cmd_help(void *func)
|
||
|
{
|
||
|
print_cmd_help(debug_cmds, ARRAY_SIZE(debug_cmds), func);
|
||
|
}
|
||
|
|
||
|
#if CONFIG_MAILBOX
|
||
|
static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
||
|
{
|
||
|
int ret_val;
|
||
|
|
||
|
if(ipc_inited)
|
||
|
{
|
||
|
BK_LOGI(TAG,"ipc started\r\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#if CONFIG_SYS_CPU1
|
||
|
|
||
|
if (argc < 2)
|
||
|
{
|
||
|
sprintf(pcWriteBuffer,"usage: ipc spinlock_addr\r\n");
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
ret_val = ipc_init();
|
||
|
BK_LOGI(TAG,"ipc init: %d\r\n", ret_val);
|
||
|
|
||
|
ipc_inited = 1;
|
||
|
|
||
|
#if CONFIG_SYS_CPU1
|
||
|
|
||
|
ret_val = ipc_send_power_up();
|
||
|
BK_LOGI(TAG,"ipc client power: %d\r\n", ret_val);
|
||
|
|
||
|
ret_val = ipc_send_heart_beat(0x34);
|
||
|
BK_LOGI(TAG,"ipc client heartbeat: %d\r\n", ret_val);
|
||
|
|
||
|
ret_val = ipc_send_test_cmd(0x12);
|
||
|
BK_LOGI(TAG,"ipc client test: 0x%x\r\n", ret_val);
|
||
|
|
||
|
gpio_spinlock_ptr = (spinlock_t *)strtoul(argv[1], NULL, 0);
|
||
|
sprintf(pcWriteBuffer,"spinlock_addr: 0x%x\r\n", gpio_spinlock_ptr);
|
||
|
|
||
|
#else
|
||
|
|
||
|
spinlock_init(&gpio_spinlock);
|
||
|
sprintf(pcWriteBuffer,"spinlock_addr: 0x%x\r\n", &gpio_spinlock);
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void debug_spinlock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
||
|
{
|
||
|
u32 timeout_second = 10; // 10s
|
||
|
|
||
|
if(ipc_inited == 0)
|
||
|
{
|
||
|
BK_LOGI(TAG,"Failed: no rpc client/server in CPU0/CPU1.\r\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (argc > 1)
|
||
|
{
|
||
|
timeout_second = strtoul(argv[1], NULL, 0);
|
||
|
|
||
|
if(timeout_second > 20)
|
||
|
timeout_second = 20;
|
||
|
if(timeout_second == 0)
|
||
|
timeout_second = 10;
|
||
|
}
|
||
|
|
||
|
int i;
|
||
|
|
||
|
for(i = 0; i < 10; i++)
|
||
|
{
|
||
|
BK_LOGI(TAG,"times: %d\r\n", i);
|
||
|
|
||
|
#if CONFIG_SYS_CPU0
|
||
|
uint32_t flag = spinlock_acquire(&gpio_spinlock);
|
||
|
BK_LOGI(TAG,"svr spinlock acquired %d\r\n", gpio_spinlock.owner);
|
||
|
rtos_delay_milliseconds(timeout_second * 1000);
|
||
|
spinlock_release(&gpio_spinlock, flag);
|
||
|
BK_LOGI(TAG,"svr spinlock released %d\r\n", gpio_spinlock.owner);
|
||
|
#endif
|
||
|
|
||
|
#if CONFIG_SYS_CPU1
|
||
|
uint32_t flag = spinlock_acquire(gpio_spinlock_ptr);
|
||
|
BK_LOGI(TAG,"client spinlock acquired %d\r\n", gpio_spinlock_ptr->owner);
|
||
|
rtos_delay_milliseconds(timeout_second * 1000);
|
||
|
spinlock_release(gpio_spinlock_ptr, flag);
|
||
|
BK_LOGI(TAG,"client spinlock released %d\r\n", gpio_spinlock_ptr->owner);
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
||
|
{
|
||
|
u32 timeout_second = 10; // 10s
|
||
|
|
||
|
if(ipc_inited == 0)
|
||
|
{
|
||
|
BK_LOGI(TAG,"Failed: no ipc client/server in CPU0/CPU1.\r\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (argc > 1)
|
||
|
{
|
||
|
timeout_second = strtoul(argv[1], NULL, 0);
|
||
|
|
||
|
if(timeout_second > 20)
|
||
|
timeout_second = 20;
|
||
|
if(timeout_second == 0)
|
||
|
timeout_second = 10;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
print_debug_cmd_help(debug_cpulock_command);
|
||
|
BK_LOGI(TAG,"default timeout 10s is used.\r\n");
|
||
|
}
|
||
|
|
||
|
int ret_val = BK_FAIL;
|
||
|
|
||
|
ret_val = amp_res_init(AMP_RES_ID_GPIO);
|
||
|
BK_LOGI(TAG,"amp res init:ret=%d\r\n", ret_val);
|
||
|
|
||
|
ret_val = amp_res_acquire(AMP_RES_ID_GPIO, timeout_second * 1000);
|
||
|
BK_LOGI(TAG,"amp res acquire:ret=%d\r\n", ret_val);
|
||
|
|
||
|
rtos_delay_milliseconds(timeout_second * 1000);
|
||
|
|
||
|
if(ret_val == 0)
|
||
|
{
|
||
|
ret_val = amp_res_release(AMP_RES_ID_GPIO);
|
||
|
BK_LOGI(TAG,"amp res release:ret=%d\r\n", ret_val);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
BK_LOGI(TAG,"amp res release: no release\r\n");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
const struct cli_command * cli_debug_cmd_table(int *num)
|
||
|
{
|
||
|
*num = ARRAY_SIZE(debug_cmds);
|
||
|
|
||
|
return &debug_cmds[0];
|
||
|
}
|
||
|
|
||
|
#if CONFIG_ARCH_RISCV
|
||
|
|
||
|
extern u64 riscv_get_instruct_cnt(void);
|
||
|
extern u64 riscv_get_mtimer(void);
|
||
|
|
||
|
static u64 saved_time = 0;
|
||
|
static u64 saved_inst_cnt = 0;
|
||
|
|
||
|
static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
||
|
{
|
||
|
u64 cur_time = riscv_get_mtimer();
|
||
|
u64 cur_inst_cnt = riscv_get_instruct_cnt();
|
||
|
|
||
|
BK_LOGI(TAG,"cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF));
|
||
|
BK_LOGI(TAG,"cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF));
|
||
|
|
||
|
saved_time = (cur_time - saved_time) / 26;
|
||
|
saved_inst_cnt = cur_inst_cnt - saved_inst_cnt;
|
||
|
|
||
|
// BK_LOGI(TAG,"elapse time(us): %x:%08x\r\n", (u32)(saved_time >> 32), (u32)(saved_time & 0xFFFFFFFF));
|
||
|
// BK_LOGI(TAG,"diff inst_cnt: %x:%08x\r\n", (u32)(saved_inst_cnt >> 32), (u32)(saved_inst_cnt & 0xFFFFFFFF));
|
||
|
|
||
|
sprintf(pcWriteBuffer,"MIPS: %d KIPS\r\n", (u32)(saved_inst_cnt * 1000 / saved_time));
|
||
|
|
||
|
saved_time = cur_time;
|
||
|
saved_inst_cnt = cur_inst_cnt;
|
||
|
}
|
||
|
|
||
|
static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
||
|
{
|
||
|
u64 cur_time = riscv_get_mtimer();
|
||
|
u64 cur_inst_cnt = riscv_get_instruct_cnt();
|
||
|
|
||
|
BK_LOGI(TAG,"cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF));
|
||
|
BK_LOGI(TAG,"cur time: %ldms\r\n", (u32)(cur_time/26000));
|
||
|
BK_LOGI(TAG,"cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF));
|
||
|
|
||
|
#if CONFIG_SAVE_BOOT_TIME_POINT
|
||
|
show_saved_mtime_info();
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef CORE_MARK_ENABLED
|
||
|
static void debug_core_mark(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
|
||
|
{
|
||
|
extern bk_err_t bk_wdt_stop(void);
|
||
|
extern bk_err_t bk_wdt_start(uint32_t timeout_ms);
|
||
|
|
||
|
extern void core_mark(int argc, char *argv[]);
|
||
|
|
||
|
bk_wdt_stop();
|
||
|
u32 int_mask = rtos_enter_critical();
|
||
|
|
||
|
core_mark(argc, argv);
|
||
|
|
||
|
rtos_exit_critical(int_mask);
|
||
|
bk_wdt_start(CONFIG_INT_WDT_PERIOD_MS);
|
||
|
}
|
||
|
|
||
|
#include "./core_mark/core_main.c"
|
||
|
#endif /* CORE_MARK_ENABLED */
|
||
|
|