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