blob: c90126bbcce2e14bc3f4a5b67e7591cab5857013 [file] [log] [blame]
xf.libfc6e712025-02-07 01:54:34 -08001/*******************************************************************************
2* °æÈ¨ËùÓÐ (C)2016, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
3*
4* ÎļþÃû³Æ: ramdump_oss.c
5* Îļþ±êʶ: ramdump_oss.c
6* ÄÚÈÝÕªÒª: ramdump²Ù×÷ϵͳÒÀÀµ½Ó¿Ú/Êý¾Ý½á¹¹¶¨ÒåÍ·Îļþ
7* ʹÓ÷½·¨: Èç¹û¸ü»»²Ù×÷ϵͳ£¬¸ÄÍ·ÎļþÄÚ½Ó¿Ú»òÕßÊý¾Ý¶¨ÒåÐèÒªÖØÐÂÊÊÅä
8*
9* ÐÞ¸ÄÈÕÆÚ °æ±¾ºÅ Ð޸ıê¼Ç ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ
10* ------------------------------------------------------------------------------
11* 2016/6/10 V1.0 Create ÕÔ¾ü¿ü ´´½¨
12*
13*******************************************************************************/
14
15/*******************************************************************************
16* Í·Îļþ *
17*******************************************************************************/
18#include "ramdump_pub.h"
19#include "ramdump_oss.h"
20#include <linux/module.h>
21#include <linux/lzo.h>
22#ifdef _USE_VEHICLE_DC
23#include "ramdump_compress.h"
24#endif
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/*******************************************************************************
31* Íⲿº¯ÊýÉùÃ÷ *
32*******************************************************************************/
33extern unsigned long ramdump_phy_to_vir(ramdump_ram_config_t * ram_config);
34
35/*******************************************************************************
36* ºê¶¨Òå *
37*******************************************************************************/
38
39/*******************************************************************************
40* Êý¾ÝÀàÐͶ¨Òå *
41*******************************************************************************/
42#ifdef _USE_VEHICLE_DC
43typedef struct
44{
45 volatile unsigned int core_flag;//0:cp,1:cap
46 volatile unsigned int rw_flag;//0:non,1:w,2:r
47 volatile unsigned int size;//orginal size
48 char buf[];
49} ramdump_shmem_t;
50
51/*******************************************************************************
52* È«¾Ö±äÁ¿ÉùÃ÷ *
53*******************************************************************************/
54unsigned char *ramdump_mem_base = NULL;
55unsigned char *ramdump_shared_mem_base = NULL;
56unsigned int ramdump_export_mode = 0xFF;
57#endif
58
59/*******************************************************************************
60* È«¾Öº¯ÊýÉùÃ÷ *
61*******************************************************************************/
62#ifdef _OS_LINUX
63/* icp api */
64extern int zDrvRpMsg_CreateChannel(
65 T_ZDrvRpMsg_ActorID actorID,
66 T_ZDrvRpMsg_ChID chID,
67 unsigned int size);
68extern int zDrvRpMsg_RegCallBack(
69 T_ZDrvRpMsg_ActorID actorID,
70 unsigned int chID,
71 T_ZDrvRpMsg_CallbackFunction callback);
72extern int zDrvRpMsg_WriteLockIrq(const T_ZDrvRpMsg_Msg *pMsg);
73extern void panic(const char *fmt, ...);
74
75extern int zDrvUsbPoll_Init(void);
76extern int zDrvUsbPoll_Isr(void);
77extern bool zDrvUsbPoll_isConnect(void);
78extern int zDrvUsbPoll_Read(unsigned char* pBuf,unsigned long length);
79extern int zDrvUsbPoll_Write(unsigned char* pBuf,unsigned long length);
80#if defined CONFIG_PRINTK
81extern void get_logbuf_info(unsigned long *addr, unsigned long *size);
82#endif
83#endif //#ifdef _OS_LINUX
84extern unsigned int ramdump_compress_flag;
85
86/*******************************************************************************
87* È«¾Öº¯ÊýʵÏÖ *
88*******************************************************************************/
89
90/*******************************************************************************
91* ¹¦ÄÜÃèÊö: ramdump_oss_create_thread
92* ²ÎÊý˵Ã÷:
93* (´«Èë²ÎÊý) void
94* (´«³ö²ÎÊý) void
95* ·µ »Ø Öµ: void
96* ÆäËü˵Ã÷:
97*******************************************************************************/
98void ramdump_oss_create_thread (
99 unsigned char *name,
100 ramdump_oss_thread_entry_t entry)
101{
102#ifdef _OS_TOS
103#define RAMDUMP_THREAD_STACK_DEF_SIZE 2048
104#define RAMDUMP_THREAD_DEF_PRIO 20
105#define RAMDUMP_THREAD_DEF_ARG 0
106#define RAMDUMP_THREAD_AUTORUN 1
107#define RAMDUMP_THREAD_PREEMPT 1
108
109 zOss_CreateThread(
110 name,entry,
111 RAMDUMP_THREAD_DEF_ARG,
112 RAMDUMP_THREAD_STACK_DEF_SIZE,
113 RAMDUMP_THREAD_DEF_PRIO,
114 RAMDUMP_THREAD_PREEMPT,
115 RAMDUMP_THREAD_AUTORUN);
116#endif
117}
118
119/*******************************************************************************
120* ¹¦ÄÜÃèÊö: ramdump_oss_mmap
121* ²ÎÊý˵Ã÷:
122* (´«Èë²ÎÊý) void
123* (´«³ö²ÎÊý) void
124* ·µ »Ø Öµ: void
125* ÆäËü˵Ã÷:
126*******************************************************************************/
127unsigned long ramdump_oss_mmap (unsigned long addr, unsigned long size)
128{
129#ifdef _OS_LINUX
130 return ioremap(addr,size);
131#elif defined (_OS_TOS)
132
133#ifdef __USE_MMU__
134 T_zTos_MmuRamdumpTable mmuTable = {0};
135 zTos_MmuGetMappingRegion(addr, size, &mmuTable);
136 /*
137 * TODO!
138 * current tos mmap one to one
139 * need new API like ioremap realize
140 */
141 return addr;
142#endif
143
144#endif
145}
146
147#ifdef _USE_CAP_SYS
148/*******************************************************************************
149* ¹¦ÄÜÃèÊö: ramdump_oss_icp_send_cap
150* ²ÎÊý˵Ã÷:
151* (´«Èë²ÎÊý) icp_msg: msg info
152 client_id: client id
153* (´«³ö²ÎÊý) void
154* ·µ »Ø Öµ: int: if msg send success
155* ÆäËü˵Ã÷: This function is used for server to send msg to client
156*******************************************************************************/
157int ramdump_oss_icp_send_cap(ramdump_oss_msg_t *icp_msg, unsigned int client_id)
158{
159 int ret;
160 ramdump_oss_icp_msg rpmsg = {0};
161
162 rpmsg.actorID = client_id;
163 rpmsg.chID = channel_10;
164 rpmsg.flag = 1;
165 rpmsg.buf = icp_msg;
166 rpmsg.len = sizeof(*icp_msg);
167
168 /*
169 * clean all the caches to make sure all data in ddr
170 */
171 ramdump_arch_clean_caches();
172
173 ret = zDrvRpMsg_Write_Cap(&rpmsg);
174
175 if (ret != rpmsg.len)
176 {
177 OSS_PRINTF(
178 "[ramdump] icpmsg send fail, ret != rpmsg.len[ret:%d], [client_id:%d]\n",
179 ret,
180 client_id);
181 return ret;
182 }
183
184 return RAMDUMP_ICP_SUCCESS;
185}
186#endif
187
188/*******************************************************************************
189* ¹¦ÄÜÃèÊö: ramdump_oss_icp_send
190* ²ÎÊý˵Ã÷:
191* (´«Èë²ÎÊý) icp_msg: msg info
192 client_id: client id
193* (´«³ö²ÎÊý) void
194* ·µ »Ø Öµ: int: if msg send success
195* ÆäËü˵Ã÷: This function is used for server to send msg to client
196*******************************************************************************/
197int ramdump_oss_icp_send(ramdump_oss_msg_t *icp_msg, unsigned int client_id)
198{
199 int ret;
200 ramdump_oss_icp_msg rpmsg = {0};
201
202 rpmsg.actorID = client_id;
203 rpmsg.chID = channel_40;
204 rpmsg.flag = 1;
205 rpmsg.buf = icp_msg;
206 rpmsg.len = sizeof(*icp_msg);
207
208 /*
209 * clean all the caches to make sure all data in ddr
210 */
211 ramdump_arch_clean_caches();
212
213 ret = ramdump_oss_icp_write(&rpmsg);
214
215 if (ret != rpmsg.len)
216 {
217#ifdef _OS_LINUX
218 OSS_PRINTF(
219 "[ramdump] icpmsg send fail, ret != rpmsg.len[ret:%d], [client_id:%d]\n",
220 ret,
221 client_id);
222#elif defined (_OS_TOS)
223 OSS_PRINTF(
224 SUBMDL_TEST,
225 PRINT_LEVEL_NORMAL,
226 "[ramdump] icpmsg send fail, ret != rpmsg.len[ret:%d], [client_id:%d]\n",
227 ret,
228 client_id);
229#endif
230 return ret;
231 }
232
233 return RAMDUMP_ICP_SUCCESS;
234}
235
236/*******************************************************************************
237* ¹¦ÄÜÃèÊö: ramdump_oss_error_log_creat
238* ²ÎÊý˵Ã÷:
239* (´«Èë²ÎÊý) buf : addr point
240* (´«³ö²ÎÊý) void
241* ·µ »Ø Öµ: void
242* ÆäËü˵Ã÷:
243*******************************************************************************/
244void ramdump_oss_error_log_creat(char *buf)
245{
246#ifdef _OS_LINUX
247 if (current->mm != NULL)
248 sprintf(
249 buf,
250 " dump at user, app name is: %s, load addr is: %lu \n",
251 current->comm,
252 current->mm->start_code);
253 else
254 sprintf(
255 buf,
256 " dump at kernel, app name is: %s \n",
257 current->comm);
258#endif
259
260}
261
262/*******************************************************************************
263* ¹¦ÄÜÃèÊö: ramdump_oss_icp_create_channel
264* ²ÎÊý˵Ã÷:
265* (´«Èë²ÎÊý) actorID: icp send core id
266 chID: icp channel id
267 size: icp channel size
268* (´«³ö²ÎÊý) void
269* ·µ »Ø Öµ: int: if msg send success
270* ÆäËü˵Ã÷:
271*******************************************************************************/
272int ramdump_oss_icp_create_channel(
273 ramdump_oss_icp_actorid actorID,
274 ramdump_oss_icp_channelid chID,
275 unsigned int size)
276{
277#ifdef _OS_LINUX
278 return CPPS_FUNC(cpps_callbacks, zDrvRpMsg_CreateChannel)(actorID, chID, size);
279#elif defined (_OS_TOS)
280 if (actorID == ramdump_cpu_id[RAMDUMP_CPU_2])
281 return 0;
282 else
283 return zDrvRpMsg_CreateChannel(actorID, chID, size);
284#endif
285}
286
287/*******************************************************************************
288* ¹¦ÄÜÃèÊö: ramdump_oss_icp_regcallback
289* ²ÎÊý˵Ã÷:
290* (´«Èë²ÎÊý) actorID: icp send core id
291 chID: icp channel id
292 callback:icp callback fun
293* (´«³ö²ÎÊý) void
294* ·µ »Ø Öµ: int: if msg send success
295* ÆäËü˵Ã÷:
296*******************************************************************************/
297int ramdump_oss_icp_regcallback (
298 ramdump_oss_icp_actorid actorID,
299 unsigned int chID,
300 ramdump_oss_icp_callback callback)
301{
302#ifdef _OS_LINUX
303 return CPPS_FUNC(cpps_callbacks, zDrvRpMsg_RegCallBack)(actorID,chID,callback);
304#elif defined (_OS_TOS)
305 if (actorID == ramdump_cpu_id[RAMDUMP_CPU_2])
306 return zDrvIcp_RegCallback(
307 ICP_ARM0_MODULE_ID_OS,
308 actorID,
309 callback,
310 ICP_ISR_CALLBACK);
311 else
312 return zDrvRpMsg_RegCallBack(actorID,chID,callback);
313#endif
314}
315
316/*******************************************************************************
317* ¹¦ÄÜÃèÊö: ramdump_oss_icp_write
318* ²ÎÊý˵Ã÷:
319* (´«Èë²ÎÊý) pMsg: icp send msg
320* (´«³ö²ÎÊý) void
321* ·µ »Ø Öµ: int: if msg send success
322* ÆäËü˵Ã÷:
323*******************************************************************************/
324int ramdump_oss_icp_write(const ramdump_oss_icp_msg *pMsg)
325{
326#ifdef _OS_LINUX
327 return CPPS_FUNC(cpps_callbacks, zDrvRpMsg_Write)(pMsg);
328#elif defined (_OS_TOS)
329 if ((ramdump_msg_t *)pMsg->actorID == ramdump_cpu_id[RAMDUMP_CPU_2])
330 {
331 switch (((ramdump_msg_t *)(pMsg->buf))->msg_id)
332 {
333 case RAMDUMP_MSG_EXCEPT:
334 {
335 T_HalIcp_Msg icpMsg = { 0 };
336 icpMsg.SrcModId = ICP_ARM0_MODULE_ID_OS;
337 icpMsg.desModId = ICP_ARM1_MODULE_ID_OS;
338 icpMsg.IntInfo.high_word = ZPLAT_PS2PHY_RAMDUMP_INT_ICP_CF;
339 zDrvIcp_SendMsg((const T_HalIcp_Msg *)&icpMsg);
340 }
341 case RAMDUMP_MSG_SYNC:
342 default:
343 return pMsg->len;
344 }
345 }
346 else
347 return zDrvRpMsg_WriteLockIrq(pMsg);
348#endif
349}
350
351/*******************************************************************************
352* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_init
353* ²ÎÊý˵Ã÷:
354* (´«Èë²ÎÊý) void
355* (´«³ö²ÎÊý) void
356* ·µ »Ø Öµ: void
357* ÆäËü˵Ã÷:
358*******************************************************************************/
359void ramdump_oss_data_trans_init(void)
360{
361#ifdef _OS_LINUX
362#ifdef _USE_VEHICLE_DC
363 if((ramdump_export_mode != RAMDUMP_MODE_EMMC)
364 &&(ramdump_export_mode != RAMDUMP_MODE_SPINAND))
365 {
366#endif
367 zDrvUsbPoll_Init(); /* ³õʼ»¯USB */
368 while (!zDrvUsbPoll_isConnect()) ; /* ²éѯUSBÊÇ·ñÁ¬½Ó */
369#ifdef _USE_VEHICLE_DC
370 }
371 else
372 {
373 ramdump_lzo_init();
374 }
375#endif
376#endif
377}
378
379void ramdump_usb_trans_read(unsigned char *buffer, unsigned int size)
380{
381#ifdef _OS_LINUX
382 unsigned int count = 0;
383
384 do
385 {
386 zDrvUsbPoll_Isr();
387 count = (unsigned int)zDrvUsbPoll_Read(buffer, size);
388 if ( size <= count)
389 {
390 break;
391 }
392 buffer += count;
393 size -=count;
394 }
395 while (size > 0);
396#endif
397
398}
399
400void ramdump_usb_trans_write(unsigned char *buffer, unsigned int size)
401{
402#ifdef _OS_LINUX
403 unsigned int count = 0;
404
405 while (size > 0)
406 {
407 zDrvUsbPoll_Isr();
408 count = (unsigned int)zDrvUsbPoll_Write(buffer, size);
409 if ( size <= count)
410 {
411 break;
412 }
413
414 buffer += count;
415 size -=count;
416 }
417#endif
418
419}
420static inline void ramdump_wait_delay( unsigned long ms)
421{
422 volatile int j = 0;
423 for (j = 0; j < 50000; j++);
424}
425
426#ifdef _USE_VEHICLE_DC
427void ramdump_shared_mem_init(void)
428{
429 ramdump_mem_base = OSS_MMAP(RAMDUMP_MEM_BASE, RAMDUMP_SHARED_MEM_LEN);
430 ramdump_shared_mem_base = ramdump_mem_base;
431}
432
433int ramdump_shm_trans_write(unsigned char *buffer, unsigned int size)
434{
435 int ret = -1;
436 size_t dst_len = 0;
437 ramdump_shmem_t tmp_msg;
438 ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
439
440 if (size > (RAMDUMP_SHARED_MEM_LEN - roundup(sizeof(ramdump_shmem_t), RAMDUMP_SHMEM_ALIGN_SIZE)))
441 ret = -1;
442
443 while(1){
444 if ((msg->core_flag == 0) && (msg->rw_flag == 1)){
445 _memcpy_toio(msg->buf, buffer, size);
446 tmp_msg.size = size;
447 tmp_msg.core_flag = 1;
448 tmp_msg.rw_flag = 2;
449 _memcpy_toio(msg, &tmp_msg, sizeof(ramdump_shmem_t));
450 ret = size;
451 break;
452 }
453 else
454 ramdump_wait_delay(0);
455 }
456 return ret;
457}
458
459/*******************************************************************************
460* ¹¦ÄÜÃèÊö: ramdump_shm_trans_write_data
461* ²ÎÊý˵Ã÷:
462* (´«Èë²ÎÊý) void
463* (´«³ö²ÎÊý) void
464* ·µ »Ø Öµ: void
465* ÆäËü˵Ã÷: This function is used for ramdump to trans dump data to PC
466*******************************************************************************/
467int ramdump_shm_trans_write_data(unsigned char *buffer, unsigned int size)
468{
469 int ret = -1;
470 size_t dst_len = 0;
471 ramdump_shmem_t tmp_msg;
472 ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
473
474 if (size > (RAMDUMP_SHARED_MEM_LEN - roundup(sizeof(ramdump_shmem_t), RAMDUMP_SHMEM_ALIGN_SIZE)))
475 {
476 printk("ramdump_shm_trans_write_data failed!\n");
477 return ret;
478 }
479
480 while(1){
481 if ((msg->core_flag == 0) && (msg->rw_flag == 1)){
482 if (ramdump_compress_flag == 1){
483 ret = ramdump_lzo_compress(buffer, size, msg->buf, &dst_len);
484 }
485 if (ret != LZO_E_OK){
486 _memcpy_toio(msg->buf, buffer, size);
487 tmp_msg.size = size;
488 tmp_msg.core_flag = 1;
489 tmp_msg.rw_flag = 2;
490 _memcpy_toio(msg, &tmp_msg, sizeof(ramdump_shmem_t));
491 ret = size;
492 }else{
493 msg->size = dst_len;
494 msg->core_flag = 1;
495 msg->rw_flag = 2;
496 }
497 break;
498 }
499 else
500 ramdump_wait_delay(0);
501 }
502 return ret;
503}
504
505
506/*******************************************************************************
507* ¹¦ÄÜÃèÊö: ramdump_shm_trans_read
508* ²ÎÊý˵Ã÷:
509* (´«Èë²ÎÊý) void
510* (´«³ö²ÎÊý) void
511* ·µ »Ø Öµ: void
512* ÆäËü˵Ã÷: This function is used for ramdump to trans dump data to PC
513*******************************************************************************/
514int ramdump_shm_trans_read(unsigned char *buffer, unsigned int size)
515{
516 int ret;
517 ramdump_shmem_t tmp_msg;
518 ramdump_shmem_t *msg = (ramdump_shmem_t *)ramdump_shared_mem_base;
519
520 if (size > (RAMDUMP_SHARED_MEM_LEN - roundup(sizeof(ramdump_shmem_t), RAMDUMP_SHMEM_ALIGN_SIZE)))
521 ret = -1;
522
523 while(1){
524 if ((msg->core_flag == 0) && (msg->rw_flag == 2)){
525 if (size < msg->size)
526 return -1;
527 _memcpy_fromio(buffer, msg->buf, msg->size);
528 tmp_msg.size = msg->size;
529 tmp_msg.core_flag = 0;
530 tmp_msg.rw_flag = 1;
531 _memcpy_toio(msg, &tmp_msg, sizeof(ramdump_shmem_t));
532 ret = size;
533 break;
534 }
535 else
536 ramdump_wait_delay(0);
537 }
538 return ret;
539}
540#endif
541/*******************************************************************************
542* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_read
543* ²ÎÊý˵Ã÷:
544* (´«Èë²ÎÊý) buffer: data buff
545 size: data size
546* (´«³ö²ÎÊý) void
547* ·µ »Ø Öµ: void
548* ÆäËü˵Ã÷:
549*******************************************************************************/
550void ramdump_oss_data_trans_read(unsigned char *buffer, unsigned int size)
551{
552#ifdef _USE_VEHICLE_DC
553 if ((ramdump_export_mode == RAMDUMP_MODE_EMMC)
554 || (ramdump_export_mode == RAMDUMP_MODE_SPINAND))
555 ramdump_shm_trans_read(buffer, size);
556 else
557#endif
558 ramdump_usb_trans_read(buffer, size);
559}
560
561/*******************************************************************************
562* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_write
563* ²ÎÊý˵Ã÷:
564* (´«Èë²ÎÊý) buffer: data buff
565 size: data size
566* (´«³ö²ÎÊý) void
567* ·µ »Ø Öµ: void
568* ÆäËü˵Ã÷:
569*******************************************************************************/
570void ramdump_oss_data_trans_write(unsigned char *buffer, unsigned int size)
571{
572#ifdef _USE_VEHICLE_DC
573 if ((ramdump_export_mode == RAMDUMP_MODE_EMMC)
574 || (ramdump_export_mode == RAMDUMP_MODE_SPINAND))
575 ramdump_shm_trans_write(buffer, size);
576 else
577#endif
578 ramdump_usb_trans_write(buffer, size);
579
580}
581
582void ramdump_oss_data_trans_write_data(unsigned char *buffer, unsigned int size)
583{
584#ifdef _USE_VEHICLE_DC
585 if ((ramdump_export_mode == RAMDUMP_MODE_EMMC)
586 || (ramdump_export_mode == RAMDUMP_MODE_SPINAND)){
587 ramdump_shm_trans_write_data(buffer, size);
588 }
589 else
590#endif
591 ramdump_usb_trans_write(buffer, size);
592
593}
594
595/*******************************************************************************
596* ¹¦ÄÜÃèÊö: ramdump_oss_data_trans_done
597* ²ÎÊý˵Ã÷:
598* (´«Èë²ÎÊý) void
599* (´«³ö²ÎÊý) void
600* ·µ »Ø Öµ: void
601* ÆäËü˵Ã÷:
602*******************************************************************************/
603void ramdump_oss_data_trans_done(void)
604{
605#ifdef _OS_LINUX
606#ifdef _USE_VEHICLE_DC
607
608 /* µÈ´ýÊý¾Ý·¢ËÍÍêºó£¬ÔÙÖØÆô */
609 if ((ramdump_export_mode == RAMDUMP_MODE_EMMC)
610 || (ramdump_export_mode == RAMDUMP_MODE_SPINAND))
611 return;
612 else
613#endif
614 zDrvUsbPoll_Isr();
615#endif
616}
617
618void ramdump_oss_logbuf_create(void)
619{
620#ifdef _OS_LINUX
621#if defined CONFIG_PRINTK
622
623 unsigned long addr;
624 unsigned long size;
625
626 get_logbuf_info(&addr, &size);
627
628 ramdump_ram_conf_table_add(
629 "ap_log_buf",
630 (unsigned long)OSS_VIRT_TO_PHY(addr),
631 size,
632 addr,
633 RAMDUMP_FLAG_LEVEL_HIGH,
634 0);
635#endif
636#endif
637}
638
639#ifdef __cplusplus
640}
641#endif
642