[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);
+