blob: f59e646637140abe4ffcc5d53c134c989622579a [file] [log] [blame]
/*******************************************************************************
* °æÈ¨ËùÓÐ (C)2016, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
*
* ÎļþÃû³Æ: ramdump_oss.c
* Îļþ±êʶ: ramdump_oss.c
* ÄÚÈÝÕªÒª: ramdump²Ù×÷ϵͳÒÀÀµ½Ó¿Ú/Êý¾Ý½á¹¹¶¨ÒåÍ·Îļþ
* ʹÓ÷½·¨: Èç¹û¸ü»»²Ù×÷ϵͳ£¬¸ÄÍ·ÎļþÄÚ½Ó¿Ú»òÕßÊý¾Ý¶¨ÒåÐèÒªÖØÐÂÊÊÅä
*
* ÐÞ¸ÄÈÕÆÚ °æ±¾ºÅ Ð޸ıê¼Ç ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ
* ------------------------------------------------------------------------------
* 2016/6/10 V1.0 Create ÕÔ¾ü¿ü ´´½¨
*
*******************************************************************************/
/*******************************************************************************
* Í·Îļþ *
*******************************************************************************/
#include "ramdump_pub.h"
#include "ramdump_oss.h"
#include <linux/module.h>
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Íⲿº¯ÊýÉùÃ÷ *
*******************************************************************************/
/*******************************************************************************
* ºê¶¨Òå *
*******************************************************************************/
/*******************************************************************************
* Êý¾ÝÀàÐͶ¨Òå *
*******************************************************************************/
/*******************************************************************************
* È«¾Ö±äÁ¿ÉùÃ÷ *
*******************************************************************************/
/*******************************************************************************
* È«¾Öº¯ÊýÉùÃ÷ *
*******************************************************************************/
#ifdef _OS_LINUX
/* icp api */
extern int zDrvRpMsg_CreateChannel(
T_ZDrvRpMsg_ActorID actorID,
T_ZDrvRpMsg_ChID chID,
unsigned int size);
extern int zDrvRpMsg_RegCallBack(
T_ZDrvRpMsg_ActorID actorID,
unsigned int chID,
T_ZDrvRpMsg_CallbackFunction callback);
extern int zDrvRpMsg_WriteLockIrq(const T_ZDrvRpMsg_Msg *pMsg);
extern void panic(const char *fmt, ...);
extern int zDrvUsbPoll_Init(void);
extern int zDrvUsbPoll_Isr(void);
extern bool zDrvUsbPoll_isConnect(void);
extern int zDrvUsbPoll_Read(unsigned char* pBuf,unsigned long length);
extern int zDrvUsbPoll_Write(unsigned char* pBuf,unsigned long length);
#if defined CONFIG_PRINTK
extern void get_logbuf_info(unsigned long *addr, unsigned long *size);
#endif
#endif //#ifdef _OS_LINUX
/*******************************************************************************
* È«¾Öº¯ÊýʵÏÖ *
*******************************************************************************/
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_create_thread
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) void
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷:
*******************************************************************************/
void ramdump_oss_create_thread (
unsigned char *name,
ramdump_oss_thread_entry_t entry)
{
#ifdef _OS_TOS
#define RAMDUMP_THREAD_STACK_DEF_SIZE 2048
#define RAMDUMP_THREAD_DEF_PRIO 20
#define RAMDUMP_THREAD_DEF_ARG 0
#define RAMDUMP_THREAD_AUTORUN 1
#define RAMDUMP_THREAD_PREEMPT 1
zOss_CreateThread(
name,entry,
RAMDUMP_THREAD_DEF_ARG,
RAMDUMP_THREAD_STACK_DEF_SIZE,
RAMDUMP_THREAD_DEF_PRIO,
RAMDUMP_THREAD_PREEMPT,
RAMDUMP_THREAD_AUTORUN);
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_mmap
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) void
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷:
*******************************************************************************/
unsigned long ramdump_oss_mmap (unsigned long addr, unsigned long size)
{
#ifdef _OS_LINUX
return ioremap(addr,size);
#elif defined (_OS_TOS)
#ifdef __USE_MMU__
T_zTos_MmuRamdumpTable mmuTable = {0};
zTos_MmuGetMappingRegion(addr, size, &mmuTable);
/*
* TODO!
* current tos mmap one to one
* need new API like ioremap realize
*/
return addr;
#endif
#endif
}
#ifdef _USE_CAP_SYS
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_icp_send_cap
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) icp_msg: msg info
client_id: client id
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: int: if msg send success
* ÆäËü˵Ã÷: This function is used for server to send msg to client
*******************************************************************************/
int ramdump_oss_icp_send_cap(ramdump_oss_msg_t *icp_msg, unsigned int client_id)
{
int ret;
ramdump_oss_icp_msg rpmsg = {0};
rpmsg.actorID = client_id;
rpmsg.chID = channel_10;
rpmsg.flag = 1;
rpmsg.buf = icp_msg;
rpmsg.len = sizeof(*icp_msg);
/*
* clean all the caches to make sure all data in ddr
*/
ramdump_arch_clean_caches();
ret = zDrvRpMsg_Write_Cap(&rpmsg);
if (ret != rpmsg.len)
{
OSS_PRINTF(
"[ramdump] icpmsg send fail, ret != rpmsg.len[ret:%d], [client_id:%d]\n",
ret,
client_id);
return ret;
}
return RAMDUMP_ICP_SUCCESS;
}
#endif
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_icp_send
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) icp_msg: msg info
client_id: client id
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: int: if msg send success
* ÆäËü˵Ã÷: This function is used for server to send msg to client
*******************************************************************************/
int ramdump_oss_icp_send(ramdump_oss_msg_t *icp_msg, unsigned int client_id)
{
int ret;
ramdump_oss_icp_msg rpmsg = {0};
rpmsg.actorID = client_id;
rpmsg.chID = channel_40;
rpmsg.flag = 1;
rpmsg.buf = icp_msg;
rpmsg.len = sizeof(*icp_msg);
/*
* clean all the caches to make sure all data in ddr
*/
ramdump_arch_clean_caches();
ret = ramdump_oss_icp_write(&rpmsg);
if (ret != rpmsg.len)
{
#ifdef _OS_LINUX
OSS_PRINTF(
"[ramdump] icpmsg send fail, ret != rpmsg.len[ret:%d], [client_id:%d]\n",
ret,
client_id);
#elif defined (_OS_TOS)
OSS_PRINTF(
SUBMDL_TEST,
PRINT_LEVEL_NORMAL,
"[ramdump] icpmsg send fail, ret != rpmsg.len[ret:%d], [client_id:%d]\n",
ret,
client_id);
#endif
return ret;
}
return RAMDUMP_ICP_SUCCESS;
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_error_log_creat
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) buf : addr point
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷:
*******************************************************************************/
void ramdump_oss_error_log_creat(char *buf)
{
#ifdef _OS_LINUX
if (current->mm != NULL)
sprintf(
buf,
" dump at user, app name is: %s, load addr is: %lu \n",
current->comm,
current->mm->start_code);
else
sprintf(
buf,
" dump at kernel, app name is: %s \n",
current->comm);
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_icp_create_channel
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) actorID: icp send core id
chID: icp channel id
size: icp channel size
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: int: if msg send success
* ÆäËü˵Ã÷:
*******************************************************************************/
int ramdump_oss_icp_create_channel(
ramdump_oss_icp_actorid actorID,
ramdump_oss_icp_channelid chID,
unsigned int size)
{
#ifdef _OS_LINUX
return CPPS_FUNC(cpps_callbacks, zDrvRpMsg_CreateChannel)(actorID, chID, size);
#elif defined (_OS_TOS)
if (actorID == ramdump_cpu_id[RAMDUMP_CPU_2])
return 0;
else
return zDrvRpMsg_CreateChannel(actorID, chID, size);
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_icp_regcallback
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) actorID: icp send core id
chID: icp channel id
callback:icp callback fun
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: int: if msg send success
* ÆäËü˵Ã÷:
*******************************************************************************/
int ramdump_oss_icp_regcallback (
ramdump_oss_icp_actorid actorID,
unsigned int chID,
ramdump_oss_icp_callback callback)
{
#ifdef _OS_LINUX
return CPPS_FUNC(cpps_callbacks, zDrvRpMsg_RegCallBack)(actorID,chID,callback);
#elif defined (_OS_TOS)
if (actorID == ramdump_cpu_id[RAMDUMP_CPU_2])
return zDrvIcp_RegCallback(
ICP_ARM0_MODULE_ID_OS,
actorID,
callback,
ICP_ISR_CALLBACK);
else
return zDrvRpMsg_RegCallBack(actorID,chID,callback);
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_icp_write
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) pMsg: icp send msg
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: int: if msg send success
* ÆäËü˵Ã÷:
*******************************************************************************/
int ramdump_oss_icp_write(const ramdump_oss_icp_msg *pMsg)
{
#ifdef _OS_LINUX
return CPPS_FUNC(cpps_callbacks, zDrvRpMsg_Write)(pMsg);
#elif defined (_OS_TOS)
if ((ramdump_msg_t *)pMsg->actorID == ramdump_cpu_id[RAMDUMP_CPU_2])
{
switch (((ramdump_msg_t *)(pMsg->buf))->msg_id)
{
case RAMDUMP_MSG_EXCEPT:
{
T_HalIcp_Msg icpMsg = { 0 };
icpMsg.SrcModId = ICP_ARM0_MODULE_ID_OS;
icpMsg.desModId = ICP_ARM1_MODULE_ID_OS;
icpMsg.IntInfo.high_word = ZPLAT_PS2PHY_RAMDUMP_INT_ICP_CF;
zDrvIcp_SendMsg((const T_HalIcp_Msg *)&icpMsg);
}
case RAMDUMP_MSG_SYNC:
default:
return pMsg->len;
}
}
else
return zDrvRpMsg_WriteLockIrq(pMsg);
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_init
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) void
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷:
*******************************************************************************/
void ramdump_oss_data_trans_init(void)
{
#ifdef _OS_LINUX
zDrvUsbPoll_Init(); /* ³õʼ»¯USB */
while (!zDrvUsbPoll_isConnect()) ; /* ²éѯUSBÊÇ·ñÁ¬½Ó */
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_read
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) buffer: data buff
size: data size
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷:
*******************************************************************************/
void ramdump_oss_data_trans_read(unsigned char *buffer, unsigned int size)
{
#ifdef _OS_LINUX
unsigned int count = 0;
do
{
zDrvUsbPoll_Isr();
count = (unsigned int)zDrvUsbPoll_Read(buffer, size);
if ( size <= count)
{
break;
}
buffer += count;
size -=count;
}
while (size > 0);
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_write
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) buffer: data buff
size: data size
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷:
*******************************************************************************/
void ramdump_oss_data_trans_write(unsigned char *buffer, unsigned int size)
{
#ifdef _OS_LINUX
unsigned int count = 0;
while (size > 0)
{
zDrvUsbPoll_Isr();
count = (unsigned int)zDrvUsbPoll_Write(buffer, size);
if ( size <= count)
{
break;
}
buffer += count;
size -=count;
}
#endif
}
/*******************************************************************************
* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_done
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) void
* (´«³ö²ÎÊý) void
* ·µ »Ø Öµ: void
* ÆäËü˵Ã÷:
*******************************************************************************/
void ramdump_oss_data_trans_done(void)
{
#ifdef _OS_LINUX
/* µÈ´ýÊý¾Ý·¢ËÍÍêºó£¬ÔÙÖØÆô */
zDrvUsbPoll_Isr();
#endif
}
void ramdump_oss_logbuf_create(void)
{
#ifdef _OS_LINUX
#if defined CONFIG_PRINTK
unsigned long addr;
unsigned long size;
get_logbuf_info(&addr, &size);
ramdump_ram_conf_table_add(
"ap_log_buf",
(unsigned long)OSS_VIRT_TO_PHY(addr),
size,
addr,
RAMDUMP_FLAG_NONE,
0);
#endif
#endif
}
#ifdef __cplusplus
}
#endif