You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1790 lines
55 KiB
1790 lines
55 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2009-2020. All rights reserved.
|
|
* Description: log drv
|
|
* Author: Hisilicon
|
|
* Create: 2009-12-17
|
|
*/
|
|
#include "drv_log.h"
|
|
|
|
#include <mntn/rdr_log.h>
|
|
#include <linux/rtc.h>
|
|
#include <linux/huanglong/securec.h>
|
|
|
|
#include "td_type.h"
|
|
#include "soc_log.h"
|
|
#include "osal_ext.h"
|
|
#include "drv_dev_ext.h"
|
|
#include "drv_module_ext.h"
|
|
#include "drv_log_ext.h"
|
|
#include "drv_sys_ext.h"
|
|
#include "drv_ioctl_log.h"
|
|
#include "drv_log.h"
|
|
|
|
typedef struct {
|
|
struct dma_buf *dmabuf;
|
|
td_u8 *virt_addr;
|
|
} log_ion_buf;
|
|
|
|
#define LOG_MSG_BUF_RESERVE (4 * 1024)
|
|
|
|
static log_ion_buf g_log_cfg_buf;
|
|
/* kernel-state pointer of log control info */ /* CNcomment: 打印控制信息的内核态指针 */
|
|
static log_cfg_info *g_log_cfg_info;
|
|
|
|
static td_bool g_log_init = TD_FALSE;
|
|
|
|
#define LOG_MAX_FILE_SIZE 120U /* 120M */
|
|
#define LOG_MIN_FILE_SIZE 1U /* 1M */
|
|
#define LOG_DEFAULT_FILE_SIZE 12U /* 12M */
|
|
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
#define LOG_MAX_FILE_CNT (4) /* Save up to 5 log files */
|
|
static log_ion_buf g_log_msg_buf;
|
|
static td_u64 g_log_write_len_count = 0;
|
|
static td_u32 g_log_file_count = 0;
|
|
#endif
|
|
|
|
static log_buf_info g_log_msg_info;
|
|
|
|
static osal_semaphore g_log_k_mutex;
|
|
osal_semaphore g_log_store_mutex;
|
|
DEFINE_SPINLOCK(g_log_lock);
|
|
|
|
#define log_file_lock() osal_sem_down_interruptible(&g_log_k_mutex)
|
|
#define log_file_unlock() osal_sem_up(&g_log_k_mutex)
|
|
#define log_store_lock() osal_sem_down_interruptible(&g_log_store_mutex)
|
|
#define log_store_unlock() osal_sem_up(&g_log_store_mutex)
|
|
|
|
#define STORE_LOG_WAKE_UP_SIZE 1000
|
|
#define LOG_RTC_TIME_LENGH 19
|
|
#define LOG_WAIT_DATA_TIMEOUT 1000 /* 1s */
|
|
|
|
/* this variable will be used by /kmod/load script */
|
|
static td_u32 g_log_buf_size = 10 * 256 * LOG_MSG_BUF_RESERVE; /* Multiply by 256 means buf_size is 1M,10M total */
|
|
|
|
static td_char g_log_path_buf[LOG_MAX_FILE_NAME_LENTH] = "/tmp";
|
|
static td_char *g_udisk_log_file = g_log_path_buf;
|
|
static td_bool g_set_log_file_flag = TD_FALSE;
|
|
|
|
static td_char g_store_path_buf[LOG_MAX_FILE_NAME_LENTH] = "/mnt";
|
|
td_char *g_store_path = g_store_path_buf;
|
|
|
|
static td_u32 g_default_log_size = LOG_DEFAULT_FILE_SIZE * 1024 * 1024; /* Multiply by 1024 means buf_size is 16M */
|
|
|
|
td_char *g_debug_level_name[SOC_LOG_LEVEL_MAX + 1] = {
|
|
"ALERT", "FATAL", "ERROR", "WARN", "NOTICE", "INFO", "DEBUG", "TRACE", "MAX"
|
|
};
|
|
static td_u32 g_default_log_level = SOC_LOG_LEVEL_ERROR;
|
|
|
|
static log_store_info_t g_log_store_info = {
|
|
.store_log_enable = TD_FALSE,
|
|
.store_log_thread_exist = TD_FALSE,
|
|
.store_log_poll_new = TD_FALSE,
|
|
.store_log_len = 0,
|
|
};
|
|
|
|
td_void drv_log_store_enable(const td_bool *enable)
|
|
{
|
|
if (enable == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
if (g_set_log_file_flag == TD_TRUE) {
|
|
g_log_store_info.store_log_enable = TD_FALSE;
|
|
} else {
|
|
g_log_store_info.store_log_enable = *enable;
|
|
}
|
|
|
|
g_log_store_info.store_log_thread_exist = *enable;
|
|
return;
|
|
}
|
|
|
|
td_void drv_log_get_store_status(td_bool *store_enable, td_bool *store_thread_exist)
|
|
{
|
|
if (store_enable == TD_NULL || store_thread_exist == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
*store_enable = g_log_store_info.store_log_enable;
|
|
*store_thread_exist = g_log_store_info.store_log_thread_exist;
|
|
return;
|
|
}
|
|
|
|
unsigned int drv_log_store_poll(osal_poll *osal_poll)
|
|
{
|
|
unsigned int poll_mask = 0;
|
|
|
|
if (g_log_store_info.store_log_thread_exist == TD_TRUE) {
|
|
if (g_log_store_info.store_log_poll_new == TD_TRUE) {
|
|
poll_mask |= OSAL_POLLIN;
|
|
g_log_store_info.store_log_poll_new = TD_FALSE;
|
|
} else {
|
|
osal_poll_wait(osal_poll, &g_log_store_info.poll_wait_queue);
|
|
}
|
|
}
|
|
|
|
return poll_mask;
|
|
}
|
|
|
|
static td_void drv_log_reset_buf(td_void)
|
|
{
|
|
td_ulong flags;
|
|
|
|
spin_lock_irqsave(&g_log_lock, flags);
|
|
g_log_msg_info.read = g_log_msg_info.write;
|
|
g_log_msg_info.reset_cnt++;
|
|
spin_unlock_irqrestore(&g_log_lock, flags);
|
|
}
|
|
|
|
static td_s32 drv_log_wait_condition(const td_void *param)
|
|
{
|
|
return (((log_buf_info *)param)->write != ((log_buf_info *)param)->read);
|
|
}
|
|
|
|
static td_s32 log_data_buf_copy(td_u8 *buf, td_u32 buf_size, const td_u8 *src, td_u32 copy_len,
|
|
td_bool b_kernel_copy)
|
|
{
|
|
errno_t err_ret;
|
|
|
|
if (b_kernel_copy == TD_FALSE) {
|
|
if (osal_copy_to_user(buf, src, copy_len)) {
|
|
soc_log_err("copy_to_user error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
} else {
|
|
err_ret = memcpy_s(buf, buf_size, src, copy_len);
|
|
if (err_ret != EOK) {
|
|
soc_log_err("secure func call error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 log_read_data(td_u8 *buf, td_u32 buf_len, log_buf_info *msg_info_now,
|
|
td_u32 *copy_len, td_bool b_kernel_copy)
|
|
{
|
|
td_u32 buf_used, data_part_one, data_part_two, data_len, new_read_addr;
|
|
td_s32 ret;
|
|
|
|
/* not support log when uart close or user version */
|
|
#if defined (CONFIG_CLOSE_UART0) || defined (ANDROID_BUILD_USER)
|
|
return TD_SUCCESS;
|
|
#endif
|
|
if (osal_get_buildvariant() == OSAL_BUILDVARIANT_USER) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
if (msg_info_now->write < msg_info_now->read) {
|
|
buf_used = msg_info_now->buf_size - msg_info_now->read + msg_info_now->write;
|
|
data_part_one = msg_info_now->buf_size - msg_info_now->read;
|
|
data_part_two = msg_info_now->write;
|
|
} else {
|
|
buf_used = msg_info_now->write - msg_info_now->read;
|
|
data_part_one = buf_used;
|
|
data_part_two = 0;
|
|
}
|
|
*copy_len = (buf_len <= (data_part_one + data_part_two)) ? (buf_len) : (data_part_one + data_part_two);
|
|
data_len = (data_part_one >= *copy_len) ? (*copy_len) : (data_part_one);
|
|
|
|
ret = log_data_buf_copy(buf, buf_len, msg_info_now->start_virt_addr + msg_info_now->read, data_len, b_kernel_copy);
|
|
if (ret != TD_SUCCESS) {
|
|
return TD_FAILURE;
|
|
}
|
|
if (data_part_one < *copy_len) {
|
|
ret = log_data_buf_copy(buf + data_part_one, buf_len - data_part_one,
|
|
msg_info_now->start_virt_addr, *copy_len - data_part_one, b_kernel_copy);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("log data copy error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
new_read_addr = (data_part_one >= *copy_len) ? (msg_info_now->read + *copy_len) : (*copy_len - data_part_one);
|
|
new_read_addr = (new_read_addr >= msg_info_now->buf_size) ? (0) : (new_read_addr);
|
|
|
|
return new_read_addr;
|
|
}
|
|
|
|
static td_s32 log_buffer_read(td_u8 *buf, td_u32 buf_len, td_u32 *p_copy_len, td_bool b_kernel_copy)
|
|
{
|
|
log_buf_info msg_info_now;
|
|
unsigned long flags;
|
|
td_s32 ret;
|
|
errno_t err_ret;
|
|
|
|
spin_lock_irqsave(&g_log_lock, flags);
|
|
err_ret = memcpy_s(&msg_info_now, sizeof(log_buf_info), &g_log_msg_info, sizeof(g_log_msg_info));
|
|
spin_unlock_irqrestore(&g_log_lock, flags);
|
|
if (err_ret != EOK) {
|
|
soc_log_err("secure func call error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = log_read_data(buf, buf_len, &msg_info_now, p_copy_len, b_kernel_copy);
|
|
if (ret < 0) {
|
|
soc_log_err("call log_read_data error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
spin_lock_irqsave(&g_log_lock, flags);
|
|
g_log_store_info.store_log_len -= *p_copy_len;
|
|
if (msg_info_now.reset_cnt == g_log_msg_info.reset_cnt) {
|
|
g_log_msg_info.read = (td_u32)ret;
|
|
}
|
|
spin_unlock_irqrestore(&g_log_lock, flags);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_drv_log_read_buf(td_u8 *buf, td_u32 buf_len, td_u32 *copy_len, td_bool *status,
|
|
td_bool is_kernel_copy)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (g_log_msg_info.buf_size == 0) {
|
|
soc_log_err("Log Buffer size is 0, Please confige the Buffer size, for example:");
|
|
soc_log_err(" Config buffer size 500K: insmod soc_cmpi.ko g_log_buf_size = 0x80000");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (buf == TD_NULL) {
|
|
soc_log_err("buf is null\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (status == TD_NULL) {
|
|
soc_log_err("status is null\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
*status = g_log_store_info.store_log_enable;
|
|
|
|
if (g_log_msg_info.write == g_log_msg_info.read) {
|
|
if (g_set_log_file_flag == TD_TRUE || g_log_store_info.store_log_enable == TD_TRUE) {
|
|
return TD_FAILURE;
|
|
} else {
|
|
/* the following code segment will pending when reboot or reload ko */
|
|
ret = osal_wait_timeout_interruptible(&g_log_msg_info.wq_no_data, drv_log_wait_condition,
|
|
&g_log_msg_info, LOG_WAIT_DATA_TIMEOUT);
|
|
if (ret == 0 && (g_log_msg_info.write == g_log_msg_info.read)) {
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = log_buffer_read(buf, buf_len, copy_len, is_kernel_copy);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("call log_buffer_read failed !\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_write(const td_u8 *buf, td_u32 copy_len1,
|
|
td_u32 copy_len2, td_u32 msg_from_pos, td_u32 new_write_addr)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (copy_len1 > 0) {
|
|
if (msg_from_pos == LOG_MSG_FROM_KERNEL) {
|
|
ret = memcpy_s((g_log_msg_info.write + g_log_msg_info.start_virt_addr),
|
|
g_log_msg_info.buf_size - g_log_msg_info.write, buf, copy_len1);
|
|
if (ret != EOK) {
|
|
soc_log_err("memcpy_s error !\n");
|
|
return TD_FAILURE;
|
|
}
|
|
} else {
|
|
if (osal_copy_from_user((g_log_msg_info.write + g_log_msg_info.start_virt_addr), buf, copy_len1)) {
|
|
soc_log_err("copy_from_user error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (copy_len2 > 0) {
|
|
if (msg_from_pos == LOG_MSG_FROM_KERNEL) {
|
|
ret = memcpy_s(g_log_msg_info.start_virt_addr, g_log_msg_info.buf_size, (buf + copy_len1), copy_len2);
|
|
if (ret != EOK) {
|
|
soc_log_err("memcpy_s error !\n");
|
|
return TD_FAILURE;
|
|
}
|
|
} else {
|
|
if (osal_copy_from_user(g_log_msg_info.start_virt_addr, (buf + copy_len1), copy_len2)) {
|
|
soc_log_err("copy_from_user error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
|
|
g_log_msg_info.write = new_write_addr;
|
|
|
|
if (g_set_log_file_flag != TD_TRUE || g_log_store_info.store_log_enable != TD_TRUE) {
|
|
osal_wait_wakeup(&g_log_msg_info.wq_no_data);
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_drv_log_write_buf(const td_u8 *buf, td_u32 msg_len, td_u32 msg_from_pos)
|
|
{
|
|
td_u32 copy_len1, copy_len2, new_write_addr, cond;
|
|
td_ulong flags;
|
|
td_s32 ret;
|
|
|
|
/* not support log when uart close or user version */
|
|
#if defined (CONFIG_CLOSE_UART0) || defined (ANDROID_BUILD_USER)
|
|
return TD_SUCCESS;
|
|
#endif
|
|
if (osal_get_buildvariant() == OSAL_BUILDVARIANT_USER) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
cond = ((g_log_msg_info.buf_size == 0) || (buf == TD_NULL || msg_len >= g_log_buf_size));
|
|
if (cond) {
|
|
soc_log_err("param invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
spin_lock_irqsave(&g_log_lock, flags);
|
|
g_log_store_info.store_log_len += msg_len;
|
|
spin_unlock_irqrestore(&g_log_lock, flags);
|
|
|
|
if (g_log_store_info.store_log_len > STORE_LOG_WAKE_UP_SIZE) {
|
|
g_log_store_info.store_log_poll_new = TD_TRUE;
|
|
osal_wait_wakeup(&g_log_store_info.poll_wait_queue);
|
|
}
|
|
if (g_log_msg_info.write < g_log_msg_info.read) {
|
|
if ((g_log_msg_info.read - g_log_msg_info.write) < LOG_MSG_BUF_RESERVE) {
|
|
drv_log_reset_buf();
|
|
}
|
|
} else {
|
|
if ((g_log_msg_info.write - g_log_msg_info.read) > (g_log_msg_info.buf_size - LOG_MSG_BUF_RESERVE)) {
|
|
drv_log_reset_buf();
|
|
}
|
|
}
|
|
|
|
if ((msg_len + g_log_msg_info.write) >= g_log_msg_info.buf_size) {
|
|
copy_len1 = g_log_msg_info.buf_size - g_log_msg_info.write;
|
|
copy_len2 = msg_len - copy_len1;
|
|
new_write_addr = copy_len2;
|
|
} else {
|
|
copy_len1 = msg_len;
|
|
copy_len2 = 0;
|
|
new_write_addr = msg_len + g_log_msg_info.write;
|
|
}
|
|
|
|
/*
|
|
* protect with semaphore while two module write at the same time
|
|
* CNcomment: 两个模块同时写要做信号量保护
|
|
*/
|
|
spin_lock_irqsave(&g_log_lock, flags);
|
|
ret = drv_log_write(buf, copy_len1, copy_len2, msg_from_pos, new_write_addr);
|
|
if (ret != TD_SUCCESS) {
|
|
spin_unlock_irqrestore(&g_log_lock, flags);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
spin_unlock_irqrestore(&g_log_lock, flags);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void log_get_rtc_time(td_char *rtc_time, td_u32 len)
|
|
{
|
|
osal_rtc_time tm = {0};
|
|
osal_timeval tv;
|
|
td_u32 cur_usec;
|
|
td_s32 ret;
|
|
|
|
if (rtc_time == TD_NULL) {
|
|
soc_log_err("rtc_time is null\n");
|
|
return;
|
|
}
|
|
/* 获取当前的UTC时间 */
|
|
osal_gettimeofday(&tv);
|
|
|
|
/* 把UTC时间调整为本地时间 */
|
|
tv.tv_sec -= sys_tz.tz_minuteswest * 60; /* 60 表示min与s的换算关系 */
|
|
|
|
/* 算出时间中的年月日等数值到tm中 */
|
|
osal_rtc_time_to_tm(tv.tv_sec, &tm);
|
|
cur_usec = (td_u32)tv.tv_usec / 1000; /* 1000 表示s/ms/us的换算关系 */
|
|
ret = snprintf_s(rtc_time, len, LOG_RTC_TIME_LENGH, "%02d-%02d %02d:%02d:%02d.%03d", tm.tm_mon + 1,
|
|
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, cur_usec);
|
|
if (ret < 0) {
|
|
soc_print("call snprintf_s failed!\n");
|
|
return;
|
|
}
|
|
rtc_time[LOG_RTC_TIME_LENGH - 1] = ' ';
|
|
return;
|
|
}
|
|
|
|
td_s32 drv_log_add_module(const td_char *name, td_u32 mod_id)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (name == TD_NULL || g_log_cfg_info == TD_NULL || mod_id >= LOG_CFG_BUF_SIZE / sizeof(log_cfg_info)) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = strncpy_s(g_log_cfg_info[mod_id].module_name, sizeof(g_log_cfg_info[mod_id].module_name),
|
|
name, strlen(name));
|
|
if (ret != EOK) {
|
|
soc_log_err("strncpy_s failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
g_log_cfg_info[mod_id].module_name[sizeof(g_log_cfg_info[mod_id].module_name) - 1] = '\0';
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
#define DEFAULT_LOG_QUOTA (12288)
|
|
td_s32 drv_log_remove_module(td_u32 mod_id)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (g_log_cfg_info == TD_NULL || mod_id >= LOG_CFG_BUF_SIZE / sizeof(log_cfg_info)) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_log_cfg_info[mod_id].log_level = (td_u8)g_default_log_level;
|
|
g_log_cfg_info[mod_id].log_print_pos = LOG_OUTPUT_SERIAL;
|
|
g_log_cfg_info[mod_id].log_quota = DEFAULT_LOG_QUOTA;
|
|
ret = snprintf_s(g_log_cfg_info[mod_id].module_name, sizeof(g_log_cfg_info[mod_id].module_name),
|
|
strlen("Invalid"), "Invalid");
|
|
if (ret < 0) {
|
|
soc_log_err("snprintf_s failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
g_log_cfg_info[mod_id].module_name[sizeof(g_log_cfg_info[mod_id].module_name) - 1] = '\0';
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void drv_log_set_module(td_u32 mod_id)
|
|
{
|
|
td_s32 ret;
|
|
module_detail_info module_data;
|
|
|
|
if (g_log_cfg_info == TD_NULL || mod_id >= LOG_CFG_BUF_SIZE / sizeof(log_cfg_info)) {
|
|
return;
|
|
}
|
|
|
|
ret = ext_drv_module_get_data(mod_id, &module_data);
|
|
if (ret != TD_SUCCESS) {
|
|
(td_void)drv_log_remove_module(mod_id);
|
|
/* use log info debug, beacuse of the module number is larger than register so some module id we cannot find. */
|
|
soc_log_info("invaild or do not register module id :%d \n", mod_id);
|
|
return;
|
|
}
|
|
|
|
ret = drv_log_add_module(module_data.name, mod_id);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_info("add module failed. mod_id:%d, name :%s\n", module_data.name, mod_id);
|
|
}
|
|
}
|
|
|
|
/* TD_TRUE: need print; TD_FALSE: not print */
|
|
static td_void log_level_check(td_u32 level, td_u32 mod_id, log_level_t *log_level)
|
|
{
|
|
td_u8 current_level;
|
|
|
|
if (mod_id >= (LOG_CFG_BUF_SIZE / sizeof(log_cfg_info))) {
|
|
soc_print("mod_id invalid !\n");
|
|
return;
|
|
}
|
|
/* log module has initialized yet */
|
|
if (likely(g_log_init)) {
|
|
log_level->bbox_level = (level == SOC_LOG_LEVEL_ALERT) ? (TD_TRUE) : (TD_FALSE);
|
|
current_level = g_log_cfg_info[mod_id].log_level;
|
|
if (current_level == SOC_LOG_LEVEL_TRACE) {
|
|
log_level->general_level = (level == SOC_LOG_LEVEL_TRACE) ? (TD_TRUE) : (TD_FALSE);
|
|
log_level->memory_level = log_level->general_level;
|
|
return;
|
|
}
|
|
if (likely(current_level <= g_default_log_level)) {
|
|
if (likely(level > SOC_LOG_LEVEL_INFO)) {
|
|
return;
|
|
}
|
|
|
|
if (level <= current_level) {
|
|
log_level->memory_level = TD_TRUE;
|
|
log_level->general_level = TD_TRUE;
|
|
}
|
|
} else {
|
|
if (level <= current_level) {
|
|
log_level->general_level = TD_TRUE;
|
|
log_level->memory_level = TD_TRUE;
|
|
}
|
|
}
|
|
} else {
|
|
/* log module has not initialized yet */
|
|
if (level <= g_default_log_level) {
|
|
log_level->general_level = TD_TRUE;
|
|
log_level->memory_level = TD_TRUE;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/* 0: seria port, 1: network */
|
|
static td_u32 drv_log_get_print_pos(td_u32 mod_id)
|
|
{
|
|
td_u32 pos;
|
|
|
|
if (mod_id >= LOG_CFG_BUF_SIZE / sizeof(log_cfg_info)) {
|
|
return LOG_OUTPUT_SERIAL;
|
|
}
|
|
|
|
if (g_log_init == TD_FALSE) {
|
|
return LOG_OUTPUT_SERIAL;
|
|
}
|
|
|
|
if (g_set_log_file_flag == TD_TRUE) {
|
|
pos = LOG_OUTPUT_UDISK;
|
|
} else {
|
|
pos = g_log_cfg_info[mod_id].log_print_pos;
|
|
}
|
|
|
|
return pos;
|
|
}
|
|
|
|
#ifdef CONFIG_SOCT_LOG_UDISK_SUPPORT
|
|
td_s32 drv_log_udisk_save(const td_s8 *file_name, const td_s8 *data, td_u32 data_len)
|
|
{
|
|
td_s32 write_len, ret;
|
|
void *file = NULL;
|
|
errno_t err_ret;
|
|
static td_char cur_file_name[LOG_MAX_FILE_NAME_LENTH] = {0};
|
|
|
|
if (file_name == TD_NULL) {
|
|
soc_log_err("file_name is null\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (strlen(file_name) < strlen(cur_file_name)) {
|
|
err_ret = memset_s(cur_file_name, LOG_MAX_FILE_NAME_LENTH, 0, sizeof(cur_file_name));
|
|
if (err_ret != EOK) {
|
|
soc_log_err("secure func call error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
if (g_log_write_len_count > g_default_log_size) {
|
|
g_log_file_count++;
|
|
g_log_file_count = (g_log_file_count > LOG_MAX_FILE_CNT) ? (0) : (g_log_file_count);
|
|
}
|
|
ret = snprintf_s(cur_file_name, LOG_MAX_FILE_NAME_LENTH, LOG_MAX_FILE_NAME_LENTH - 1,
|
|
"%s.%d", file_name, g_log_file_count);
|
|
if (ret < 0) {
|
|
soc_log_err("call snprintf_s failed.\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (g_log_write_len_count > g_default_log_size) {
|
|
file = osal_klib_fopen(cur_file_name, OSAL_O_RDWR | OSAL_O_CREAT | OSAL_O_TRUNC, 0644); /* 0644 is authority */
|
|
if (file == NULL) {
|
|
soc_log_err("osal_klib_fopen %s failure...................\n", cur_file_name);
|
|
return TD_FAILURE;
|
|
}
|
|
osal_klib_fclose(file);
|
|
g_log_write_len_count = 0;
|
|
}
|
|
|
|
file = osal_klib_fopen(cur_file_name, OSAL_O_RDWR | OSAL_O_CREAT | OSAL_O_APPEND, 0644); /* 0644 is authority */
|
|
if (file == NULL) {
|
|
soc_log_err("osal_klib_fopen %s failure...................\n", cur_file_name);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
write_len = osal_klib_fwrite(data, data_len, file);
|
|
g_log_write_len_count += (unsigned int)write_len;
|
|
|
|
osal_klib_fclose(file);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static osal_task *g_udisk_task = TD_NULL;
|
|
static td_u8 g_udisk_buf[LOG_MSG_BUF_RESERVE] = {0};
|
|
static td_u8 g_udisk_file_name[LOG_MAX_FILE_NAME_LENTH] = {0};
|
|
|
|
td_s32 drv_log_udisk_write_thread(td_void *arg)
|
|
{
|
|
td_u32 read_len = 0;
|
|
td_s32 ret;
|
|
td_bool set_file_flag;
|
|
td_bool status = TD_FALSE;
|
|
errno_t err_ret;
|
|
td_u8 *udisk_log_file = (td_u8 *)arg;
|
|
|
|
if (udisk_log_file == TD_NULL) {
|
|
soc_log_err("input arg udisk_log_file is NULL.. \n");
|
|
return TD_FAILURE;
|
|
}
|
|
ret = snprintf_s(g_udisk_file_name, sizeof(g_udisk_file_name),
|
|
sizeof(g_udisk_file_name) - 1, "%s/stb.log", (const td_s8*)udisk_log_file);
|
|
if (ret < 0 ||
|
|
(strlen(g_udisk_file_name) - strlen("stb.log")) < 0 ||
|
|
strncmp(g_udisk_file_name + (strlen(g_udisk_file_name) - strlen("stb.log")),
|
|
"stb.log", strlen("stb.log")) != 0) {
|
|
soc_log_err("snprintf_s fail or file_name invalid [%s]!\n", g_udisk_file_name);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
while (1) {
|
|
set_file_flag = g_set_log_file_flag;
|
|
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
if (osal_kthread_should_stop()) {
|
|
break;
|
|
}
|
|
|
|
if (set_file_flag == TD_FALSE) {
|
|
osal_msleep(10); /* 10ms polling */
|
|
continue;
|
|
}
|
|
|
|
ret = log_store_lock();
|
|
err_ret = memset_s(g_udisk_buf, sizeof(g_udisk_buf), 0, sizeof(g_udisk_buf));
|
|
if (err_ret != EOK) {
|
|
soc_log_err("secure func call error\n");
|
|
log_store_unlock();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_drv_log_read_buf(g_udisk_buf, sizeof(g_udisk_buf) - 1, &read_len, &status, TD_TRUE);
|
|
if (ret == TD_SUCCESS) {
|
|
drv_log_udisk_save((const td_s8 *)g_udisk_file_name, g_udisk_buf, read_len);
|
|
soc_log_info("b_status = %d\n", status);
|
|
}
|
|
log_store_unlock();
|
|
|
|
osal_msleep(10); /* save log every 10ms */
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 drv_log_udisk_init(const td_u8 *disk_folder)
|
|
{
|
|
if (disk_folder == TD_NULL) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (g_udisk_task == TD_NULL) {
|
|
g_udisk_task = osal_kthread_create(drv_log_udisk_write_thread, (td_void *)disk_folder, "g_udisk_task", 0);
|
|
if (g_udisk_task == TD_NULL) {
|
|
soc_log_err("create new kernel thread failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 drv_log_udisk_exit(td_void)
|
|
{
|
|
if (g_udisk_task != TD_NULL) {
|
|
osal_kthread_destroy(g_udisk_task, TD_TRUE);
|
|
g_udisk_task = TD_NULL;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
td_void soc_log_simple_print(const td_char *format, ...)
|
|
{
|
|
va_list args;
|
|
td_u32 msg_len;
|
|
td_char log_str[LOG_MAX_TRACE_LEN] = {'a'};
|
|
|
|
log_str[LOG_MAX_TRACE_LEN - 0x1] = 'b';
|
|
log_str[LOG_MAX_TRACE_LEN - 0x2] = 'c';
|
|
|
|
va_start(args, format);
|
|
msg_len = (td_u32)vsnprintf_s(log_str, sizeof(log_str), LOG_MAX_TRACE_LEN - 1, format, args);
|
|
va_end(args);
|
|
if (msg_len < 0) {
|
|
return;
|
|
}
|
|
|
|
if (msg_len >= LOG_MAX_TRACE_LEN) {
|
|
log_str[LOG_MAX_TRACE_LEN - 0x1] = '\0'; /* even the 'vsnprintf' commond will do it */
|
|
log_str[LOG_MAX_TRACE_LEN - 0x2] = '\n';
|
|
log_str[LOG_MAX_TRACE_LEN - 0x3] = '.';
|
|
log_str[LOG_MAX_TRACE_LEN - 0x4] = '.';
|
|
log_str[LOG_MAX_TRACE_LEN - 0x5] = '.';
|
|
}
|
|
|
|
soc_print("%s", log_str);
|
|
}
|
|
|
|
td_void soc_log_print_block(td_u32 level, td_u32 module_id, const td_char *block, td_u32 size)
|
|
{
|
|
errno_t err_ret;
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
td_char str_out[LOG_BLOCK_BUFSIZE] = {0};
|
|
|
|
if (block == NULL) {
|
|
return;
|
|
}
|
|
for (i = 0; i < size; i++) {
|
|
ret = snprintf_s(&str_out[(i % LOG_BLOCK_PERLINE) * 3], /* 3 is offset */
|
|
(LOG_BLOCK_BUFSIZE - (i % LOG_BLOCK_PERLINE) * 3), 4, " %02X", block[i]); /* 4,3 is countsize */
|
|
if (ret == -1) {
|
|
soc_print("snprintf_s failed!!!");
|
|
return;
|
|
}
|
|
if (((i + 1) % LOG_BLOCK_PERLINE) == 0) {
|
|
soc_trace(level, module_id, " %s\n", str_out);
|
|
err_ret = memset_s(str_out, sizeof(str_out), 0x00, sizeof(str_out));
|
|
if (err_ret != EOK) {
|
|
soc_print("memset_s failed!!!");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (((i % LOG_BLOCK_PERLINE) != 0) && (i != 0)) {
|
|
soc_trace(level, module_id, " %s\n", str_out);
|
|
}
|
|
}
|
|
|
|
static td_void drv_log_adjust_str(char *log_str, td_u32 str_len, td_u32 log_cnt)
|
|
{
|
|
if ((log_str != TD_NULL) && (unlikely(log_cnt >= str_len))) {
|
|
log_str[LOG_MAX_TRACE_LEN - 1] = '\0'; /* even the 'vsnprintf' commond will do it */
|
|
log_str[LOG_MAX_TRACE_LEN - 2] = '\n'; /* 2 表示log_str向左偏移2个字节 */
|
|
log_str[LOG_MAX_TRACE_LEN - 3] = '.'; /* 3 表示log_str向左偏移3个字节 */
|
|
log_str[LOG_MAX_TRACE_LEN - 4] = '.'; /* 4 表示log_str向左偏移4个字节 */
|
|
log_str[LOG_MAX_TRACE_LEN - 5] = '.'; /* 5 表示log_str向左偏移5个字节 */
|
|
log_cnt = LOG_MAX_TRACE_LEN;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static td_void drv_log_print(soc_mod_id mod_id, log_level_t *log_level,
|
|
char *log_str, td_u32 str_len, td_u32 log_cnt)
|
|
{
|
|
td_u32 n_pos;
|
|
|
|
if (log_level->bbox_level == TD_TRUE) {
|
|
log_get_rtc_time(log_str, str_len);
|
|
rdr_print_to_file("%s", log_str);
|
|
return;
|
|
}
|
|
|
|
n_pos = drv_log_get_print_pos(mod_id);
|
|
switch (n_pos) {
|
|
case LOG_OUTPUT_SERIAL:
|
|
if ((mod_id == SOC_ID_VSYNC) || (mod_id == SOC_ID_ASYNC)) {
|
|
break;
|
|
}
|
|
|
|
if (g_log_store_info.store_log_enable == TD_TRUE && log_level->memory_level == TD_TRUE) {
|
|
log_get_rtc_time(log_str, str_len);
|
|
ext_drv_log_write_buf((td_u8 *)log_str, log_cnt, LOG_MSG_FROM_KERNEL);
|
|
}
|
|
|
|
if (log_level->general_level == TD_TRUE) {
|
|
log_get_rtc_time(log_str, str_len);
|
|
soc_print("%s", log_str);
|
|
}
|
|
break;
|
|
|
|
case LOG_OUTPUT_NETWORK:
|
|
case LOG_OUTPUT_UDISK:
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
if (log_level->general_level == TD_TRUE) {
|
|
log_get_rtc_time(log_str, str_len);
|
|
ext_drv_log_write_buf((td_u8 *)log_str, log_cnt, LOG_MSG_FROM_KERNEL);
|
|
}
|
|
#endif
|
|
break;
|
|
default:
|
|
soc_print("output pos %d invalid!\n", n_pos);
|
|
}
|
|
return;
|
|
}
|
|
|
|
static td_u32 soc_log_print_msg_process(char *log_serial, td_u32 level,
|
|
td_u32 mod_id, const td_u8 *fn_name, td_u32 line_num)
|
|
{
|
|
td_s32 msg_len = 0;
|
|
td_u32 buff_len = LOG_MAX_TRACE_LEN - LOG_RTC_TIME_LENGH;
|
|
|
|
if (log_serial == NULL || fn_name == NULL) {
|
|
soc_print("soc_log_print_msg_process input null\n");
|
|
return 0;
|
|
}
|
|
|
|
if (likely(g_log_init)) {
|
|
msg_len = snprintf_s(log_serial, buff_len, buff_len - 1,
|
|
"[%s-%s]:%s[%d]:", g_debug_level_name[level], g_log_cfg_info[mod_id].module_name, fn_name, line_num);
|
|
if (msg_len < 0) {
|
|
soc_print("soc_log_print_msg_process snprintf_s --failed\n");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return (td_u32)msg_len;
|
|
}
|
|
|
|
td_void soc_log_print(td_u32 level, td_u32 mod_id, const td_u8 *fn_name, td_u32 line_num,
|
|
const td_char *format, ...)
|
|
{
|
|
va_list args;
|
|
td_u32 msg_len;
|
|
char log_str[LOG_MAX_TRACE_LEN] = {'a'};
|
|
td_u32 log_cnt = LOG_RTC_TIME_LENGH;
|
|
char *log_serial = log_str + LOG_RTC_TIME_LENGH;
|
|
char *log_msg_pos = TD_NULL;
|
|
td_u32 buff_len = LOG_MAX_TRACE_LEN - LOG_RTC_TIME_LENGH;
|
|
log_level_t log_level = { TD_FALSE, TD_FALSE, TD_FALSE };
|
|
|
|
if ((level > SOC_LOG_LEVEL_MAX) ||
|
|
(mod_id >= (LOG_CFG_BUF_SIZE / sizeof(log_cfg_info))) ||
|
|
(fn_name == TD_NULL)) {
|
|
soc_print("ERR: invalid param, level:%#x, mod_id:%#x, fn_name:%p\n", level, mod_id, fn_name);
|
|
return;
|
|
}
|
|
|
|
log_level_check(level, mod_id, &log_level);
|
|
if (unlikely(log_level.memory_level == TD_TRUE || log_level.general_level == TD_TRUE)) {
|
|
msg_len = soc_log_print_msg_process(log_serial, level, mod_id, fn_name, line_num);
|
|
log_cnt += msg_len;
|
|
|
|
log_str[LOG_MAX_TRACE_LEN - 1] = 'b';
|
|
log_str[LOG_MAX_TRACE_LEN - 2] = 'c'; /* 2 表示log_str向左偏移2个字节 */
|
|
|
|
if (likely(buff_len > msg_len)) {
|
|
log_msg_pos = log_serial + msg_len;
|
|
buff_len = buff_len - msg_len;
|
|
va_start(args, format);
|
|
msg_len = (td_u32)vsnprintf_s(log_msg_pos, buff_len, buff_len - 1, format, args);
|
|
if (msg_len < 0) {
|
|
va_end(args);
|
|
return;
|
|
}
|
|
va_end(args);
|
|
log_cnt += msg_len;
|
|
}
|
|
|
|
drv_log_adjust_str(log_str, LOG_MAX_TRACE_LEN, log_cnt);
|
|
|
|
if (unlikely(g_log_init == 0)) {
|
|
/* log module has not Initialized. */
|
|
soc_print("[%s-Unknow]: %s[%d]:%s", g_debug_level_name[level], fn_name, line_num, log_msg_pos);
|
|
return;
|
|
}
|
|
|
|
/* log module has initialized. */
|
|
drv_log_print(mod_id, &log_level, log_str, LOG_MAX_TRACE_LEN, log_cnt);
|
|
}
|
|
return;
|
|
}
|
|
|
|
td_s32 drv_log_set_path(const td_char *path, td_u32 path_len, td_bool is_user_state)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (path == TD_NULL || path_len >= sizeof(g_log_path_buf)) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = log_file_lock();
|
|
if (ret != 0) {
|
|
soc_log_err("down_interruptible failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
(td_void)memset_s(g_log_path_buf, sizeof(g_log_path_buf), 0, sizeof(g_log_path_buf));
|
|
|
|
if (is_user_state == TD_TRUE) {
|
|
ret = (td_s32)osal_copy_from_user(g_log_path_buf, path, path_len);
|
|
} else {
|
|
ret = memcpy_s(g_log_path_buf, sizeof(g_log_path_buf), path, path_len);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
log_file_unlock();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (memcmp(g_log_path_buf, "/dev/null", strlen("/dev/null")) == 0) {
|
|
g_set_log_file_flag = TD_FALSE;
|
|
} else {
|
|
g_set_log_file_flag = TD_TRUE;
|
|
}
|
|
|
|
g_log_cfg_info->udisk_flag = (td_u8)g_set_log_file_flag;
|
|
|
|
g_udisk_log_file = g_log_path_buf;
|
|
|
|
log_file_unlock();
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_drv_log_get_path(td_s8 *buf, td_u32 buf_len)
|
|
{
|
|
td_u32 path_len;
|
|
td_s32 ret;
|
|
/* not support log when uart close or user version */
|
|
#if defined (CONFIG_CLOSE_UART0) || defined (ANDROID_BUILD_USER)
|
|
return TD_SUCCESS;
|
|
#endif
|
|
if (osal_get_buildvariant() == OSAL_BUILDVARIANT_USER) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
if (g_udisk_log_file == TD_NULL) {
|
|
soc_log_err("g_udisk_log_file is NULL!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (buf == TD_NULL) {
|
|
soc_log_err("buf is NULL!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
path_len = strlen(g_udisk_log_file) + 1;
|
|
if (path_len > buf_len) {
|
|
soc_log_err("path len is lager than buf len!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (path_len == 1) {
|
|
soc_log_info("no redirect to file!\n");
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
ret = memcpy_s(buf, buf_len, g_udisk_log_file, path_len);
|
|
if (ret != EOK) {
|
|
soc_log_err("memcpy_s fail\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 drv_log_set_store_path(const td_char *path, td_u32 path_len, td_bool is_user_state)
|
|
{
|
|
td_s32 ret;
|
|
|
|
/* not support log when uart close or user version */
|
|
#if defined (CONFIG_CLOSE_UART0) || defined (ANDROID_BUILD_USER)
|
|
return TD_SUCCESS;
|
|
#endif
|
|
if (osal_get_buildvariant() == OSAL_BUILDVARIANT_USER) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
if (path == TD_NULL || path_len >= sizeof(g_store_path_buf)) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = log_file_lock();
|
|
if (ret != 0) {
|
|
soc_log_err("down_interruptible failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
(td_void)memset_s(g_store_path_buf, sizeof(g_store_path_buf), 0, sizeof(g_store_path_buf));
|
|
|
|
if (is_user_state == TD_TRUE) {
|
|
ret = (td_s32)osal_copy_from_user(g_store_path_buf, path, path_len);
|
|
} else {
|
|
ret = memcpy_s(g_store_path_buf, sizeof(g_store_path_buf), path, path_len);
|
|
}
|
|
|
|
if (ret != 0) {
|
|
log_file_unlock();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_store_path = g_store_path_buf;
|
|
log_file_unlock();
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_drv_log_get_store_path(td_s8 *buf, td_u32 buf_len)
|
|
{
|
|
td_u32 path_len;
|
|
td_s32 ret;
|
|
|
|
if (g_store_path == TD_NULL || buf == TD_NULL) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
path_len = strlen(g_store_path) + 1;
|
|
if (path_len > buf_len || path_len <= 1) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = memcpy_s(buf, buf_len, g_store_path, path_len);
|
|
if (ret != EOK) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_drv_log_set_size(td_u32 size)
|
|
{
|
|
td_s32 ret;
|
|
|
|
if (size > LOG_MAX_FILE_SIZE || size < LOG_MIN_FILE_SIZE) {
|
|
soc_log_err("Logsize(%dMB) is out of range(%dMB~%dMB)\n", size, LOG_MIN_FILE_SIZE, LOG_MAX_FILE_SIZE);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = log_file_lock();
|
|
if (ret != 0) {
|
|
soc_log_err("down_interruptible failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_default_log_size = size * 1024 * 1024; /* 1024 * 1024 means 1k */
|
|
|
|
log_file_unlock();
|
|
|
|
soc_log_info("set log file size as %d MB\n", g_default_log_size);
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 ext_drv_log_get_level(td_u32 mod_id, soc_log_level *log_level)
|
|
{
|
|
if (g_log_init == TD_FALSE || mod_id >= LOG_CFG_BUF_SIZE / sizeof(log_cfg_info) || log_level == TD_NULL) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
*log_level = (soc_log_level)g_log_cfg_info[mod_id].log_level;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_cfg_info_init(td_void)
|
|
{
|
|
td_u32 i;
|
|
td_s32 ret;
|
|
|
|
g_log_cfg_buf.dmabuf = osal_mem_alloc("CMN_LogInfo", LOG_CFG_BUF_SIZE, OSAL_MMZ_TYPE, TD_NULL, 0);
|
|
if (IS_ERR_OR_NULL(g_log_cfg_buf.dmabuf)) {
|
|
soc_log_err("osal_mem_alloc failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_log_cfg_buf.virt_addr = (td_u8 *)osal_mem_kmap(g_log_cfg_buf.dmabuf, 0, TD_FALSE);
|
|
if (IS_ERR_OR_NULL(g_log_cfg_buf.virt_addr)) {
|
|
osal_mem_free(g_log_cfg_buf.dmabuf);
|
|
soc_log_err("dma_buf_kmap failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
osal_mem_flush(g_log_cfg_buf.dmabuf);
|
|
|
|
ret = memset_s(g_log_cfg_buf.virt_addr, LOG_CFG_BUF_SIZE, 0, LOG_CFG_BUF_SIZE);
|
|
if (ret != EOK) {
|
|
osal_mem_free(g_log_cfg_buf.dmabuf);
|
|
soc_log_err("memset_s error!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_log_cfg_info = (log_cfg_info *)g_log_cfg_buf.virt_addr;
|
|
g_log_cfg_info->udisk_flag = 0;
|
|
|
|
/* max debug module number: 8192/28 = 341/292 */
|
|
for (i = 0; i < LOG_CFG_BUF_SIZE / sizeof(log_cfg_info); i++) {
|
|
g_log_cfg_info[i].log_level = (td_u8)g_default_log_level;
|
|
g_log_cfg_info[i].log_print_pos = LOG_OUTPUT_SERIAL;
|
|
g_log_cfg_info[i].log_quota = DEFAULT_LOG_QUOTA;
|
|
ret = snprintf_s(g_log_cfg_info[i].module_name, sizeof(g_log_cfg_info[i].module_name),
|
|
sizeof(g_log_cfg_info[i].module_name) - 1, "Invalid");
|
|
if (ret < 0) {
|
|
osal_mem_free(g_log_cfg_buf.dmabuf);
|
|
soc_log_err("snprintf_s error!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_cfg_info_exit(td_void)
|
|
{
|
|
if (g_log_cfg_buf.virt_addr != 0) {
|
|
osal_mem_kunmap(g_log_cfg_buf.dmabuf, (td_void *)g_log_cfg_buf.virt_addr, 0);
|
|
osal_mem_free(g_log_cfg_buf.dmabuf);
|
|
g_log_cfg_info = TD_NULL;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
static td_s32 drv_log_buf_init(td_u32 size)
|
|
{
|
|
(td_void)memset_s(&g_log_msg_info, sizeof(g_log_msg_info), 0, sizeof(g_log_msg_info));
|
|
|
|
g_log_msg_info.buf_size = size;
|
|
|
|
osal_wait_init(&g_log_msg_info.wq_no_data);
|
|
g_log_msg_buf.dmabuf = osal_mem_alloc("CMN_LogTrace", size, OSAL_MMZ_TYPE, TD_NULL, 0);
|
|
if (IS_ERR_OR_NULL(g_log_msg_buf.dmabuf)) {
|
|
soc_log_err("ion_alloc_dmabuf failed!\n");
|
|
osal_wait_destroy(&g_log_msg_info.wq_no_data);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_log_msg_buf.virt_addr = (td_u8 *)osal_mem_kmap(g_log_msg_buf.dmabuf, 0, TD_FALSE);
|
|
if (IS_ERR_OR_NULL(g_log_msg_buf.virt_addr)) {
|
|
soc_log_err("dma_buf_kmap failed!\n");
|
|
osal_mem_free(g_log_msg_buf.dmabuf);
|
|
osal_wait_destroy(&g_log_msg_info.wq_no_data);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
(td_void)memset_s(g_log_msg_buf.virt_addr, size, 0, size);
|
|
|
|
g_log_msg_info.start_virt_addr = g_log_msg_buf.virt_addr;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_buf_exit(td_void)
|
|
{
|
|
if (g_log_msg_buf.virt_addr != TD_NULL) {
|
|
osal_mem_kunmap(g_log_msg_buf.dmabuf, (td_void *)g_log_msg_buf.virt_addr, 0);
|
|
osal_mem_free(g_log_msg_buf.dmabuf);
|
|
osal_wait_destroy(&g_log_msg_info.wq_no_data);
|
|
g_log_msg_info.start_virt_addr = TD_NULL;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
static td_s32 drv_log_get_cfg_buf_fd(td_mem_handle_t *fd)
|
|
{
|
|
td_s32 ret = TD_FAILURE;
|
|
td_mem_handle_t buf_fd;
|
|
td_u32 idx;
|
|
td_u32 module_num = LOG_CFG_BUF_SIZE / sizeof(log_cfg_info);
|
|
|
|
/* process register module log feature */
|
|
for (idx = 0; idx < module_num; idx++) {
|
|
drv_log_set_module(idx);
|
|
}
|
|
|
|
if (g_log_init == TD_TRUE && g_log_cfg_buf.dmabuf != TD_NULL) {
|
|
buf_fd = osal_mem_create_fd(g_log_cfg_buf.dmabuf, O_CLOEXEC);
|
|
if (buf_fd < 0) {
|
|
soc_log_err("ext_dma_buf_fd failed!\n");
|
|
*fd = 0;
|
|
} else {
|
|
*fd = buf_fd;
|
|
ret = TD_SUCCESS;
|
|
}
|
|
} else {
|
|
soc_log_err("Log is not init!\n");
|
|
*fd = 0;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static td_s32 drv_log_put_cfg_buf_fd(td_mem_handle_t fd)
|
|
{
|
|
if (fd < 0) {
|
|
soc_log_err("invalid fd!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
osal_mem_close_fd((long)fd);
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 drv_log_init(td_void)
|
|
{
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
ext_chip_name_id chip_name_id;
|
|
#endif
|
|
osal_dts_get_u32_byname("huanglong,common", "log_level", &g_default_log_level);
|
|
if (drv_log_cfg_info_init() != TD_SUCCESS) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
ext_drv_sys_get_chip_name_id(&chip_name_id);
|
|
|
|
/* on reserved5, MMZ size is only 8M, therfore, the size of log MMZ reduce to 512K */
|
|
if ((chip_name_id == CHIP_NAME_RESERVED5) || (chip_name_id == CHIP_NAME_RESERVED2)) {
|
|
g_log_buf_size = 0x80 * LOG_MSG_BUF_RESERVE;
|
|
} else if ((chip_name_id == CHIP_NAME_RESERVED13) || (chip_name_id == CHIP_NAME_RESERVED9) ||
|
|
(chip_name_id == CHIP_NAME_RESERVED6) || (chip_name_id == CHIP_NAME_RESERVED8)) {
|
|
g_log_buf_size = 0xa * 0x100 * LOG_MSG_BUF_RESERVE; /* 10M buf size for NPU save log */
|
|
} else {
|
|
soc_log_info("unspport chip_type chip_version, g_log_bu_size use default value 10M. \n");
|
|
g_log_buf_size = LOG_MSG_BUF_RESERVE;
|
|
}
|
|
|
|
if (drv_log_buf_init(g_log_buf_size) != TD_SUCCESS) {
|
|
drv_log_cfg_info_exit();
|
|
return TD_FAILURE;
|
|
}
|
|
#endif
|
|
|
|
if (drv_log_add_module("ASYNC", (td_u32)SOC_ID_ASYNC) != TD_SUCCESS) {
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
drv_log_buf_exit();
|
|
#endif
|
|
drv_log_cfg_info_exit();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (drv_log_add_module("VSYNC", (td_u32)SOC_ID_VSYNC) != TD_SUCCESS) {
|
|
drv_log_remove_module((td_u32)SOC_ID_ASYNC);
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
drv_log_buf_exit();
|
|
#endif
|
|
drv_log_cfg_info_exit();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_log_init = TD_TRUE;
|
|
osal_sem_init(&g_log_k_mutex, 1);
|
|
osal_sem_init(&g_log_store_mutex, 1);
|
|
osal_wait_init(&g_log_store_info.poll_wait_queue);
|
|
osal_klib_set_store_path(g_store_path);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void drv_log_exit(td_void)
|
|
{
|
|
g_log_init = TD_FALSE;
|
|
osal_sem_destroy(&g_log_k_mutex);
|
|
osal_sem_destroy(&g_log_store_mutex);
|
|
osal_wait_destroy(&g_log_store_info.poll_wait_queue);
|
|
|
|
#ifdef CONFIG_SOCT_LOG_UDISK_SUPPORT
|
|
if (drv_log_udisk_exit() != TD_SUCCESS) {
|
|
soc_log_err("drv_log_udisk_exit error!\n");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
if (drv_log_buf_exit() != TD_SUCCESS) {
|
|
soc_log_err("drv_log_buf_exit error!\n");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if (drv_log_cfg_info_exit() != TD_SUCCESS) {
|
|
soc_log_err("drv_log_cfg_info_exit error!\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
#ifndef MODULE
|
|
/* Legacy boot options - nonmodular */
|
|
static td_s32 __init drv_log_get_buf_size(td_char *str)
|
|
{
|
|
g_log_buf_size = simple_strtol(str, TD_NULL, 0);
|
|
soc_log_info("g_log_buf_size = 0x%x\n", g_log_buf_size);
|
|
return 1;
|
|
}
|
|
__setup("g_log_buf_size=", drv_log_get_buf_size);
|
|
#endif
|
|
|
|
EXPORT_SYMBOL(ext_drv_log_read_buf);
|
|
EXPORT_SYMBOL(ext_drv_log_write_buf);
|
|
EXPORT_SYMBOL(ext_drv_log_get_store_path);
|
|
EXPORT_SYMBOL(ext_drv_log_get_level);
|
|
EXPORT_SYMBOL(soc_log_print);
|
|
EXPORT_SYMBOL(soc_log_print_block);
|
|
EXPORT_SYMBOL(soc_log_simple_print);
|
|
|
|
#ifdef MODULE
|
|
module_param(g_log_buf_size, int, S_IRUGO);
|
|
module_param(g_udisk_log_file, charp, S_IRUGO);
|
|
module_param(g_store_path, charp, S_IRUGO);
|
|
EXPORT_SYMBOL(g_store_path);
|
|
#endif
|
|
|
|
static td_s32 drv_log_find_module(const td_char *s)
|
|
{
|
|
td_u32 i;
|
|
td_u32 cnt = LOG_CFG_BUF_SIZE / sizeof(log_cfg_info);
|
|
|
|
for (i = 0; i < cnt; i++) {
|
|
if (!strncasecmp(g_log_cfg_info[i].module_name, s, sizeof(g_log_cfg_info[i].module_name))) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static td_s32 drv_log_process_proc_help(td_u32 argc, td_char(*argv)[PROC_CMD_SINGEL_LENGTH_MAX],
|
|
td_void *private)
|
|
{
|
|
if (g_log_init == TD_FALSE) {
|
|
soc_log_err("Log is not init!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
osal_proc_echo("\n=========================================================log"
|
|
"=============================================================================================\n");
|
|
|
|
osal_proc_echo("echo command para1 para2 path "
|
|
"explanation\n");
|
|
|
|
osal_proc_echo("echo loglevel SOC_DEMUX 2 >/proc/msp/log "
|
|
"modify the log level of the SOC_DEMUX to 2\n");
|
|
osal_proc_echo(" "
|
|
"para1(module_name) para2(0:ALERT 1:FATAL 2:ERROR WARN:3 NOTICE:4 INFO:5 DEBUG:6 TRACE:7)\n");
|
|
|
|
osal_proc_echo("echo loglevel all 2 >/proc/msp/log "
|
|
"modify the log level of all module to 2\n");
|
|
osal_proc_echo(" "
|
|
"para1(module_name) para2(0:ALERT 1:FATAL 2:ERROR WARN:3 NOTICE:4 INFO:5 DEBUG:6 TRACE:7)\n");
|
|
|
|
osal_proc_echo("echo logsize 12 >/proc/msp/log "
|
|
"set log size as 12 MB para1(1M~120MB)\n");
|
|
|
|
osal_proc_echo("echo logpath /tmp >/proc/msp/log "
|
|
"set log path as /tmp para1(log path)\n");
|
|
|
|
osal_proc_echo("echo logpath /dev/null >/proc/msp/log "
|
|
"close log udisk output para1(log path)\n");
|
|
|
|
osal_proc_echo("echo storepath /mnt >/proc/msp/log "
|
|
"set the debug file store path as /mnt para1(store path)\n");
|
|
|
|
osal_proc_echo("============================================================"
|
|
"=============================================================================================\n");
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_process_proc_level(td_u32 argc, td_char(*argv)[PROC_CMD_SINGEL_LENGTH_MAX],
|
|
td_void *private)
|
|
{
|
|
td_char *module = TD_NULL;
|
|
td_u8 level;
|
|
td_s32 idx;
|
|
td_u32 module_num = LOG_CFG_BUF_SIZE / sizeof(log_cfg_info);
|
|
|
|
if (g_log_init == TD_FALSE) {
|
|
soc_log_err("Log is not init!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (argc != 3) { /* the number of required paras is 3 */
|
|
soc_log_err("argc is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
module = argv[1]; /* the first para(1) is module name */
|
|
level = argv[2][0] - '0'; /* the second para(2) is log level */
|
|
if (level >= SOC_LOG_LEVEL_MAX) {
|
|
soc_log_err("level is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (!strncasecmp("all", module, sizeof("all"))) {
|
|
for (idx = 0; idx < module_num; idx++) {
|
|
g_log_cfg_info[idx].log_level = level;
|
|
}
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
idx = drv_log_find_module(module);
|
|
if (idx == -1) {
|
|
soc_log_err("%s is not registered!\n", module);
|
|
return TD_FAILURE;
|
|
}
|
|
g_log_cfg_info[idx].log_level = level;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_process_proc_size(td_u32 argc, td_char(*argv)[PROC_CMD_SINGEL_LENGTH_MAX],
|
|
td_void *private)
|
|
{
|
|
td_u32 log_size;
|
|
|
|
if (g_log_init == TD_FALSE) {
|
|
soc_log_err("Log is not init!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (argc != 2) { /* the number of required paras is 2 */
|
|
soc_log_err("argc is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (strstr(argv[1], "0x") || strstr(argv[1], "0X")) {
|
|
log_size = simple_strtoul(argv[1], TD_NULL, 16); /* the first para(1) is log size, 16 base conversion */
|
|
} else {
|
|
log_size = simple_strtoul(argv[1], TD_NULL, 10); /* the first para(1) is log size, 10 base conversion */
|
|
}
|
|
|
|
if (log_size > LOG_MAX_FILE_SIZE || log_size < LOG_MIN_FILE_SIZE) {
|
|
soc_log_err("size is invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return ext_drv_log_set_size(log_size);
|
|
}
|
|
|
|
td_s32 log_drv_udisk_store_init(td_void)
|
|
{
|
|
#ifdef CONFIG_SOCT_LOG_UDISK_SUPPORT
|
|
td_s32 ret;
|
|
ret = drv_log_udisk_init(g_udisk_log_file);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("call log_udisk_init failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
#endif
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 log_drv_udisk_store_deinit(td_void)
|
|
{
|
|
#ifdef CONFIG_SOCT_LOG_UDISK_SUPPORT
|
|
td_s32 ret;
|
|
g_log_cfg_info->udisk_flag = (td_u8)g_set_log_file_flag;
|
|
soc_log_info("set log path is g_log_path_buf = %s\n", g_udisk_log_file);
|
|
|
|
ret = drv_log_udisk_exit();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_log_err("call drv_log_udisk_exit failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
#endif
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_process_proc_path(td_u32 argc, td_char(*argv)[PROC_CMD_SINGEL_LENGTH_MAX],
|
|
td_void *private)
|
|
{
|
|
td_s32 ret;
|
|
errno_t err_ret;
|
|
|
|
if (argc < 2) { /* argc at least 2 */
|
|
soc_log_err("param invalid! argc = %d\n", argc);
|
|
return TD_FAILURE;
|
|
}
|
|
if (strlen(argv[1]) >= sizeof(g_log_path_buf)) { /* 命令的第1个参数 */
|
|
soc_log_err("log path length is over than %d!\n", sizeof(g_log_path_buf));
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = log_file_lock();
|
|
if (ret != 0) {
|
|
soc_log_err("down_interruptible failed\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
err_ret = memcpy_s(g_log_path_buf, LOG_MAX_FILE_NAME_LENTH, argv[1], strlen(argv[1]) + 1); /* 命令的第1个参数 */
|
|
if (err_ret != EOK) {
|
|
log_file_unlock();
|
|
soc_log_err("secure func call error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_udisk_log_file = g_log_path_buf;
|
|
|
|
if (memcmp(g_log_path_buf, "/dev/null", strlen("/dev/null")) != 0) {
|
|
ret = log_drv_udisk_store_init();
|
|
if (ret != TD_SUCCESS) {
|
|
log_file_unlock();
|
|
soc_log_err("log_drv_udisk_store_init failed ... \n");
|
|
return ret;
|
|
}
|
|
g_set_log_file_flag = TD_TRUE;
|
|
if (g_log_store_info.store_log_thread_exist == TD_TRUE) {
|
|
g_log_store_info.store_log_enable = TD_FALSE;
|
|
}
|
|
} else {
|
|
g_set_log_file_flag = TD_FALSE;
|
|
if (g_log_store_info.store_log_thread_exist == TD_TRUE) {
|
|
g_log_store_info.store_log_enable = TD_TRUE;
|
|
}
|
|
|
|
ret = log_drv_udisk_store_deinit();
|
|
log_file_unlock();
|
|
return ret;
|
|
}
|
|
|
|
g_log_cfg_info->udisk_flag = (td_u8)g_set_log_file_flag;
|
|
|
|
log_file_unlock();
|
|
|
|
soc_log_info("set log path is g_log_path_buf = %s\n", g_udisk_log_file);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 drv_log_process_proc_store_path(td_u32 argc, td_char(*argv)[PROC_CMD_SINGEL_LENGTH_MAX],
|
|
td_void *private)
|
|
{
|
|
errno_t err_ret;
|
|
|
|
if (argc < 2) { /* argc at least 2 */
|
|
soc_log_err("param invalid! argc = %d\n", argc);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (strlen(argv[1]) >= sizeof(g_store_path_buf)) { /* 命令的第1个参数 */
|
|
soc_log_err("store path length is over than %d!\n", sizeof(g_store_path_buf));
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
log_file_lock();
|
|
|
|
err_ret = memset_s(g_store_path_buf, LOG_MAX_FILE_NAME_LENTH, 0, sizeof(g_store_path_buf));
|
|
if (err_ret != EOK) {
|
|
log_file_unlock();
|
|
soc_log_err("secure func call error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
err_ret = memcpy_s(g_store_path_buf, LOG_MAX_FILE_NAME_LENTH, argv[1], strlen(argv[1])); /* 命令的第1个参数 */
|
|
if (err_ret != EOK) {
|
|
log_file_unlock();
|
|
soc_log_err("secure func call error\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_store_path = g_store_path_buf;
|
|
|
|
log_file_unlock();
|
|
|
|
soc_log_info("set log path is store_path = %s\n", g_store_path_buf);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static osal_proc_cmd g_proc_cmd[] = {
|
|
{"help", drv_log_process_proc_help},
|
|
{"loglevel", drv_log_process_proc_level},
|
|
{"logsize", drv_log_process_proc_size},
|
|
{"logpath", drv_log_process_proc_path},
|
|
{"storepath", drv_log_process_proc_store_path}
|
|
};
|
|
|
|
static td_void print_loglevel_helpinfo(td_void *s)
|
|
{
|
|
td_u32 i;
|
|
|
|
osal_seq_printf(s, "------------------support_log_level -----------------\n");
|
|
osal_seq_printf(s, "loglevel |level_val |\n");
|
|
|
|
for (i = 0; i < SOC_LOG_LEVEL_MAX; i++) {
|
|
osal_seq_printf(s, "%-18s|%-33d|\n", g_debug_level_name[i], i);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
td_s32 drv_log_read_proc(td_void *s, td_void *arg)
|
|
{
|
|
td_u32 i;
|
|
td_u8 level;
|
|
td_char path[LOG_MAX_FILE_NAME_LENTH] = {0};
|
|
td_u32 cnt = LOG_CFG_BUF_SIZE / sizeof(log_cfg_info);
|
|
|
|
if (g_log_init == TD_FALSE) {
|
|
osal_seq_printf(s, "Log is not init!\n");
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
if (ext_drv_log_get_path(path, sizeof(path)) != TD_SUCCESS) {
|
|
soc_log_err("ext_drv_log_get_path failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
osal_seq_printf(s, "\n[log] %s\n", VERSION_STRING);
|
|
|
|
osal_seq_printf(s, "------------------log_path---------------------------\n");
|
|
osal_seq_printf(s, "log_path :%-33s|\n", path);
|
|
|
|
if (ext_drv_log_get_store_path(path, sizeof(path)) != TD_SUCCESS) {
|
|
soc_log_err("ext_drv_log_get_store_path failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
osal_seq_printf(s, "------------------store_path-------------------------\n");
|
|
osal_seq_printf(s, "store_path :%-33s|\n", path);
|
|
osal_seq_printf(s, "------------------Store Path-------------------------\n");
|
|
osal_seq_printf(s, "maxlogsize(MB) :%-33u|\n", (g_default_log_size / 1024U / 1024U));
|
|
|
|
osal_seq_printf(s, "------------------module_log_level-------------------\n");
|
|
osal_seq_printf(s, "Log_module |Level |\n");
|
|
|
|
for (i = 0; i < cnt; i++) {
|
|
drv_log_set_module(i);
|
|
if (strncmp(g_log_cfg_info[i].module_name, "Invalid", 0x8)) {
|
|
level = g_log_cfg_info[i].log_level;
|
|
if (level <= SOC_LOG_LEVEL_MAX) {
|
|
osal_seq_printf(s, "%-18s|%1d(%-6s) |\n", g_log_cfg_info[i].module_name,
|
|
level, g_debug_level_name[level]);
|
|
}
|
|
}
|
|
}
|
|
|
|
print_loglevel_helpinfo(s);
|
|
osal_seq_printf(s, "=====================================================\n");
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 drv_log_add_proc(td_void)
|
|
{
|
|
osal_proc_entry *item = TD_NULL;
|
|
|
|
item = osal_proc_add(SOC_MOD_LOG_NAME, strlen(SOC_MOD_LOG_NAME));
|
|
if (item == TD_NULL) {
|
|
soc_log_err("add proc failed!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
item->read = drv_log_read_proc;
|
|
item->cmd_cnt = sizeof(g_proc_cmd) / sizeof(osal_proc_cmd);
|
|
item->cmd_list = g_proc_cmd;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void drv_log_remove_proc(td_void)
|
|
{
|
|
osal_proc_remove(SOC_MOD_LOG_NAME, strlen(SOC_MOD_LOG_NAME));
|
|
}
|
|
|
|
td_s32 drv_log_network_or_udisk_read(td_u32 cmd, td_void *arg)
|
|
{
|
|
log_read_buf *para = (log_read_buf *)arg;
|
|
|
|
if (cmd != LOG_CMPI_READ) {
|
|
soc_log_err("cmd is not LOG_CMPI_READ.\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (para == TD_NULL || para->msg_addr == TD_NULL) {
|
|
soc_log_err("User buffer is null!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (para->magic_num != LOG_MAGIC_NUM) {
|
|
soc_log_err("User buffer is likely illegal!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return ext_drv_log_read_buf(para->msg_addr, para->buf_len, ¶->copy_len, ¶->task_status, TD_FALSE);
|
|
}
|
|
|
|
td_s32 drv_log_network_or_udisk_write(td_u32 cmd, const td_void *arg)
|
|
{
|
|
log_write_buf *para = (log_write_buf *)arg;
|
|
|
|
if (cmd != LOG_CMPI_WRITE) {
|
|
soc_log_err("cmd is not LOG_CMPI_WRITE \n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (para == TD_NULL || para->msg_addr == TD_NULL) {
|
|
soc_log_err("User buffer is null!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return ext_drv_log_write_buf(para->msg_addr, para->msg_len, LOG_MSG_FROM_USER);
|
|
}
|
|
|
|
td_s32 drv_log_ioctl(td_u32 cmd, td_void *arg, td_void *private_data)
|
|
{
|
|
if (arg == TD_NULL) {
|
|
soc_log_err("param arg invalid!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
switch (cmd) {
|
|
case LOG_CMPI_INIT: {
|
|
td_mem_handle_t *fd = (td_mem_handle_t *)arg;
|
|
|
|
return drv_log_get_cfg_buf_fd(fd);
|
|
}
|
|
case LOG_CMPI_EXIT: {
|
|
td_mem_handle_t *fd = (td_mem_handle_t *)arg;
|
|
|
|
return drv_log_put_cfg_buf_fd(*fd);
|
|
}
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
case LOG_CMPI_READ: {
|
|
return drv_log_network_or_udisk_read(cmd, arg);
|
|
}
|
|
case LOG_CMPI_WRITE: {
|
|
return drv_log_network_or_udisk_write(cmd, arg);
|
|
}
|
|
#endif
|
|
case LOG_CMPI_SET_SIZE: {
|
|
td_u32 *size = (td_u32 *)arg;
|
|
|
|
return ext_drv_log_set_size(*size);
|
|
}
|
|
case LOG_CMPI_STORE_ENABLE: {
|
|
drv_log_store_enable((td_bool *)arg);
|
|
return TD_SUCCESS;
|
|
}
|
|
case LOG_CMPI_GET_STORE_STATUS: {
|
|
log_store_status *param = (log_store_status *)arg;
|
|
drv_log_get_store_status(&(param->log_store_enable), &(param->log_store_thread_exist));
|
|
return TD_SUCCESS;
|
|
}
|
|
default:
|
|
soc_log_err("unknown command 0x%x\n", cmd);
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
td_s32 drv_log_compat_ioctl(unsigned int cmd, td_void *arg, td_void *private_data)
|
|
{
|
|
switch (cmd) {
|
|
#if defined(CONFIG_SOCT_LOG_NETWORK_SUPPORT) || defined(CONFIG_SOCT_LOG_UDISK_SUPPORT)
|
|
case LOG_CMPI_COMPAT_READ: {
|
|
log_compat_read_buf *para = (log_compat_read_buf *)arg;
|
|
|
|
if (para == TD_NULL || (td_u8 *)compat_ptr(para->msg_addr) == TD_NULL) {
|
|
soc_log_err("User buffer is null!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
if (para->magic_num != LOG_MAGIC_NUM) {
|
|
soc_log_err("User buffer is likely illegal!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return ext_drv_log_read_buf((td_u8 *)compat_ptr(para->msg_addr), para->buf_len, ¶->copy_len,
|
|
¶->task_status, TD_FALSE);
|
|
}
|
|
case LOG_CMPI_COMPAT_WRITE: {
|
|
log_compat_write_buf *para = (log_compat_write_buf *)arg;
|
|
|
|
if (para == TD_NULL || (td_u8 *)compat_ptr(para->msg_addr) == TD_NULL) {
|
|
soc_log_err("User buffer is null!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return ext_drv_log_write_buf((td_u8 *)compat_ptr(para->msg_addr), para->msg_len, LOG_MSG_FROM_USER);
|
|
}
|
|
#endif
|
|
default:
|
|
return drv_log_ioctl(cmd, arg, private_data);
|
|
}
|
|
return -ENOIOCTLCMD;
|
|
}
|
|
#endif
|
|
|