[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
+
diff --git a/upstream/linux-5.10/kernel/ramdump/ramdump_emmc.c b/upstream/linux-5.10/kernel/ramdump/ramdump_emmc.c
new file mode 100755
index 0000000..0c28f27
--- /dev/null
+++ b/upstream/linux-5.10/kernel/ramdump/ramdump_emmc.c
@@ -0,0 +1,170 @@
+/**
+ * @file oss_ramdump_osa.c
+ * @brief Implementation of Ramdump os adapt
+ *
+ * Copyright (C) 2017 Sanechips Technology Co., Ltd.
+ * @author Qing Wang <wang.qing@sanechips.com.cn>
+ * @ingroup si_ap_oss_ramdump_id
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*******************************************************************************
+ *                           Include header files                              *
+ ******************************************************************************/
+#include "ramdump.h"
+#include "ramdump_emmc.h"
+#include "ram_config.h"
+#include "ramdump_compress.h"
+#include <linux/lzo.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+*                          Extern function declarations                        *
+*******************************************************************************/
+
+/*******************************************************************************
+*                          Extern variable declarations                        *
+*******************************************************************************/
+extern unsigned char *ramdump_shared_mem_base;
+extern unsigned char *ramdump_emmc_flag_base;
+extern unsigned int ramdump_compress_flag;
+
+/*******************************************************************************
+ *                             Macro definitions                               *
+ ******************************************************************************/
+#define RAMDUMP_DELAY_MS_COUNT (2500)
+
+/*******************************************************************************
+ *                             Type definitions                                *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *                        Local function declarations                          *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *                         Local variable definitions                          *
+ ******************************************************************************/
+
+/*******************************************************************************
+ *                        Global variable definitions                          *
+ ******************************************************************************/
+unsigned int ramdump_emmc_size = 0;
+volatile unsigned int ramdump_emmc_offset = 0;
+extern unsigned int ramdump_device_file_cnt;
+
+/*******************************************************************************
+ *                      Inline function implementations                        *
+ ******************************************************************************/
+static inline void ramdump_wait_delay( unsigned long ms)
+{
+	volatile int j = 0;
+	for (j = 0; j < 10000; j++);
+}
+
+/*******************************************************************************
+ *                      Local function implementations                         *
+ ******************************************************************************/
+int ramdump_emmc_init(ramdump_file_t *fp)
+{
+	fp->magic = 0x2A2A2A2A;
+	ramdump_emmc_offset = roundup(sizeof(ramdump_file_t), RAMDUMP_EMMC_ALIGN_SIZE);
+	
+	if(RAMDUMP_TRANS_EMMC_LEN > ramdump_emmc_offset)
+	{
+		ramdump_emmc_size = RAMDUMP_TRANS_EMMC_LEN - ramdump_emmc_offset;
+	}
+	else
+	{
+		printk("[ramdump] emmc start addr is %ld, emmc size= %ld, error: size smaller than ramdump file header, return!\n", sysctl_ramdump_emmc_start_addr, sysctl_ramdump_emmc_size);
+		return -1;
+	}
+
+	if(mmc_ramdump_init()){
+		ramdump_printf("EMMC init failed! No ramdump data trans to emmc!\n");
+		return -1;
+	}
+	return 0;
+}
+
+int ramdump_emmc_write_file(char *file_name, unsigned int file_size, ramdump_file_t *fp)
+{
+	if (ramdump_device_file_cnt >= RAMDUMP_FILE_NUM_MAX)
+		return -1;
+	if (ramdump_emmc_offset >= RAMDUMP_TRANS_EMMC_LEN)
+		return -1;
+
+	fp->file_fp[ramdump_device_file_cnt].magic = 0x3A3A3A3A;
+	strncpy(fp->file_fp[ramdump_device_file_cnt].file_name, file_name, RAMDUMP_RAMCONF_FILENAME_MAXLEN - 1);
+	fp->file_fp[ramdump_device_file_cnt].offset = ramdump_emmc_offset;
+	fp->file_fp[ramdump_device_file_cnt].size = file_size;
+	return 0;
+}
+
+int ramdump_emmc_write_file_head(ramdump_file_t *fp)
+{
+	int ret = -1;
+	mmc_bwrite(RAMDUMP_EMMC_ADDR, roundup(sizeof(ramdump_file_t), RAMDUMP_EMMC_ALIGN_SIZE), fp);
+	return ret;
+}
+
+int ramdump_emmc_write_data(ramdump_shmem_t *msg, ramdump_file_t *fp, unsigned int size)
+{
+	int ret = 0;
+	unsigned int buffer = RAMDUMP_EMMC_ADDR + ramdump_emmc_offset;
+
+	if (ramdump_device_file_cnt >= RAMDUMP_FILE_NUM_MAX)
+		return -1;
+
+	while(1){
+		if ((msg->core_flag == 1) && (msg->rw_flag == 2)){
+			if(msg->size >= (ramdump_emmc_size - fp->file_fp[ramdump_device_file_cnt].offset))
+				return -1;
+			ret = mmc_bwrite(buffer, msg->size, msg->buf);
+			ramdump_emmc_offset = ramdump_emmc_offset + roundup(msg->size, RAMDUMP_EMMC_ALIGN_SIZE);
+			msg->core_flag = 1;
+			msg->rw_flag = 1;
+			ret = msg->size;
+			break;
+		}
+		else
+			ramdump_wait_delay(0);
+	}
+	return ret;
+}
+
+int ramdump_emmc_read(char *buffer, ramdump_shmem_t *msg, unsigned int size)
+{
+	int ret = 0;
+
+	return ret;
+}
+
+void ramdump_emmc_close(ramdump_file_t *fp)
+{
+	fp->file_size = ramdump_emmc_offset;
+	ramdump_emmc_write_file_head(fp);
+	ramdump_printf("ramdump trans emmc finished!\n");
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/upstream/linux-5.10/kernel/ramdump/ramdump_emmc.h b/upstream/linux-5.10/kernel/ramdump/ramdump_emmc.h
new file mode 100755
index 0000000..1028ab2
--- /dev/null
+++ b/upstream/linux-5.10/kernel/ramdump/ramdump_emmc.h
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* °æÈ¨ËùÓÐ (C)2016, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+* 
+* ÎļþÃû³Æ: ramdump_emmc.h
+* Îļþ±êʶ: ramdump_emmc.h
+* ÄÚÈÝÕªÒª: ramdump emmcÍ·Îļþ
+* ʹÓ÷½·¨: #include "ramdump_emmc.h"
+* 
+* ÐÞ¸ÄÈÕÆÚ        °æ±¾ºÅ      Ð޸ıê¼Ç        ÐÞ¸ÄÈË          ÐÞ¸ÄÄÚÈÝ
+* ------------------------------------------------------------------------------
+* 2016/3/10      V1.0        Create           ÕÔ¾ü¿ü          ´´½¨
+* 
+*******************************************************************************/
+
+#ifndef _RAMDUMP_EMMC_H
+#define _RAMDUMP_EMMC_H
+
+/*******************************************************************************
+*                                   Í·Îļþ                                     *
+*******************************************************************************/
+#include "ramdump.h"
+#include <linux/mmc/mmc_func.h>
+
+/*******************************************************************************
+*                                Íⲿ±äÁ¿ÉùÃ÷                                  *
+*******************************************************************************/
+extern unsigned int sysctl_ramdump_emmc_start_addr;
+extern unsigned int sysctl_ramdump_emmc_size;
+extern volatile unsigned int ramdump_emmc_offset;
+
+/*******************************************************************************
+*                                   ºê¶¨Òå                                     *
+*******************************************************************************/
+#define RAMDUMP_EMMC_ADDR         (sysctl_ramdump_emmc_start_addr * 512) 
+#define RAMDUMP_TRANS_EMMC_LEN    (sysctl_ramdump_emmc_size * 512)
+
+/*******************************************************************************
+*                                Êý¾ÝÀàÐͶ¨Òå                                  *
+*******************************************************************************/
+
+/*******************************************************************************
+*                                È«¾Ö±äÁ¿ÉùÃ÷                                  *
+*******************************************************************************/
+
+/*******************************************************************************
+*                                È«¾Öº¯ÊýÉùÃ÷                                  *
+*******************************************************************************/
+/**
+ * @brief ramdump_emmc_init .
+ *
+ * @param void.
+ *
+ * @return int.
+ * @retval standard error
+ * @note   This function is used for ramdump init
+ */
+int ramdump_emmc_init(ramdump_file_t *fp);
+int ramdump_emmc_write_file(char *file_name, unsigned int file_size, ramdump_file_t *fp);
+int ramdump_emmc_write_file_head(ramdump_file_t *fp);
+int ramdump_emmc_modify_file_size(ramdump_file_t *fp, unsigned int file_size);
+int ramdump_emmc_write_data(ramdump_shmem_t *msg, ramdump_file_t *fp, unsigned int size);
+int ramdump_emmc_write_logbuf(ramdump_file_t *fp);
+void ramdump_emmc_close(ramdump_file_t *fp);
+int ramdump_emmc_write_log_txt(ramdump_file_t *fp);
+
+/*******************************************************************************
+*                                ÄÚÁªº¯ÊýʵÏÖ                                  *
+*******************************************************************************/
+
+#endif  //#ifndef _RAMDUMP_EMMC_H
+