| /******************************************************************************* |
| * °æÈ¨ËùÓÐ (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 |
| |