[Feature][T106_eSDK]17.09(SDK4.8)diff_19.00(SDK5.0)
Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No
Change-Id: I768f6d42285f04acf919b9f8f6cd34af460c3ef4
diff --git a/upstream/linux-5.10/kernel/ramdump/ramdump_client_cap.c b/upstream/linux-5.10/kernel/ramdump/ramdump_client_cap.c
new file mode 100755
index 0000000..bcb6a53
--- /dev/null
+++ b/upstream/linux-5.10/kernel/ramdump/ramdump_client_cap.c
@@ -0,0 +1,457 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2016, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+*
+* ÎļþÃû³Æ: ramdump_client_cap.c
+* Îļþ±êʶ: ramdump_client_cap.c
+* ÄÚÈÝÕªÒª: ramdump cap¿Í»§¶ËÒì³£ËÀ»úÏÖ³¡Êý¾Ýµ¼³öʵÏÖ
+*
+* ÐÞ¸ÄÈÕÆÚ °æ±¾ºÅ Ð޸ıê¼Ç ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ
+* ------------------------------------------------------------------------------
+* 2019/10/10 V1.0 Create 00130574 ´´½¨
+*
+*******************************************************************************/
+
+/*******************************************************************************
+* Í·Îļþ *
+*******************************************************************************/
+#include "ramdump.h"
+#include "ramdump_arch.h"
+#include <linux/module.h>
+#include <linux/soc/zte/rpmsg.h>
+#include "ram_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+* ³£Á¿¶¨Òå *
+*******************************************************************************/
+
+/*******************************************************************************
+* ºê¶¨Òå *
+*******************************************************************************/
+
+/*******************************************************************************
+* Êý¾ÝÀàÐͶ¨Òå *
+*******************************************************************************/
+
+/*******************************************************************************
+* º¯ÊýÉùÃ÷ *
+*******************************************************************************/
+extern void ramdump_register_callbacks(void);
+extern unsigned char *ramdump_phy_to_vir(unsigned long phy, unsigned long size);
+extern void ramdump_shared_mem_init(void);
+extern void ramdump_data_transfer_to_device(void);
+extern void ramdump_oss_data_trans_init(void);
+extern unsigned char *ramdump_export_flag_base;
+
+/*******************************************************************************
+* ¾Ö²¿¾²Ì¬±äÁ¿¶¨Òå *
+*******************************************************************************/
+#define RAMDUMP_ON_DEFAULT_VAL (1)
+
+/*******************************************************************************
+* È«¾Ö±äÁ¿¶¨Òå *
+*******************************************************************************/
+/*
+ * run time control dump or not, use ( echo "0" > ramdump_on ) to close ramdump
+ */
+int sysctl_ramdump_on_panic = RAMDUMP_ON_DEFAULT_VAL;
+int ramdump_cap_init_flag = -1;
+int ramdump_count = 0;
+int ramdump_server_exp_core = RAMDUMP_FALSE;
+#ifdef CONFIG_RAMDUMP_USER
+unsigned int sysctl_ramdump_on_user = 1;
+#endif
+unsigned int ramdump_export_mode = 0xFF;
+/* Cmm file content */
+unsigned char *ramdump_cap_cmm_buf = NULL;
+/* err log file */
+unsigned char *ramdump_cap_error_log = NULL;
+unsigned int *cap_ddr_len_base = NULL;
+unsigned int sysctl_ramdump_emmc_size = 0x0;
+unsigned int sysctl_ramdump_emmc_start_addr = 0xFFFF;
+
+static struct ctl_table cfg_ramdump_array[] = {
+#ifdef CONFIG_RAMDUMP_USER
+ {
+ .procname = "sysctl_ramdump_on_user",
+ .data = &sysctl_ramdump_on_user,
+ .maxlen = sizeof(sysctl_ramdump_on_user),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE,
+ },
+#endif
+ {
+ .procname = "ramdump_start_addr",
+ .data = &sysctl_ramdump_emmc_start_addr,
+ .maxlen = sizeof(u64),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ },
+ {
+ .procname = "ramdump_emmc_size",
+ .data = &sysctl_ramdump_emmc_size,
+ .maxlen = sizeof(u64),
+ .mode = 0644,
+ .proc_handler = proc_doulongvec_minmax,
+ },
+
+ { }
+};
+
+static struct ctl_table sysctl_ramdump_table[] = {
+ {
+ .procname = "ramdump_ap",
+ .mode = 0555,
+ .child = cfg_ramdump_array,
+ },
+ { }
+};
+
+/*******************************************************************************
+* ¾Ö²¿º¯ÊýʵÏÖ *
+*******************************************************************************/
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_cap_icp_handle
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) buf: icp msg addr
+* len: icp msg len
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: This function is used for ramdump client icp msg handle, common entry
+*******************************************************************************/
+static void ramdump_cap_icp_handle(void *buf, unsigned int len)
+{
+ ramdump_msg_t *icp_msg = (ramdump_msg_t *)buf;
+
+ ramdump_server_exp_core = RAMDUMP_SUCCESS;
+
+ switch(icp_msg->msg_id)
+ {
+ case RAMDUMP_MSG_EXCEPT:
+ {
+ ramdump_panic("trans server received forced dump request from Ap server!\n");
+ break;
+ }
+
+ default:
+ {
+ ramdump_panic("trans server received forced dump request from Ap server!\n");
+ break;
+ }
+ }
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_oss_icp_create_channel
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) actorID: icp send core id
+ chID: icp channel id
+ size: icp channel size
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: int: if msg send success
+* ÆäËü˵Ã÷:
+*******************************************************************************/
+static int ramdump_cap_icp_create_channel(T_RpMsg_CoreID dstCoreID, T_RpMsg_ChID chID, unsigned int size)
+{
+ return rpmsgCreateChannel(dstCoreID, chID, size);
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_oss_icp_regcallback
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) actorID: icp send core id
+ chID: icp channel id
+ callback:icp callback fun
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: int: if msg send success
+* ÆäËü˵Ã÷:
+*******************************************************************************/
+static int ramdump_cap_icp_regcallback (T_RpMsg_CoreID coreID, unsigned int chID, T_RpMsg_Callback callback)
+{
+ return rpmsgRegCallBack(coreID, chID, callback);
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_init_sysctl_table
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: ×¢²ásysctlÃüÁÓû§Ì¬Ê¹ÓÃsysctl¿ØÖÆramdump´æ´¢µØÖ·
+*******************************************************************************/
+void ramdump_init_sysctl_table(void)
+{
+ register_sysctl_table(sysctl_ramdump_table);
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_cap_icp_init
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: This function is used for ramdump client icp init
+*******************************************************************************/
+static int ramdump_cap_icp_init(void)
+{
+ int ret = 0;
+
+ ret = ramdump_cap_icp_create_channel(
+ RAMDUMP_SERVER_AP,
+ RAMDUMP_CHANNEL,
+ RAMDUMP_CHANNEL_SIZE);
+
+ if (ret != RAMDUMP_SUCCESS)
+ {
+ return ret;
+ }
+ ret = ramdump_cap_icp_regcallback(
+ RAMDUMP_SERVER_AP,
+ RAMDUMP_CHANNEL,
+ ramdump_cap_icp_handle);
+
+ if (ret != RAMDUMP_SUCCESS)
+ {
+ return ret;
+ }
+ return RAMDUMP_SUCCESS;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_notify_server_panic
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: This function is used for cap notify ramdump server to panic
+*******************************************************************************/
+static int ramdump_notify_server_panic(void)
+{
+ int ret = 0;
+ T_RpMsg_Msg rpMsg = {0};
+ ramdump_msg_t ramdumpMsg = {0};
+
+ ramdumpMsg.msg_id = RAMDUMP_MSG_EXCEPT;
+ ramdumpMsg.cpu_id = CORE_AP;
+
+ rpMsg.coreID = RAMDUMP_SERVER_AP;
+ rpMsg.chID = RAMDUMP_CHANNEL;
+ rpMsg.flag = RPMSG_WRITE_INT | RPMSG_WRITE_IRQLOCK;
+ rpMsg.len = sizeof(ramdump_msg_t);
+ rpMsg.buf = &ramdumpMsg;
+
+ ret = rpmsgWrite(&rpMsg);
+ return ret;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_cap_store_ram_conf
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) mem: addr
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: unsigend char*: changed addr
+* ÆäËü˵Ã÷: This function is used to store ram conf
+*******************************************************************************/
+static unsigned char *ramdump_cap_store_ram_conf(unsigned char *mem)
+{
+ mem += sprintf(
+ mem,
+ "data.load.binary &ramdump_dir\\%s A:0x%x--A:0x%x /noclear\n",
+ "cap_ddr.bin",
+ (unsigned int)DDR_BASE_CAP_ADDR_PA,
+ (unsigned int)(DDR_BASE_CAP_ADDR_PA + *cap_ddr_len_base - 1));
+ mem += sprintf(
+ mem,
+ "data.load.binary &ramdump_dir\\%s A:0x%x--A:0x%x /noclear\n",
+ "cap.cmm",
+ (unsigned int)RAMDUMP_CAP_CMM_BUF_ADDR,
+ (unsigned int)(RAMDUMP_CAP_CMM_BUF_ADDR + RAMDUMP_CAP_CMM_BUF_LEN_REAL - 1));
+ mem += sprintf(
+ mem,
+ "data.load.binary &ramdump_dir\\%s A:0x%x--A:0x%x /noclear\n",
+ "cap_err_log.txt",
+ (unsigned int)RAMDUMP_CAP_LOG_BUF_ADDR,
+ (unsigned int)(RAMDUMP_CAP_LOG_BUF_ADDR + RAMDUMP_CAP_LOG_BUF_LEN - 1));
+ return mem;
+}
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_cap_cmm_create
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: This function is used for server to generate cmm scripts
+*******************************************************************************/
+static void ramdump_cap_cmm_create(void)
+{
+ unsigned char *pcmm_buf = ramdump_cap_cmm_buf;
+
+ memset(ramdump_cap_cmm_buf, 0, RAMDUMP_CAP_CMM_BUF_LEN_REAL);
+
+ // store the cmm BEGIN
+ pcmm_buf += sprintf(pcmm_buf, "ENTRY &ramdump_dir\n");
+
+ // store procmodes regs
+ pcmm_buf = ramdump_arch_store_modes_regs(pcmm_buf);
+
+ // store ram config
+ pcmm_buf = ramdump_cap_store_ram_conf(pcmm_buf);
+
+ // store memory map control regs
+ pcmm_buf = ramdump_arch_store_mm_regs(pcmm_buf);
+
+ // store end symbol
+ pcmm_buf += sprintf(pcmm_buf, "ENDDO\n");
+
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_trans_cap_error_log_create
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: This function is used to create err log file
+*******************************************************************************/
+static void ramdump_cap_error_log_create(void)
+{
+ unsigned char *buf = ramdump_cap_error_log;
+
+ memset(ramdump_cap_error_log, 0, RAMDUMP_CAP_LOG_BUF_LEN);
+ buf += sprintf(buf, "dump at core%d,", smp_processor_id());
+ if (current->mm != NULL)
+ buf += sprintf(buf, "in user,task is: %s\n", current->comm);
+ else
+ buf += sprintf(buf, "in kernel,task is: %s\n", current->comm);
+
+ if (ramdump_server_exp_core)
+ buf += sprintf(buf, "recv dumpinfo from ap\n");
+}
+
+/*******************************************************************************
+* È«¾Öº¯ÊýʵÏÖ *
+*******************************************************************************/
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_ram_conf_table_add
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) ram_name: dump ram name
+ ram_start: dump ram start(virtual addr)
+ ram_size: dump ram size
+ ram_virt: dump ram virt addr
+ ram_flag: dump ram flag(copy/exter/callback)
+ ram_extra: dump ram extra access addr
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: This function is used to add dump ram conf into public table
+*******************************************************************************/
+void ramdump_ram_conf_table_add(
+ char *ram_name,
+ unsigned long ram_phy,
+ unsigned long ram_size,
+ unsigned long ram_virt,
+ unsigned long ram_flag,
+ unsigned long ram_extra)
+{
+}
+void ramdump_init_cmm_buf(void)
+{
+ /* Cmm file content */
+ ramdump_cap_cmm_buf = ramdump_phy_to_vir((unsigned long)RAMDUMP_CAP_CMM_BUF_ADDR, RAMDUMP_CAP_CMM_BUF_LEN_REAL);
+ /* err log file */
+ ramdump_cap_error_log = ramdump_phy_to_vir((unsigned long)RAMDUMP_CAP_LOG_BUF_ADDR, RAMDUMP_CAP_LOG_BUF_LEN);
+ cap_ddr_len_base = (unsigned int *)ramdump_phy_to_vir((unsigned long)IRAM_BASE_ADDR_BOOT_DDR, sizeof(unsigned long));
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_init
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: RAMDUMP_SUCCESS or RAMDUMP_FAILED
+* ÆäËü˵Ã÷: This function is used for ramdump init
+*******************************************************************************/
+int __init ramdump_init(void)
+{
+ int ret = 0;
+ ramdump_printf("Ramdump cap init start!!!!!\n");
+
+ if (ramdump_cap_init_flag == RAMDUMP_TRUE)
+ return RAMDUMP_SUCCESS;
+ ramdump_printf("Ramdump cap init rpmsg start!!!!!\n");
+ ret = ramdump_cap_icp_init();
+ if (ret != RAMDUMP_ICP_SUCCESS)
+ return ret;
+
+ ramdump_register_callbacks();
+
+ ramdump_init_cmm_buf();
+
+ ramdump_init_sysctl_table();
+
+ ramdump_shared_mem_init();
+ ramdump_oss_data_trans_init();
+
+ ramdump_printf("Ramdump cap init success!\n");
+ ramdump_cap_init_flag = RAMDUMP_TRUE;
+
+ return RAMDUMP_SUCCESS;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö: ramdump_entry
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: void
+* ÆäËü˵Ã÷: This function is used for ramdump entry
+*******************************************************************************/
+void ramdump_entry (void)
+{
+ unsigned long flags;
+ if (sysctl_ramdump_on_panic == false)
+ return;
+
+ /*
+ * we need lock the irq, this can`t be interrupt.
+ */
+ ramdump_irq_lock(flags);
+
+ if (!ramdump_cap_init_flag)
+ while(true); /* endless circle */
+
+ if (++ramdump_count > 1)
+ while(true); /* endless circle */
+
+ /*
+ * save all regs first.
+ */
+ ramdump_arch_save_all_regs();
+ // generate error log
+ ramdump_cap_error_log_create();
+
+ //Éú³Écmm½Å±¾µÄµ¼³öÅäÖÃ
+ ramdump_cap_cmm_create();
+
+ /* notify client ramdump */
+ ramdump_notify_server_panic();
+
+ ramdump_arch_clean_caches();
+ ramdump_export_mode = *(unsigned int *)ramdump_export_flag_base;
+
+ if((ramdump_export_mode == RAMDUMP_MODE_EMMC)
+ || (ramdump_export_mode == RAMDUMP_MODE_SPINAND))
+ ramdump_data_transfer_to_device();
+
+ while(true)
+ ;
+}
+
+#ifdef __cplusplus
+}
+#endif
+