[Feature][ZXW-65]merged P49 base code

Change-Id: I3e09c0c3d47483bc645f02310380ecb7fc6f4041
diff --git a/ap/os/linux/linux-3.4.x/ipc/cross_msg.c b/ap/os/linux/linux-3.4.x/ipc/cross_msg.c
new file mode 100755
index 0000000..c5491bc
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/ipc/cross_msg.c
@@ -0,0 +1,142 @@
+/*
+ * linux/ipc/cross_msg.c
+ * Copyright (C) 2023 Sanechips Technology Co., Ltd.
+ */
+#include <linux/kthread.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+
+#include "cross_msg.h"
+
+extern int msg_chn_ready;
+extern struct mutex cross_msg_mutex;
+
+extern int sys_msgget(key_t key, int msgflg);
+extern long do_kmsgsnd(int msqid, struct msgbuf* msgp, size_t msgsz, int msgflg);
+
+static void msg_ap_icp_init(void)
+{
+	mutex_init(&cross_msg_mutex);
+
+	if (zDrvRpMsg_CreateChannel_Cap(CROSS_MSG_ACT, CROSS_MSG_CHN, CROSS_CHN_SIZE)) {
+		panic(CROSS_PRINT "Failed create ap->cap msg channel id %d!\n", CROSS_MSG_CHN);
+	} else {
+		printk(KERN_INFO CROSS_PRINT "create ap->cap msg channel success!\n");
+		msg_chn_ready = 1;
+	}
+	
+	if (zDrvRpMsg_CreateChannel_Cap(CROSS_MSG_ACT, CROSS_MSG_CHN_CAP, CROSS_CHN_SIZE)) {
+		panic(CROSS_PRINT "Failed create cap->ap msg channel id %d\n", CROSS_MSG_CHN_CAP);
+	} else {
+		printk(KERN_INFO CROSS_PRINT "create cap->ap msg channel success!\n");
+	}
+}
+
+void cross_msg_recv()
+{
+	T_sc_msg_header *msgheader = NULL;
+	long *typeheader = NULL;
+	char *textheader = NULL;
+	T_ZDrvRpMsg_Msg Icp_Msg;
+	int ret;
+	int msqid, alen;
+	
+	msgheader = (T_sc_msg_header *)kmalloc(CROSS_MSG_SIZE, GFP_KERNEL);
+	if (!msgheader) {
+		panic(CROSS_PRINT "Failed malloc send msgheader!\n");
+	}
+
+	while (1)
+	{
+		memset(msgheader, 0, sizeof(T_sc_msg_header));
+		Icp_Msg.actorID	= CROSS_MSG_ACT;
+		Icp_Msg.chID	= CROSS_MSG_CHN_CAP;
+		Icp_Msg.buf		= msgheader; 
+		Icp_Msg.len		= CROSS_MSG_SIZE;
+		Icp_Msg.flag	= 0;
+		ret = zDrvRpMsg_Read_Cap(&Icp_Msg);
+#if CROSS_DEBUG 
+		printk(KERN_INFO CROSS_PRINT "cross message rpmsg recv header %x ops %x\n", msgheader->head, msgheader->ops);
+#endif
+		if(ret < 0) {
+			printk(KERN_ERR CROSS_PRINT "read rmpsg from cap error:(%d)\n", ret);
+			continue;
+		}
+		if (msgheader->head != CROSS_MSG_HEAD)
+		{
+			printk(KERN_ERR CROSS_PRINT "read rmpsg content error\n");
+			continue;
+		}
+		switch (msgheader->ops) {
+			case MSGGET_F: {
+				break;
+			}
+			case MSGCTL_F: {
+				break;
+			}
+			case MSGSND_F: {
+				typeheader = (long *)(msgheader + 1);
+				textheader = (char *)(typeheader + 1);
+#if CROSS_DEBUG 
+				printk(KERN_INFO CROSS_PRINT "cross message msgget key:(%d) flag:(%d)\n", msgheader->sndp.getp.key, msgheader->sndp.getp.msgflg);
+#endif
+				msqid = sys_msgget(msgheader->sndp.getp.key, msgheader->sndp.getp.msgflg);
+				if (msqid < 0) {
+					printk(KERN_ERR CROSS_PRINT "msgget error:(%d)\n", msqid);
+					ret = msqid;
+					goto ack;
+				}
+#if CROSS_DEBUG 
+				printk(KERN_INFO CROSS_PRINT "cross message msgsnd text:(%s) msgtyp:(%d)\n", textheader, *typeheader);
+				printk(KERN_INFO CROSS_PRINT "cross message msgsnd msgflg: %x, msgsz:(%d)\n", msgheader->sndp.msgflg, msgheader->sndp.msgsz);
+#endif
+				ret = do_kmsgsnd(msqid, typeheader, msgheader->sndp.msgsz, msgheader->sndp.msgflg);
+				if (ret < 0) {
+					printk(KERN_ERR CROSS_PRINT "msgsnd error:(%d)\n", ret);
+					goto ack;
+				}
+#if CROSS_DEBUG 
+				printk(KERN_INFO CROSS_PRINT "cross message msgsnd ret:(%d)\n", ret);
+#endif
+ack:		 
+				msgheader->head	= CROSS_MSG_HEAD;
+				msgheader->ret	= ret;
+				Icp_Msg.actorID	= CROSS_MSG_ACT;
+				Icp_Msg.chID	= CROSS_MSG_CHN_CAP;
+				Icp_Msg.flag	= RPMSG_WRITE_INT;
+				Icp_Msg.buf		= msgheader;
+				Icp_Msg.len		= sizeof(T_sc_msg_header);
+				ret = zDrvRpMsg_Write_Cap(&Icp_Msg);
+				if (ret < 0)
+					printk(KERN_INFO CROSS_PRINT "write rpmsg to cap error:(%d)\n", ret);
+				break;
+			}
+			case MSGRCV_F: {
+				break;
+			}
+			default: {
+				printk(KERN_INFO CROSS_PRINT "cross message msg options unknow:(%d)\n", ret);
+				break;
+			}
+		}
+	}
+	
+}
+
+void __init cross_msg_init(void)
+{
+	struct task_struct *recv_msg_thread; 
+	msg_ap_icp_init();
+	
+	printk(KERN_INFO CROSS_PRINT "cross message init");
+	recv_msg_thread = kthread_run(cross_msg_recv, NULL, "cross_msg_recv");
+	if (IS_ERR(recv_msg_thread)) {
+		panic("create recv_msg_thread err");
+	}
+	else {
+		wake_up_process(recv_msg_thread);	  
+	}
+}
+late_initcall(cross_msg_init);
+