blob: bcb6a53d7fedd600196cb97419f470c43ba97fa2 [file] [log] [blame]
xf.lied996a22025-03-13 23:49:05 -07001/*******************************************************************************
2* °æÈ¨ËùÓÐ (C)2016, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
3*
4* ÎļþÃû³Æ: ramdump_client_cap.c
5* Îļþ±êʶ: ramdump_client_cap.c
6* ÄÚÈÝÕªÒª: ramdump cap¿Í»§¶ËÒì³£ËÀ»úÏÖ³¡Êý¾Ýµ¼³öʵÏÖ
7*
8* ÐÞ¸ÄÈÕÆÚ °æ±¾ºÅ Ð޸ıê¼Ç ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ
9* ------------------------------------------------------------------------------
10* 2019/10/10 V1.0 Create 00130574 ´´½¨
11*
12*******************************************************************************/
13
14/*******************************************************************************
15* Í·Îļþ *
16*******************************************************************************/
17#include "ramdump.h"
18#include "ramdump_arch.h"
19#include <linux/module.h>
20#include <linux/soc/zte/rpmsg.h>
21#include "ram_config.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27/*******************************************************************************
28* ³£Á¿¶¨Òå *
29*******************************************************************************/
30
31/*******************************************************************************
32* ºê¶¨Òå *
33*******************************************************************************/
34
35/*******************************************************************************
36* Êý¾ÝÀàÐͶ¨Òå *
37*******************************************************************************/
38
39/*******************************************************************************
40* º¯ÊýÉùÃ÷ *
41*******************************************************************************/
42extern void ramdump_register_callbacks(void);
43extern unsigned char *ramdump_phy_to_vir(unsigned long phy, unsigned long size);
44extern void ramdump_shared_mem_init(void);
45extern void ramdump_data_transfer_to_device(void);
46extern void ramdump_oss_data_trans_init(void);
47extern unsigned char *ramdump_export_flag_base;
48
49/*******************************************************************************
50* ¾Ö²¿¾²Ì¬±äÁ¿¶¨Òå *
51*******************************************************************************/
52#define RAMDUMP_ON_DEFAULT_VAL (1)
53
54/*******************************************************************************
55* È«¾Ö±äÁ¿¶¨Òå *
56*******************************************************************************/
57/*
58 * run time control dump or not, use ( echo "0" > ramdump_on ) to close ramdump
59 */
60int sysctl_ramdump_on_panic = RAMDUMP_ON_DEFAULT_VAL;
61int ramdump_cap_init_flag = -1;
62int ramdump_count = 0;
63int ramdump_server_exp_core = RAMDUMP_FALSE;
64#ifdef CONFIG_RAMDUMP_USER
65unsigned int sysctl_ramdump_on_user = 1;
66#endif
67unsigned int ramdump_export_mode = 0xFF;
68/* Cmm file content */
69unsigned char *ramdump_cap_cmm_buf = NULL;
70/* err log file */
71unsigned char *ramdump_cap_error_log = NULL;
72unsigned int *cap_ddr_len_base = NULL;
73unsigned int sysctl_ramdump_emmc_size = 0x0;
74unsigned int sysctl_ramdump_emmc_start_addr = 0xFFFF;
75
76static struct ctl_table cfg_ramdump_array[] = {
77#ifdef CONFIG_RAMDUMP_USER
78 {
79 .procname = "sysctl_ramdump_on_user",
80 .data = &sysctl_ramdump_on_user,
81 .maxlen = sizeof(sysctl_ramdump_on_user),
82 .mode = 0644,
83 .proc_handler = proc_dointvec_minmax,
84 .extra1 = SYSCTL_ZERO,
85 .extra2 = SYSCTL_ONE,
86 },
87#endif
88 {
89 .procname = "ramdump_start_addr",
90 .data = &sysctl_ramdump_emmc_start_addr,
91 .maxlen = sizeof(u64),
92 .mode = 0644,
93 .proc_handler = proc_dointvec_minmax,
94 },
95 {
96 .procname = "ramdump_emmc_size",
97 .data = &sysctl_ramdump_emmc_size,
98 .maxlen = sizeof(u64),
99 .mode = 0644,
100 .proc_handler = proc_doulongvec_minmax,
101 },
102
103 { }
104};
105
106static struct ctl_table sysctl_ramdump_table[] = {
107 {
108 .procname = "ramdump_ap",
109 .mode = 0555,
110 .child = cfg_ramdump_array,
111 },
112 { }
113};
114
115/*******************************************************************************
116* ¾Ö²¿º¯ÊýʵÏÖ *
117*******************************************************************************/
118/*******************************************************************************
119* ¹¦ÄÜÃèÊö: ramdump_cap_icp_handle
120* ²ÎÊý˵Ã÷:
121* (´«Èë²ÎÊý) buf: icp msg addr
122* len: icp msg len
123* (´«³ö²ÎÊý) void
124* ·µ »Ø Öµ: void
125* ÆäËü˵Ã÷: This function is used for ramdump client icp msg handle, common entry
126*******************************************************************************/
127static void ramdump_cap_icp_handle(void *buf, unsigned int len)
128{
129 ramdump_msg_t *icp_msg = (ramdump_msg_t *)buf;
130
131 ramdump_server_exp_core = RAMDUMP_SUCCESS;
132
133 switch(icp_msg->msg_id)
134 {
135 case RAMDUMP_MSG_EXCEPT:
136 {
137 ramdump_panic("trans server received forced dump request from Ap server!\n");
138 break;
139 }
140
141 default:
142 {
143 ramdump_panic("trans server received forced dump request from Ap server!\n");
144 break;
145 }
146 }
147}
148
149/*******************************************************************************
150* ¹¦ÄÜÃèÊö: ramdump_oss_icp_create_channel
151* ²ÎÊý˵Ã÷:
152* (´«Èë²ÎÊý) actorID: icp send core id
153 chID: icp channel id
154 size: icp channel size
155* (´«³ö²ÎÊý) void
156* ·µ »Ø Öµ: int: if msg send success
157* ÆäËü˵Ã÷:
158*******************************************************************************/
159static int ramdump_cap_icp_create_channel(T_RpMsg_CoreID dstCoreID, T_RpMsg_ChID chID, unsigned int size)
160{
161 return rpmsgCreateChannel(dstCoreID, chID, size);
162}
163
164/*******************************************************************************
165* ¹¦ÄÜÃèÊö: ramdump_oss_icp_regcallback
166* ²ÎÊý˵Ã÷:
167* (´«Èë²ÎÊý) actorID: icp send core id
168 chID: icp channel id
169 callback:icp callback fun
170* (´«³ö²ÎÊý) void
171* ·µ »Ø Öµ: int: if msg send success
172* ÆäËü˵Ã÷:
173*******************************************************************************/
174static int ramdump_cap_icp_regcallback (T_RpMsg_CoreID coreID, unsigned int chID, T_RpMsg_Callback callback)
175{
176 return rpmsgRegCallBack(coreID, chID, callback);
177}
178
179/*******************************************************************************
180* ¹¦ÄÜÃèÊö: ramdump_init_sysctl_table
181* ²ÎÊý˵Ã÷:
182* (´«Èë²ÎÊý) void
183* (´«³ö²ÎÊý) void
184* ·µ »Ø Öµ: void
185* ÆäËü˵Ã÷: ×¢²ásysctlÃüÁÓû§Ì¬Ê¹ÓÃsysctl¿ØÖÆramdump´æ´¢µØÖ·
186*******************************************************************************/
187void ramdump_init_sysctl_table(void)
188{
189 register_sysctl_table(sysctl_ramdump_table);
190}
191
192/*******************************************************************************
193* ¹¦ÄÜÃèÊö: ramdump_cap_icp_init
194* ²ÎÊý˵Ã÷:
195* (´«Èë²ÎÊý) void
196* (´«³ö²ÎÊý) void
197* ·µ »Ø Öµ: void
198* ÆäËü˵Ã÷: This function is used for ramdump client icp init
199*******************************************************************************/
200static int ramdump_cap_icp_init(void)
201{
202 int ret = 0;
203
204 ret = ramdump_cap_icp_create_channel(
205 RAMDUMP_SERVER_AP,
206 RAMDUMP_CHANNEL,
207 RAMDUMP_CHANNEL_SIZE);
208
209 if (ret != RAMDUMP_SUCCESS)
210 {
211 return ret;
212 }
213 ret = ramdump_cap_icp_regcallback(
214 RAMDUMP_SERVER_AP,
215 RAMDUMP_CHANNEL,
216 ramdump_cap_icp_handle);
217
218 if (ret != RAMDUMP_SUCCESS)
219 {
220 return ret;
221 }
222 return RAMDUMP_SUCCESS;
223}
224
225/*******************************************************************************
226* ¹¦ÄÜÃèÊö: ramdump_notify_server_panic
227* ²ÎÊý˵Ã÷:
228* (´«Èë²ÎÊý) void
229* (´«³ö²ÎÊý) void
230* ·µ »Ø Öµ: void
231* ÆäËü˵Ã÷: This function is used for cap notify ramdump server to panic
232*******************************************************************************/
233static int ramdump_notify_server_panic(void)
234{
235 int ret = 0;
236 T_RpMsg_Msg rpMsg = {0};
237 ramdump_msg_t ramdumpMsg = {0};
238
239 ramdumpMsg.msg_id = RAMDUMP_MSG_EXCEPT;
240 ramdumpMsg.cpu_id = CORE_AP;
241
242 rpMsg.coreID = RAMDUMP_SERVER_AP;
243 rpMsg.chID = RAMDUMP_CHANNEL;
244 rpMsg.flag = RPMSG_WRITE_INT | RPMSG_WRITE_IRQLOCK;
245 rpMsg.len = sizeof(ramdump_msg_t);
246 rpMsg.buf = &ramdumpMsg;
247
248 ret = rpmsgWrite(&rpMsg);
249 return ret;
250}
251
252/*******************************************************************************
253* ¹¦ÄÜÃèÊö: ramdump_cap_store_ram_conf
254* ²ÎÊý˵Ã÷:
255* (´«Èë²ÎÊý) mem: addr
256* (´«³ö²ÎÊý) void
257* ·µ »Ø Öµ: unsigend char*: changed addr
258* ÆäËü˵Ã÷: This function is used to store ram conf
259*******************************************************************************/
260static unsigned char *ramdump_cap_store_ram_conf(unsigned char *mem)
261{
262 mem += sprintf(
263 mem,
264 "data.load.binary &ramdump_dir\\%s A:0x%x--A:0x%x /noclear\n",
265 "cap_ddr.bin",
266 (unsigned int)DDR_BASE_CAP_ADDR_PA,
267 (unsigned int)(DDR_BASE_CAP_ADDR_PA + *cap_ddr_len_base - 1));
268 mem += sprintf(
269 mem,
270 "data.load.binary &ramdump_dir\\%s A:0x%x--A:0x%x /noclear\n",
271 "cap.cmm",
272 (unsigned int)RAMDUMP_CAP_CMM_BUF_ADDR,
273 (unsigned int)(RAMDUMP_CAP_CMM_BUF_ADDR + RAMDUMP_CAP_CMM_BUF_LEN_REAL - 1));
274 mem += sprintf(
275 mem,
276 "data.load.binary &ramdump_dir\\%s A:0x%x--A:0x%x /noclear\n",
277 "cap_err_log.txt",
278 (unsigned int)RAMDUMP_CAP_LOG_BUF_ADDR,
279 (unsigned int)(RAMDUMP_CAP_LOG_BUF_ADDR + RAMDUMP_CAP_LOG_BUF_LEN - 1));
280 return mem;
281}
282/*******************************************************************************
283* ¹¦ÄÜÃèÊö: ramdump_cap_cmm_create
284* ²ÎÊý˵Ã÷:
285* (´«Èë²ÎÊý) void
286* (´«³ö²ÎÊý) void
287* ·µ »Ø Öµ: void
288* ÆäËü˵Ã÷: This function is used for server to generate cmm scripts
289*******************************************************************************/
290static void ramdump_cap_cmm_create(void)
291{
292 unsigned char *pcmm_buf = ramdump_cap_cmm_buf;
293
294 memset(ramdump_cap_cmm_buf, 0, RAMDUMP_CAP_CMM_BUF_LEN_REAL);
295
296 // store the cmm BEGIN
297 pcmm_buf += sprintf(pcmm_buf, "ENTRY &ramdump_dir\n");
298
299 // store procmodes regs
300 pcmm_buf = ramdump_arch_store_modes_regs(pcmm_buf);
301
302 // store ram config
303 pcmm_buf = ramdump_cap_store_ram_conf(pcmm_buf);
304
305 // store memory map control regs
306 pcmm_buf = ramdump_arch_store_mm_regs(pcmm_buf);
307
308 // store end symbol
309 pcmm_buf += sprintf(pcmm_buf, "ENDDO\n");
310
311}
312
313/*******************************************************************************
314* ¹¦ÄÜÃèÊö: ramdump_trans_cap_error_log_create
315* ²ÎÊý˵Ã÷:
316* (´«Èë²ÎÊý) void
317* (´«³ö²ÎÊý) void
318* ·µ »Ø Öµ: void
319* ÆäËü˵Ã÷: This function is used to create err log file
320*******************************************************************************/
321static void ramdump_cap_error_log_create(void)
322{
323 unsigned char *buf = ramdump_cap_error_log;
324
325 memset(ramdump_cap_error_log, 0, RAMDUMP_CAP_LOG_BUF_LEN);
326 buf += sprintf(buf, "dump at core%d,", smp_processor_id());
327 if (current->mm != NULL)
328 buf += sprintf(buf, "in user,task is: %s\n", current->comm);
329 else
330 buf += sprintf(buf, "in kernel,task is: %s\n", current->comm);
331
332 if (ramdump_server_exp_core)
333 buf += sprintf(buf, "recv dumpinfo from ap\n");
334}
335
336/*******************************************************************************
337* È«¾Öº¯ÊýʵÏÖ *
338*******************************************************************************/
339/*******************************************************************************
340* ¹¦ÄÜÃèÊö: ramdump_ram_conf_table_add
341* ²ÎÊý˵Ã÷:
342* (´«Èë²ÎÊý) ram_name: dump ram name
343 ram_start: dump ram start(virtual addr)
344 ram_size: dump ram size
345 ram_virt: dump ram virt addr
346 ram_flag: dump ram flag(copy/exter/callback)
347 ram_extra: dump ram extra access addr
348* (´«³ö²ÎÊý) void
349* ·µ »Ø Öµ: void
350* ÆäËü˵Ã÷: This function is used to add dump ram conf into public table
351*******************************************************************************/
352void ramdump_ram_conf_table_add(
353 char *ram_name,
354 unsigned long ram_phy,
355 unsigned long ram_size,
356 unsigned long ram_virt,
357 unsigned long ram_flag,
358 unsigned long ram_extra)
359{
360}
361void ramdump_init_cmm_buf(void)
362{
363 /* Cmm file content */
364 ramdump_cap_cmm_buf = ramdump_phy_to_vir((unsigned long)RAMDUMP_CAP_CMM_BUF_ADDR, RAMDUMP_CAP_CMM_BUF_LEN_REAL);
365 /* err log file */
366 ramdump_cap_error_log = ramdump_phy_to_vir((unsigned long)RAMDUMP_CAP_LOG_BUF_ADDR, RAMDUMP_CAP_LOG_BUF_LEN);
367 cap_ddr_len_base = (unsigned int *)ramdump_phy_to_vir((unsigned long)IRAM_BASE_ADDR_BOOT_DDR, sizeof(unsigned long));
368}
369
370/*******************************************************************************
371* ¹¦ÄÜÃèÊö: ramdump_init
372* ²ÎÊý˵Ã÷:
373* (´«Èë²ÎÊý) void
374* (´«³ö²ÎÊý) void
375* ·µ »Ø Öµ: RAMDUMP_SUCCESS or RAMDUMP_FAILED
376* ÆäËü˵Ã÷: This function is used for ramdump init
377*******************************************************************************/
378int __init ramdump_init(void)
379{
380 int ret = 0;
381 ramdump_printf("Ramdump cap init start!!!!!\n");
382
383 if (ramdump_cap_init_flag == RAMDUMP_TRUE)
384 return RAMDUMP_SUCCESS;
385 ramdump_printf("Ramdump cap init rpmsg start!!!!!\n");
386 ret = ramdump_cap_icp_init();
387 if (ret != RAMDUMP_ICP_SUCCESS)
388 return ret;
389
390 ramdump_register_callbacks();
391
392 ramdump_init_cmm_buf();
393
394 ramdump_init_sysctl_table();
395
396 ramdump_shared_mem_init();
397 ramdump_oss_data_trans_init();
398
399 ramdump_printf("Ramdump cap init success!\n");
400 ramdump_cap_init_flag = RAMDUMP_TRUE;
401
402 return RAMDUMP_SUCCESS;
403}
404
405/*******************************************************************************
406* ¹¦ÄÜÃèÊö: ramdump_entry
407* ²ÎÊý˵Ã÷:
408* (´«Èë²ÎÊý) void
409* (´«³ö²ÎÊý) void
410* ·µ »Ø Öµ: void
411* ÆäËü˵Ã÷: This function is used for ramdump entry
412*******************************************************************************/
413void ramdump_entry (void)
414{
415 unsigned long flags;
416 if (sysctl_ramdump_on_panic == false)
417 return;
418
419 /*
420 * we need lock the irq, this can`t be interrupt.
421 */
422 ramdump_irq_lock(flags);
423
424 if (!ramdump_cap_init_flag)
425 while(true); /* endless circle */
426
427 if (++ramdump_count > 1)
428 while(true); /* endless circle */
429
430 /*
431 * save all regs first.
432 */
433 ramdump_arch_save_all_regs();
434 // generate error log
435 ramdump_cap_error_log_create();
436
437 //Éú³Écmm½Å±¾µÄµ¼³öÅäÖÃ
438 ramdump_cap_cmm_create();
439
440 /* notify client ramdump */
441 ramdump_notify_server_panic();
442
443 ramdump_arch_clean_caches();
444 ramdump_export_mode = *(unsigned int *)ramdump_export_flag_base;
445
446 if((ramdump_export_mode == RAMDUMP_MODE_EMMC)
447 || (ramdump_export_mode == RAMDUMP_MODE_SPINAND))
448 ramdump_data_transfer_to_device();
449
450 while(true)
451 ;
452}
453
454#ifdef __cplusplus
455}
456#endif
457