zte's code,first commit
Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Kconfig b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Kconfig
new file mode 100755
index 0000000..4f9faa4
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Kconfig
@@ -0,0 +1,10 @@
+
+config ZCAT_DEVICE
+ tristate "zCat device should be used by printk and printf to transport uart logs"
+ default n
+ help
+ This option enables zCat device, which should be used by printk and printf
+ to transport uart logs. Normally, logs are transported by uart and displayed
+ in terminal. But some systems don't have uart port, then we add zCat device
+ to transport uart logs
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Makefile b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Makefile
new file mode 100755
index 0000000..847838a
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Makefile
@@ -0,0 +1,13 @@
+#
+# Diag device proxy drivers.
+#
+
+obj-y += zcat_device.o
+ifndef CONFIG_SYSTEM_RECOVERY
+obj-y += ringbuf.o
+obj-y += logcat_drv_printf.o
+
+ifndef CONFIG_SYSTEM_CAP
+obj-y += logcat_drv_cp.o
+endif
+endif
\ No newline at end of file
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv.h b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv.h
new file mode 100644
index 0000000..96efebe
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv.h
@@ -0,0 +1,113 @@
+/**
+ *
+ * @file logcat_drv.h
+ * @brief
+ * This file is part of ZCAT.
+ * zcat´¦ÀílogµÄÐéÄâÉ豸¹«¹²Í·Îļþ
+ *
+ * @details
+ * @author Tools Team.
+ * @email
+ * @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
+ * @warning
+ * @date 2019/02/02
+ * @version 1.1
+ * @pre
+ * @post
+ *
+ * @par
+ * Change History :
+ * ---------------------------------------------------------------------------
+ * date version author description
+ * ---------------------------------------------------------------------------
+ * 2017/07/17 1.0 hou.bing Create file
+ * 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
+ * ---------------------------------------------------------------------------
+ *
+ *
+ */
+
+/* AP LOG BEGIN */
+#ifndef _LOGCAT_DRV_H
+#define _LOGCAT_DRV_H
+
+/* AP LOG module name */
+#define MODULE_NUMBER 24
+#define MODULE_NUMBER_MAX 255
+
+#define MODULE_PRINTF 1 // ԭprintf
+#define MODULE_PRINTK 2 // ԭprintk
+#define MODULE_CALL 3 // ͨ»°
+#define MODULE_MESSAGE 4 // ¶ÌÏûÏ¢
+#define MODULE_DATA 5 // Êý¾ÝÒµÎñ
+#define MODULE_SETTING 6 // ÉèÖù¦ÄÜ
+#define MODULE_DISPLAY 7 // ÏÔʾ¹¦ÄÜ
+#define MODULE_INTERNET 8 // ÉÏÍø¹¦ÄÜ
+#define MODULE_INSTALL 9 // °²×°¹¦ÄÜ
+#define MODULE_FOTA 10 // Éý¼¶¹¦ÄÜ
+#define MODULE_DIAGNOSIS 11 // Õï¶Ï¹¦ÄÜ
+#define MODULE_SYSTEM_LOG 12 // ϵͳÈÕÖ¾
+#define MODULE_T_CARD 13 // T¿¨ÒµÎñ
+#define MODULE_DRIVERS 14 // Çý¶¯¹¦ÄÜ
+#define MODULE_PROTOCOL 15 // ÍøÂçÐÒé
+#define MODULE_DM 16 // É豸¹ÜÀí
+#define MODULE_WIFI 17 // WIFIÎÞÏß¿í´ø
+#define MODULE_APN 18 // APNÍøÂç½ÓÈë
+#define MODULE_POWER 19 // ¹¦ºÄÊ¡µç
+#define MODULE_WEB_UI 20 // WEBÓû§½çÃæ
+#define MODULE_PC_UI 21 // PCÓû§½çÃæ
+#define MODULE_PC_TOOLS 22 // PC¹¤¾ß
+#define MODULE_AP_LOG 23 // AP LOG¹¦ÄÜ
+#define MODULE_OTHERS 24 // ÆäËü¹¦ÄÜ
+
+/* AP LOG module level */
+#define MODULE_LEVEL_EMERG 0 // ½ô¼±Ê¼þÏûÏ¢£¬ÏµÍ³±ÀÀ£Ö®Ç°Ìáʾ£¬±íʾϵͳ²»¿ÉÓÃ
+#define MODULE_LEVEL_ALERT 1 // ±¨¸æÏûÏ¢£¬±íʾ±ØÐëÁ¢¼´²ÉÈ¡´ëÊ©
+#define MODULE_LEVEL_CRIT 2 // ÁÙ½çÌõ¼þ£¬Í¨³£Éæ¼°ÑÏÖØµÄÓ²¼þ»òÈí¼þ²Ù×÷ʧ°Ü
+#define MODULE_LEVEL_ERR 3 // ´íÎóÌõ¼þ£¬Çý¶¯³ÌÐò³£ÓÃKERN_ERRÀ´±¨¸æÓ²¼þµÄ´íÎó
+#define MODULE_LEVEL_WARNING 4 // ¾¯¸æÌõ¼þ£¬¶Ô¿ÉÄܳöÏÖÎÊÌâµÄÇé¿ö½øÐо¯¸æ
+#define MODULE_LEVEL_NOTICE 5 // Õý³£µ«ÓÖÖØÒªµÄÌõ¼þ£¬ÓÃÓÚÌáÐÑ
+#define MODULE_LEVEL_INFO 6 // ÌáʾÐÅÏ¢£¬ÈçÇý¶¯³ÌÐòÆô¶¯Ê±£¬´òÓ¡Ó²¼þÐÅÏ¢
+#define MODULE_LEVEL_DEBUG 7 // µ÷ÊÔ¼¶±ðµÄÏûÏ¢
+/* AP LOG END */
+
+#define LEVEL_EMERG 1 // ½ô¼±Ê¼þÏûÏ¢£¬ÏµÍ³±ÀÀ£Ö®Ç°Ìáʾ£¬±íʾϵͳ²»¿ÉÓÃ
+#define LEVEL_ALERT 2 // ±¨¸æÏûÏ¢£¬±íʾ±ØÐëÁ¢¼´²ÉÈ¡´ëÊ©
+#define LEVEL_CRIT 4 // ÁÙ½çÌõ¼þ£¬Í¨³£Éæ¼°ÑÏÖØµÄÓ²¼þ»òÈí¼þ²Ù×÷ʧ°Ü
+#define LEVEL_ERR 8 // ´íÎóÌõ¼þ£¬Çý¶¯³ÌÐò³£ÓÃKERN_ERRÀ´±¨¸æÓ²¼þµÄ´íÎó
+#define LEVEL_WARNING 16 // ¾¯¸æÌõ¼þ£¬¶Ô¿ÉÄܳöÏÖÎÊÌâµÄÇé¿ö½øÐо¯¸æ
+#define LEVEL_NOTICE 32 // Õý³£µ«ÓÖÖØÒªµÄÌõ¼þ£¬ÓÃÓÚÌáÐÑ
+#define LEVEL_INFO 64 // ÌáʾÐÅÏ¢£¬ÈçÇý¶¯³ÌÐòÆô¶¯Ê±£¬´òÓ¡Ó²¼þÐÅÏ¢
+#define LEVEL_DEBUG 128 // µ÷ÊÔ¼¶±ðµÄÏûÏ¢
+#define LEVEL_ALL 255 // ËùÓм¶±ð£¬Ä¬ÈÏÊÇ´òÓ¡ËùÓм¶±ð
+
+
+typedef unsigned long UINT32;
+typedef unsigned char UINT8;
+
+#define BOOL int
+#define VOID void
+
+
+typedef enum
+{
+ ZCAT_IPC_SYN = 0xA0,
+ ZCAT_IPC_ACK,
+ ZCAT_IPC_ESTABLISHED,
+ ZCAT_IPC_SET_TTY,
+ ZCAT_IPC_SET_PERIPHERAL_MODE,
+ ZCAT_IPC_STOP,
+ ZCAT_IPC_START,
+ ZCAT_IPC_EXIT
+} E_ZCAT_IPC_HANDSHAKE;
+
+/* zcatÈ«¾ÖÐÅÏ¢ */
+typedef struct
+{
+ int status;
+ int peripheral_mode;
+ char usblog_path[8];
+} T_ZCAT_CONFIG_INFO;
+
+
+#endif /* !_LOGCAT_DRV_H */
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_cp.c b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_cp.c
new file mode 100644
index 0000000..500f99e
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_cp.c
@@ -0,0 +1,245 @@
+/**
+ *
+ * @file cp_log_drv.c
+ * @brief
+ * This file is part of ZCAT.
+ * zcat´¦Àícp²àlogµÄÐéÄâÉ豸
+ *
+ * @details
+ * @author Tools Team.
+ * @email
+ * @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
+ * @warning
+ * @date 2019/02/18
+ * @version 1.2
+ * @pre
+ * @post
+ *
+ * @par
+ * Change History :
+ * ---------------------------------------------------------------------------
+ * date version author description
+ * ---------------------------------------------------------------------------
+ * 2017/07/17 1.0 hou.bing Create file
+ * 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
+ * 2019/02/18 1.2 jiang.fenglin ¶¯Ì¬¿ÉÅäÖÃLOG¶Ë¿Ú,log¶Ë¿Ú¶¯Ì¬ÅäÖÃÖ»Õë¶ÔusbÅäÖÃΪÕý³£Ä£Ê½µÄÇé¿ö£¬¹¤³§Ä£Ê½±£³Ö²»±ä
+ * ---------------------------------------------------------------------------
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/serial_reg.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+#include "logcat_drv.h"
+#include "ringbuf.h"
+
+
+T_ZCAT_CONFIG_INFO gZcatConfig = {
+ .peripheral_mode = 0xC5, // ZCAT_MODE_CP_USB
+ .status = 0,
+ .usblog_path = "ttyGS2",
+};
+EXPORT_SYMBOL(gZcatConfig);
+
+T_RINGBUFFER *g_AP_ApToCpBuffer = NULL;
+EXPORT_SYMBOL(g_AP_ApToCpBuffer);
+
+T_RINGBUFFER *g_AP_CpToApBuffer = NULL;
+EXPORT_SYMBOL(g_AP_CpToApBuffer);
+
+
+extern size_t Comm_Read_CP_TO_AP_Data(const char __user *buf, size_t len);
+extern size_t Comm_Write_AP_TO_CP_Data(const char __user *buf, size_t len);
+
+static int cplog_open(struct inode *ip, struct file *fp);
+static int cplog_release(struct inode *ip, struct file *fp);
+static ssize_t cplog_read(struct file *fp, char __user *buf,size_t count, loff_t *pos);
+static ssize_t cplog_write(struct file *fp, const char __user *buf,size_t count, loff_t *pos);
+static long cplog_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
+
+
+static const struct file_operations cplog_fops = {
+ .owner = THIS_MODULE,
+ .read = cplog_read,
+ .write = cplog_write,
+ .open = cplog_open,
+ .release = cplog_release,
+ .unlocked_ioctl = cplog_ioctl,
+};
+static struct miscdevice cplog_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "cplog",
+ .fops = &cplog_fops,
+};
+
+static ssize_t cplog_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
+{
+ size_t cpbufLen = 0;
+
+ //printk("cplog_read\n");
+ if(buf && count)
+ {
+ //char *cpbuf = kzalloc(count*sizeof(UINT8), GFP_KERNEL);
+ //if(cpbuf)
+ //{
+#ifndef CONFIG_SYSTEM_RECOVERY
+ cpbufLen = CPPS_FUNC(cpps_callbacks, Comm_Read_CP_TO_AP_Data)(buf,count);
+#endif
+ // copy_to_user(buf, cpbuf, cpbufLen);
+ // kfree(cpbuf);
+ //}
+
+ //printk("cplog_read %d\n", cpbufLen);
+ }
+ return cpbufLen;
+}
+
+static ssize_t cplog_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos)
+{
+ size_t cpbufLen = 0;
+
+ //printk("cplog_write\n");
+ if (buf && count)
+ {
+ //char *cpbuf = kzalloc(count*sizeof(UINT8), GFP_KERNEL);
+ //if(cpbuf)
+ //{
+ // copy_from_user(cpbuf, buf, count);
+
+#ifndef CONFIG_SYSTEM_RECOVERY
+ cpbufLen = CPPS_FUNC(cpps_callbacks, Comm_Write_AP_TO_CP_Data)(buf, count);
+#endif
+ // kfree(cpbuf);
+ //}
+
+ //printk("cplog_write %d\n", cpbufLen);
+ }
+ return cpbufLen;
+
+}
+
+static int cplog_open(struct inode *ip, struct file *fp)
+{
+ printk("cplog open.\n");
+ return 0;
+}
+
+static int cplog_release(struct inode *ip, struct file *fp)
+{
+ printk("cplog release.\n");
+ return 0;
+}
+
+static long cplog_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+ //printk("[tool] %s, cmd = %d., tty = %s\n", __func__, cmd, gZcatConfig.usblog_path);
+ switch(cmd)
+ {
+ case ZCAT_IPC_SET_PERIPHERAL_MODE:
+ {
+ if(arg >= 0xC1 && arg <= 0xC4)
+ {
+ if(g_AP_ApToCpBuffer == NULL)
+ {
+ UINT8 *buf = vmalloc(0x8000);
+ g_AP_ApToCpBuffer = CreateRingBufferWithSymbol(buf, 0x8000, ZCAT_IPC_ESTABLISHED);
+ if(!g_AP_ApToCpBuffer)
+ {
+ printk("[tool] %s, create buffer failed.\n", __func__);
+ break;
+ }
+ }
+
+ if(g_AP_CpToApBuffer == NULL)
+ {
+ UINT8 *buf = vmalloc(0x20000);
+ g_AP_CpToApBuffer = CreateRingBufferWithSymbol(buf, 0x20000, ZCAT_IPC_ESTABLISHED);
+ if(!g_AP_CpToApBuffer)
+ {
+ printk("[tool] %s, create buffer failed.\n", __func__);
+ break;
+ }
+ }
+
+ printk("[tool] %s, create buffer success.\n", __func__);
+ }
+
+ gZcatConfig.peripheral_mode = arg;
+
+ break;
+ }
+ case ZCAT_IPC_SET_TTY:
+ {
+ if(copy_from_user(gZcatConfig.usblog_path , (void __user *)arg, sizeof(gZcatConfig.usblog_path)))
+ return -1;
+ break;
+ }
+ case ZCAT_IPC_SYN:
+ {
+ gZcatConfig.status = 1;
+ break;
+ }
+ case ZCAT_IPC_ACK:
+ {
+ if(gZcatConfig.status != 2)
+ return -1;
+ break;
+ }
+ case ZCAT_IPC_ESTABLISHED:
+ {
+ if(gZcatConfig.status == 2)
+ gZcatConfig.status = 3;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int __init cplog_init(void)
+{
+ int ret = misc_register(&cplog_device);
+ printk("cplog_init.\n");
+ if (ret)
+ {
+ printk(KERN_ERR "cplog driver init failed.\n");
+ }
+
+ return ret;
+}
+
+static void __exit cplog_exit(void)
+{
+ printk("cplog_exit.\n");
+ misc_deregister(&cplog_device);
+}
+
+module_init(cplog_init);
+module_exit(cplog_exit);
+
+MODULE_AUTHOR("jinkai");
+MODULE_DESCRIPTION("zCat cplog driver");
+MODULE_LICENSE("GPL");
+
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_printf.c b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_printf.c
new file mode 100755
index 0000000..6cdf45b
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_printf.c
@@ -0,0 +1,357 @@
+/**
+ *
+ * @file logcat_drv_printf.c
+ * @brief
+ * This file is part of ZCAT.
+ * zcat´¦ÀíprintfµÄÐéÄâÉ豸
+ *
+ * @details
+ * @author Tools Team.
+ * @email
+ * @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
+ * @warning
+ * @date 2019/02/02
+ * @version 1.2
+ * @pre
+ * @post
+ *
+ * @par
+ * Change History :
+ * ---------------------------------------------------------------------------
+ * date version author description
+ * ---------------------------------------------------------------------------
+ * 2017/07/17 1.0 hou.bing Create file
+ * 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
+ * 2019/02/22 1.2 jiang.fenglin ¹Ø±Õzcat_device.cÎļþ,»Ö¸´logcat_drv_printf.c
+ * ---------------------------------------------------------------------------
+ *
+ *
+ */
+
+
+/**
+ * Í·Îļþ
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/serial_reg.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include "linux/memory.h"
+#include <linux/vmalloc.h>
+#include <linux/kthread.h>
+
+#include "logcat_drv.h"
+#include "ringbuf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Íⲿº¯ÊýÒýÓÃ
+ */
+#ifndef CONFIG_SYSTEM_RECOVERY
+#ifndef CONFIG_SYSTEM_CAP
+extern ssize_t zCatAgt_App_Write(const char __user *buf, size_t count);
+#endif
+#endif
+
+/**
+ * ºê¶¨Òå
+ */
+
+/**
+ * Êý¾ÝÀàÐͶ¨Òå
+ */
+typedef struct
+{
+ unsigned short type;
+ UINT8 operation;
+ UINT8 reserved;
+}T_ZCAT_DIAG_CONFIG_REQ;
+
+typedef enum
+{
+ DISABLE_LOGGING = 0,
+ ENABLE_LOGGING,
+ GET_MASK,
+ SET_MASK,
+ DIAG_LAST_OPERATION
+
+}T_ZCAT_DIAG_CONFIG_OPERATION_TYPE;
+
+T_RINGBUFFER *g_AP2_KernelToCpBuffer = NULL;
+EXPORT_SYMBOL(g_AP2_KernelToCpBuffer);
+
+T_RINGBUFFER *g_AP2_AppToCpBuffer = NULL;
+EXPORT_SYMBOL(g_AP2_AppToCpBuffer);
+
+volatile T_RINGBUFFER *g_zCat_app_mem = NULL;
+EXPORT_SYMBOL(g_zCat_app_mem);
+
+struct mutex g_zCat_app_mutex;
+EXPORT_SYMBOL(g_zCat_app_mutex);
+
+volatile int g_zcat_kernel_fst = 0;
+EXPORT_SYMBOL(g_zcat_kernel_fst);
+
+
+/**
+ * ¾Ö²¿º¯ÊýÉùÃ÷
+ */
+static int logcatf_open(struct inode *ip, struct file *fp);
+static int logcatf_release(struct inode *ip, struct file *fp);
+static ssize_t logcatf_read(struct file *fp, char __user *buf, size_t count, loff_t *pos);
+static ssize_t logcatf_write(struct file *fp, const char __user *buf,size_t count, loff_t *pos);
+static long logcatf_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
+
+/**
+ * È«¾Ö±äÁ¿ÉùÃ÷
+ */
+static const struct file_operations logcatf_fops = {
+ .owner = THIS_MODULE,
+ .read = logcatf_read,
+ .write = logcatf_write,
+ .open = logcatf_open,
+ .unlocked_ioctl = logcatf_ioctl,
+ .release = logcatf_release,
+};
+
+static struct miscdevice logcatf_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "logcat_printf",
+ .fops = &logcatf_fops,
+};
+
+static int enable_applog = 1;
+
+/**
+ * º¯ÊýʵÏÖ
+ */
+
+#ifdef CONFIG_SYSTEM_CAP
+
+static struct mutex printf_mutex;
+
+/**
+ * @brief AP App LOGдÈëµ½"Master´¦ÀíÆ÷"»º³åÇø
+ * @param[in] buf Óû§Ì¬»º´æÊý¾ÝÖ¸Õë
+ * @param[in] count »º´æÊý¾Ý³¤¶È
+ * @return ʵ¼ÊдÈëµÄ³¤¶È
+ * @note
+ * @see
+ */
+ssize_t zCatAgt_App_Write(const char __user *buf, size_t count)
+{
+ ssize_t cnt = -1;
+
+ if (buf && count && g_AP2_AppToCpBuffer)
+ {
+ mutex_lock(&printf_mutex);
+ cnt = WriteRingBuffer(g_AP2_AppToCpBuffer, buf, count, ZCAT_MEM_TYPE_USER);
+ mutex_unlock(&printf_mutex);
+ }
+
+ return cnt;
+}
+
+/**
+ * @brief AP Kernel LOGдÈëµ½"Master´¦ÀíÆ÷"»º³åÇø
+ * @param[in] buf ÄÚºË̬»º´æÊý¾ÝÖ¸Õë
+ * @param[in] count »º´æÊý¾Ý³¤¶È
+ * @return ʵ¼ÊдÈëµÄ³¤¶È
+ * @note
+ * @see
+ */
+ssize_t zCatAgt_Kernel_Write(const char *buf, size_t count)
+{
+ ssize_t cnt = 0;
+
+ if (buf && count && g_AP2_KernelToCpBuffer)
+ {
+ cnt = WriteRingBuffer(g_AP2_KernelToCpBuffer, buf, count, ZCAT_MEM_TYPE_KERNEL);
+ }
+ return cnt;
+}
+EXPORT_SYMBOL(zCatAgt_Kernel_Write);
+#endif
+
+static ssize_t logcatf_read(struct file *fp, char __user *buf,size_t count, loff_t *pos)
+{
+ #if 0
+ UINT8 *appbuf = NULL;
+ UINT32 appbufLen = 0;
+ int ret = -1;
+
+ if(buf ==NULL)
+ return -1;
+ /*
+ appbuf = kzalloc(count*sizeof(UINT8),GFP_KERNEL);
+ if(appbuf == NULL)
+ return -1;*/
+ ret = wait_for_completion_interruptible(&_app_dev.write_done);
+ if(ret < 0)
+ {
+ //kfree(appbuf);
+ return ret;
+ }
+ appbufLen = ReadRingBuffer_AP(APP_BUFF, buf, count);
+ //copy_to_user(buf, appbuf, appbufLen);
+ //kfree(appbuf);
+ return appbufLen;
+ #endif
+ return 0;
+}
+
+static ssize_t logcatf_write(struct file *fp, const char __user *buf,size_t count, loff_t *pos)
+{
+ ssize_t ret = -1;
+ if(enable_applog == 1)
+ {
+#ifndef CONFIG_SYSTEM_RECOVERY
+ #ifdef USE_CPPS_KO
+ if (cpps_callbacks.zCatAgt_App_Write)
+ ret = cpps_callbacks.zCatAgt_App_Write(buf, count);
+ else
+ {
+ #ifdef _USE_MBIM
+ if (g_zCat_app_mem)
+ {
+ mutex_lock_killable(&g_zCat_app_mutex);
+ WriteRingBuffer(g_zCat_app_mem, buf, count, ZCAT_MEM_TYPE_USER);
+ mutex_unlock(&g_zCat_app_mutex);
+ }
+ #endif
+ }
+ #else
+ ret = zCatAgt_App_Write(buf, count);
+ #endif
+#endif
+ }
+ return ret;
+}
+
+static int logcatf_open(struct inode *ip, struct file *fp)
+{
+ //ÓÉÓÚprintfÔÚ²»Í¬µÄÓ¦ÓÃÖдò¿ª£¬»áƵ·±µÄµ÷ÓÃopen/close
+ //printk("logcat_printf open.\n");
+ return 0;
+}
+
+static long logcatf_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+ #if 0
+ T_ZCAT_DIAG_CONFIG_REQ aprule = {0};
+ int copy_ret = -1;
+ void __user* ubuf = (void __user*)arg;
+
+ // printfʹÓÃfopen·½Ê½´ò¿ªµÄlogcat_printf£¬»áµ÷ÓÃfcntl£¬ioctl£¬ËùÒÔÕâÀïµÄ²ÎÊýÐèÒªÖØÐÂÉè¼Æ
+ printk("logcat_printf ioctl,enable=%d.\n", enable_applog);
+
+ copy_ret = copy_from_user(&aprule, ubuf, sizeof(T_ZCAT_DIAG_CONFIG_REQ));
+
+ if(aprule.operation == DISABLE_LOGGING)
+ enable_applog = 0;
+ else if(aprule.operation == ENABLE_LOGGING)
+ enable_applog = 1;
+ #endif
+ return 0;
+}
+
+static int logcatf_release(struct inode *ip, struct file *fp)
+{
+ //printk("logcat_printf release.\n");
+ return 0;
+}
+
+/**
+ * @brief zcatץȡprintfµÄÐéÄâÉ豸³õʼ»¯º¯Êý
+ * @param[in] N/A
+ * @return ±ê×¼´íÎóÂë
+ * @note
+ * @see
+ */
+static int __init logcatf_init(void)
+{
+#ifdef _USE_MBIM
+ void *mem;
+#endif
+
+ int ret = misc_register(&logcatf_device);
+ printk("logcat_printf init.\n");
+ if (ret){
+ printk(KERN_ERR "logcat_printf driver init failed.\n");
+ }
+
+#ifdef _USE_MBIM
+ mem = vmalloc(0x10000);
+ if (!mem) {
+ panic("logcat_printf driver init failed.\n");
+ }
+ g_zCat_app_mem = CreateRingBuffer((UINT8 *)mem, 0x10000);
+ mutex_init(&g_zCat_app_mutex);
+ g_zcat_kernel_fst = 1;
+#else
+ g_zCat_app_mem = NULL;
+ mutex_init(&g_zCat_app_mutex);
+ g_zcat_kernel_fst = 0;
+#endif
+
+#ifdef _USE_CAP_SYS
+
+ // ÔÚap2ºËÉÏ´´½¨/дÈë(ap²à)£¬ÔÚap1ÉÏÒýÓÃ/¶ÁÈ¡(ps²à)
+#ifdef CONFIG_SYSTEM_CAP
+ mutex_init(&printf_mutex);
+ g_AP2_KernelToCpBuffer = CreateRingBuffer((UINT8 *)(ZX_DDR_CAPBUF_BASE + ICP_CAP_BUF_LEN), 0x4000);
+ g_AP2_AppToCpBuffer = CreateRingBuffer((UINT8 *)(ZX_DDR_CAPBUF_BASE + ICP_CAP_BUF_LEN + 0x4000), 0x4000);
+#else
+ g_AP2_KernelToCpBuffer = (T_RINGBUFFER *)(ZX_DDR_CAPBUF_BASE + ICP_CAP_BUF_LEN);
+ g_AP2_AppToCpBuffer = (T_RINGBUFFER *)(ZX_DDR_CAPBUF_BASE + ICP_CAP_BUF_LEN + 0x4000);
+#endif
+
+#endif
+
+ return ret;
+}
+
+
+/**
+ * @brief zcatץȡprintfµÄÐéÄâÉ豸Í˳öº¯Êý
+ * @param[in] N/A
+ * @return N/A
+ * @note
+ * @see
+ */
+static void __exit logcatf_exit(void)
+{
+ misc_deregister(&logcatf_device);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+module_init(logcatf_init);
+module_exit(logcatf_exit);
+
+MODULE_AUTHOR("jinkai");
+MODULE_DESCRIPTION("zCat logcat_printf driver");
+MODULE_LICENSE("GPL");
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_printk.c b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_printk.c
new file mode 100755
index 0000000..01b1fce
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/logcat_drv_printk.c
@@ -0,0 +1,467 @@
+/**
+ *
+ * @file logcat_drv_printk.c
+ * @brief
+ * This file is part of ZCAT.
+ * zcat´¦ÀíprintkµÄÐéÄâÉ豸
+ *
+ * @details
+ * @author Tools Team.
+ * @email
+ * @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
+ * @warning
+ * @date 2019/02/02
+ * @version 1.1
+ * @pre
+ * @post
+ *
+ * @par
+ * Change History :
+ * ---------------------------------------------------------------------------
+ * date version author description
+ * ---------------------------------------------------------------------------
+ * 2017/07/17 1.0 hou.bing Create file
+ * 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
+ * ---------------------------------------------------------------------------
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/ioport.h>
+#include <linux/serial_reg.h>
+#include <linux/poll.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <asm/io.h>
+#include "logcat_drv.h"
+
+
+#define TOOL_AGENT_BASE_ADDR (0x22400000)
+
+//AP KERNEL buff
+#define ZCAT_KERNEL_TO_CP_BASE_ADDR (0x22900000)
+#define ZCAT_KERNEL_TO_CP_SIZE (0x4000)
+
+#define ZCAT_CP_TO_KERNEL_BASE_ADDR (TOOL_AGENT_BASE_ADDR+0x50C000)
+#define ZCAT_CP_TO_KERNEL_SIZE (0x4000)
+
+//AP APP buff
+#define ZCAT_APP_TO_CP_BASE_ADDR (0x22910000)
+#define ZCAT_APP_TO_CP_SIZE (0x4000)
+
+#define ZCAT_CP_TO_APP_BASE_ADDR (TOOL_AGENT_BASE_ADDR+0x51C000)
+#define ZCAT_CP_TO_APP_SIZE (0x4000)
+
+
+
+#define SYMBOL_VALUE ZCAT_IPC_ESTABLISHED
+
+
+UINT8 LEVER_FOR_PRINTK[MODULE_NUMBER_MAX] = {0};
+EXPORT_SYMBOL(LEVER_FOR_PRINTK);
+
+UINT8 LEVER_FOR_PRINTF[MODULE_NUMBER_MAX] = {0};
+EXPORT_SYMBOL(LEVER_FOR_PRINTF);
+
+static const char logcatk_shortname[] = "logcat_printk";
+
+T_RINGBUFFER* KERNEL_BUFF=NULL;
+EXPORT_SYMBOL(KERNEL_BUFF);
+
+T_RINGBUFFER* APP_BUFF=NULL;
+EXPORT_SYMBOL(APP_BUFF);
+
+T_RINGBUFFER* CP_TO_KERNEL_BUFF = NULL;
+T_RINGBUFFER* CP_TO_APP_BUFF = NULL;
+
+char P_KERNEL[1024*16];
+char P_APP[1024*16];
+
+struct kernel_dev {
+ wait_queue_head_t read_wq;
+ struct completion write_done;
+};
+
+static wait_queue_head_t kernelqueue;
+static struct kernel_dev _kernel_dev;
+static int enable_kernellog = 1;
+//EXPORT_SYMBOL(enable_kernellog);
+
+typedef struct
+{
+ unsigned short type;
+ UINT8 operation;
+ UINT8 reserved;
+}T_ZCAT_DIAG_CONFIG_REQ;
+
+typedef enum
+{
+ DISABLE_LOGGING = 0,
+ ENABLE_LOGGING,
+ GET_MASK,
+ SET_MASK,
+ DIAG_LAST_OPERATION
+
+}T_ZCAT_DIAG_CONFIG_OPERATION_TYPE;
+
+typedef struct
+{
+ char* data;
+ int data_len;
+}T_IOCTL_PARA;
+
+extern UINT32 WriteRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len);
+extern T_RINGBUFFER *CreateRingBuffer(UINT8 *buf, UINT32 bufSize);
+extern BOOL IsRingBufferValid(T_RINGBUFFER *ringBuf);
+
+static int logcatk_open(struct inode *ip, struct file *fp);
+static int logcatk_release(struct inode *ip, struct file *fp);
+static ssize_t logcatk_read(struct file *fp, char __user *buf,size_t count, loff_t *pos);
+static ssize_t logcatk_write(struct file *fp, const char __user *buf,size_t count, loff_t *pos);
+static long logcatk_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
+
+
+static const struct file_operations logcatk_fops = {
+ .owner = THIS_MODULE,
+ .read = logcatk_read,
+ .write = logcatk_write,
+ .open = logcatk_open,
+ .unlocked_ioctl = logcatk_ioctl,
+ .release = logcatk_release,
+};
+
+static struct miscdevice logcatk_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = logcatk_shortname,
+ .fops = &logcatk_fops,
+};
+
+void sleep_milli_sec(nmillisec)
+{
+ do{
+ long timeout = (nmillisec)*HZ/1000;
+ while(timeout>0)
+ {
+ timeout = schedule_timeout(timeout);
+ }
+ }while(0);
+}
+EXPORT_SYMBOL(sleep_milli_sec);
+#ifdef CONFIG_SYSTEM_RECOVERY
+/**************************************************************************
+* º¯ÊýÃû³Æ: IsRingBufferIsValid
+* ¹¦ÄÜÃèÊö: Åжϻº³åÇøÊÇ·ñÓÐЧ
+* ²ÎÊý˵Ã÷: (IN)
+ ringBuf:»·Ðλº³å
+* ·µ »Ø Öµ:
+* ÆäËü˵Ã÷: ÊÇ·µ»ØTRUE,·ñ·µ»ØFALSE
+**************************************************************************/
+BOOL IsRingBufferValid(T_RINGBUFFER *ringBuf)
+{
+ return (ringBuf != NULL && ringBuf->symbol == SYMBOL_VALUE);
+}
+
+/**************************************************************************
+* º¯ÊýÃû³Æ: CreateRingBuffer
+* ¹¦ÄÜÃèÊö: ´´½¨ÐèÒªµÄ»º³åÇø
+* ²ÎÊý˵Ã÷: (IN)
+ buf:»º³åÇøµØÖ·
+ bufSize: »º³åÇø´óС
+* ·µ »Ø Öµ: ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
+* ÆäËü˵Ã÷: Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
+**************************************************************************/
+T_RINGBUFFER *CreateRingBuffer(UINT8 *buf, UINT32 bufSize)
+{
+ T_RINGBUFFER *ringBuf = NULL;
+
+ if (bufSize <= sizeof(T_RINGBUFFER))
+ {
+ return NULL;
+ }
+
+ ringBuf = (T_RINGBUFFER *)buf;
+
+
+ ringBuf->capacity = bufSize - sizeof(T_RINGBUFFER);
+ ringBuf->readPoint = 0;
+ ringBuf->writePoint = 0;
+ ringBuf->symbol = SYMBOL_VALUE;
+
+ return ringBuf;
+}
+EXPORT_SYMBOL(CreateRingBuffer);
+
+/**************************************************************************
+* º¯ÊýÃû³Æ: WriteRingBuffer
+* ¹¦ÄÜÃèÊö: ½«Êý¾ÝдÈë»·Ðλº³å
+* ²ÎÊý˵Ã÷: (IN)
+ ringBuf:»·Ðλº³å
+ buf:»º´æÖ¸Õë
+ len:³¤¶È
+* ·µ »Ø Öµ: ·µ»ØÐ´È볤¶È
+* ÆäËü˵Ã÷:
+**************************************************************************/
+UINT32 WriteRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len)
+{
+ UINT32 writeLen = 0;
+ UINT32 writePoint = ringBuf->writePoint;
+ UINT32 readPoint = ringBuf->readPoint;
+
+ /* Èë²ÎÅÐ¶Ï */
+ //pr_info("logcat---WriteRingBuffer\n");
+ if (!IsRingBufferValid(ringBuf) || buf == NULL || len == 0)
+ {
+ return 0;
+ }
+
+ if (writePoint >= readPoint)
+ {
+ if (ringBuf->capacity - writePoint > len)
+ {
+ copy_from_user(ringBuf->buf + writePoint, buf, len);
+ ringBuf->writePoint += len;
+ writeLen = len;
+ }
+ else if ((ringBuf->capacity - writePoint + readPoint - 1) >= len)
+ {
+ UINT32 copyLen = ringBuf->capacity - writePoint;
+ copy_from_user(ringBuf->buf + writePoint, buf, copyLen);
+
+ copyLen = len - copyLen;
+
+ if (copyLen > 0)
+ {
+ copy_from_user(ringBuf->buf, buf + (len - copyLen), copyLen);
+ }
+
+ ringBuf->writePoint = copyLen;
+ writeLen = len;
+ }
+ }
+ else
+ {
+ if (readPoint - writePoint - 1 >= len)
+ {
+ copy_from_user(ringBuf->buf + writePoint, buf, len);
+ ringBuf->writePoint += len;
+ writeLen = len;
+ }
+ }
+
+ return writeLen;
+}
+
+EXPORT_SYMBOL(WriteRingBuffer);
+#endif
+/**************************************************************************
+* º¯ÊýÃû³Æ: CreateRingBuffer
+* ¹¦ÄÜÃèÊö: ´´½¨ÐèÒªµÄ»º³åÇø
+* ²ÎÊý˵Ã÷: (IN)
+ buf:»º³åÇøµØÖ·
+ bufSize: »º³åÇø´óС
+* ·µ »Ø Öµ: ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
+* ÆäËü˵Ã÷: Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
+**************************************************************************/
+T_RINGBUFFER *CreateRingBufferNew(UINT8 *buf, UINT32 bufSize)
+{
+ T_RINGBUFFER *ringBuf = NULL;
+
+ if (bufSize <= sizeof(T_RINGBUFFER))
+ {
+ return NULL;
+ }
+
+ ringBuf = (T_RINGBUFFER *)buf;
+
+
+ ringBuf->capacity = bufSize - sizeof(T_RINGBUFFER);
+ ringBuf->readPoint = 0;
+ ringBuf->writePoint = 0;
+ ringBuf->symbol = 0xA0A0A0A0;
+
+ return ringBuf;
+}
+EXPORT_SYMBOL(CreateRingBufferNew);
+/**************************************************************************
+* º¯ÊýÃû³Æ: ReadRingBuffer
+* ¹¦ÄÜÃèÊö: ¶Áȡһ¶Î»·Ðλº³åÇø
+* ²ÎÊý˵Ã÷: (IN)
+ ringBuf:»·Ðλº³å
+ buf:»º´æÖ¸Õë
+ len:³¤¶È
+* ·µ »Ø Öµ: ·µ»Ø¶ÁÈ¡³¤¶È
+* ÆäËü˵Ã÷:
+**************************************************************************/
+UINT32 ReadRingBuffer_AP(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len)
+{
+ UINT32 readLen = 0;
+ UINT32 writePoint = ringBuf->writePoint;
+ UINT32 readPoint = ringBuf->readPoint;
+
+ /* ²ÎÊý¼ì²é */
+ if (!IsRingBufferValid(ringBuf) || buf == NULL || len == 0)
+ {
+ return 0;
+ }
+
+ if (writePoint > readPoint)
+ {
+ readLen = writePoint - readPoint;
+ readLen = (readLen >= len) ? len : readLen;
+
+ copy_to_user(buf, ringBuf->buf + readPoint, readLen);
+ ringBuf->readPoint += readLen;
+ }
+ else if (writePoint < readPoint)
+ {
+ readLen = ringBuf->capacity - readPoint + writePoint;
+ readLen = (readLen >= len) ? len : readLen;
+
+ if (ringBuf->capacity - readPoint >= readLen)
+ {
+ copy_to_user(buf, ringBuf->buf + readPoint, readLen);
+ ringBuf->readPoint = (ringBuf->readPoint + readLen) % ringBuf->capacity;
+ }
+ else
+ {
+ UINT32 copyLen = ringBuf->capacity - readPoint;
+ copy_to_user(buf, ringBuf->buf + readPoint, copyLen);
+
+ copyLen = readLen - copyLen;
+ copy_to_user(buf + (readLen - copyLen), ringBuf->buf, copyLen);
+
+ ringBuf->readPoint = copyLen;
+ }
+ }
+
+ return readLen;
+}
+EXPORT_SYMBOL(ReadRingBuffer_AP);
+
+static ssize_t logcatk_read(struct file *fp, char __user *buf,size_t count, loff_t *pos)
+{
+ UINT8 *kernelbuf = NULL;
+ UINT32 kernelbufLen = 0;
+ int ret = -1;
+
+ if(buf ==NULL)
+ return -1;
+ /*kernelbuf = kzalloc(count*sizeof(UINT8),GFP_KERNEL);
+ if(kernelbuf == NULL)
+ return -1;*/
+ ret = wait_for_completion_interruptible(&_kernel_dev.write_done);
+ if(ret < 0)
+ {
+ // kfree(kernelbuf);
+ return ret;
+ }
+ kernelbufLen = ReadRingBuffer_AP(KERNEL_BUFF, buf, count);
+ //copy_to_user(buf, kernelbuf, kernelbufLen);
+ //kfree(kernelbuf);
+ return kernelbufLen;
+}
+
+static ssize_t logcatk_write(struct file *fp, const char __user *buf,size_t count, loff_t *pos)
+{
+ return 0;
+}
+
+static int logcatk_open(struct inode *ip, struct file *fp)
+{
+ //fp->private_data =_kernel_dev;
+ return 0;
+}
+
+static long logcatk_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+ T_ZCAT_DIAG_CONFIG_REQ aprule = {0};
+ int copy_ret = -1;
+ void __user* ubuf = (void __user*)arg;
+
+ copy_ret = copy_from_user(&aprule, ubuf, sizeof(T_ZCAT_DIAG_CONFIG_REQ));
+ if(aprule.operation == DISABLE_LOGGING)
+ enable_kernellog = 0;
+ else if(aprule.operation == ENABLE_LOGGING)
+ enable_kernellog = 1;
+ return 0;
+}
+static int logcatk_release(struct inode *ip, struct file *fp)
+{
+ return 0;
+}
+
+
+void readringbuf_for_printk()
+{
+#if 0
+ if(enable_kernellog == 1)
+ {
+ memset(LEVER_FOR_PRINTK, 1, sizeof(UINT8)*MODULE_NUMBER_MAX);
+ wake_up_interruptible(&kernelqueue);
+
+ }
+ else
+ {
+ memset(LEVER_FOR_PRINTK, 0, sizeof(UINT8)*MODULE_NUMBER_MAX);
+ }
+ #endif
+ complete(&_kernel_dev.write_done);
+}
+EXPORT_SYMBOL(readringbuf_for_printk);
+
+static int __init logcatk_init(void)
+{
+
+ struct kernel_dev *dev;
+ int ret = misc_register(&logcatk_device);
+ printk("logcat_printk init\n");
+
+ if (ret)
+ {
+ printk(KERN_ERR "logcatk driver failed to initialize\n");
+ return -1;
+ }
+ KERNEL_BUFF = CreateRingBuffer(P_KERNEL, 16*1024);
+ APP_BUFF = CreateRingBuffer(P_APP, 16*1024);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+ //init_waitqueue_head(&dev->read_wq);
+ init_completion(&_kernel_dev.write_done);
+ //_kernel_dev = dev;
+ //kernelqueue=_kernel_dev->read_wq;
+ kfree(dev);
+ return 0;
+}
+
+
+
+static void __exit logcatk_exit(void)
+{
+ misc_deregister(&logcatk_device);
+}
+
+module_init(logcatk_init);
+module_exit(logcatk_exit);
+
+MODULE_AUTHOR("jinkai");
+MODULE_DESCRIPTION("zCat logcat_printk driver");
+MODULE_LICENSE("GPL");
+
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/ringbuf.c b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/ringbuf.c
new file mode 100644
index 0000000..6e56633
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/ringbuf.c
@@ -0,0 +1,303 @@
+/**
+ *
+ * @file ringbuf.c
+ * @brief
+ * This file is part of tools.
+ * ring buffer
+ *
+ * @details
+ * @author Tools Team.
+ * @email
+ * @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
+ * @warning
+ * @date 2019/02/02
+ * @version 1.1
+ * @pre
+ * @post
+ *
+ * @par
+ * Change History :
+ * ---------------------------------------------------------------------------
+ * date version author description
+ * ---------------------------------------------------------------------------
+ * 2013/01/21 1.0 lu.xieji Create file
+ * 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
+ * ---------------------------------------------------------------------------
+ *
+ *
+ */
+
+#include "ringbuf.h"
+#include <linux/uaccess.h>
+
+#define SYMBOL_VALUE ZCAT_IPC_ESTABLISHED
+
+/**
+ * @brief Åжϻº³åÇøÊÇ·ñÓÐЧ
+ * @param[in] ringBuf »·Ðλº³å
+ * @return ÊÇ·µ»ØTRUE,·ñ·µ»ØFALSE
+ * @note
+ * @see
+ */
+BOOL IsRingBufferValid(T_RINGBUFFER *ringBuf)
+{
+ return (ringBuf != NULL && ringBuf->symbol == SYMBOL_VALUE);
+}
+
+/**
+ * @brief ´´½¨ÐèÒªµÄ»º³åÇø,²¢ÇÒÖ¸¶¨±ê¼ÇλµÄÖµ
+ * Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
+ * @param[in] buf »º³åÇøµØÖ·
+ * @param[in] bufSize »º³åÇø´óС
+ * @param[in] bufSize ±ê¼Çλ
+ * @return ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
+ * @note
+ * @see
+ */
+T_RINGBUFFER *CreateRingBufferWithSymbol(UINT8 *buf, UINT32 bufSize, UINT32 symbol)
+{
+ T_RINGBUFFER *ringBuf = NULL;
+
+ if (bufSize <= sizeof(T_RINGBUFFER))
+ {
+ return NULL;
+ }
+
+ if (buf == NULL)
+ {
+ //ringBuf = (T_RINGBUFFER *)kmalloc(ALIGNED_SIZE(bufSize, 3), GFP_KERNEL);
+
+ //if (ringBuf == NULL)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ ringBuf = (T_RINGBUFFER *)buf;
+ }
+
+ ringBuf->capacity = bufSize - sizeof(T_RINGBUFFER);
+ ringBuf->readPoint = 0;
+ ringBuf->writePoint = 0;
+ ringBuf->symbol = symbol;
+
+ return ringBuf;
+}
+
+
+/**
+ * @brief ´´½¨ÐèÒªµÄ»º³åÇø
+ * Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
+ * @param[in] buf »º³åÇøµØÖ·
+ * @param[in] bufSize »º³åÇø´óС
+ * @return ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
+ * @note
+ * @see
+ */
+T_RINGBUFFER *CreateRingBuffer(UINT8 *buf, UINT32 bufSize)
+{
+ T_RINGBUFFER *ringBuf = NULL;
+
+ if (bufSize <= sizeof(T_RINGBUFFER))
+ {
+ return NULL;
+ }
+
+ if (buf == NULL)
+ {
+ //ringBuf = (T_RINGBUFFER *)kmalloc(ALIGNED_SIZE(bufSize, 3), GFP_KERNEL);
+
+ //if (ringBuf == NULL)
+ {
+ return NULL;
+ }
+ }
+ else
+ {
+ ringBuf = (T_RINGBUFFER *)buf;
+ }
+
+ ringBuf->capacity = bufSize - sizeof(T_RINGBUFFER);
+ ringBuf->readPoint = 0;
+ ringBuf->writePoint = 0;
+ ringBuf->symbol = SYMBOL_VALUE;
+
+ return ringBuf;
+}
+
+
+/**
+* @brief ½«Êý¾ÝдÈë»·Ðλº³å
+* @param[in] ringBuf »·Ðλº³åÖ¸Õë
+* @param[in] buf Êý¾Ý»º´æÖ¸Õë
+* @param[in] len Êý¾Ý³¤¶È
+* @param[in] flags Êý¾Ý»º´æÄÚ´æÀàÐÍ£º0:ÄÚºË̬,1:Óû§Ì¬
+* @return ·µ»ØÐ´ÈëµÄʵ¼Ê³¤¶È
+* @note
+* @see
+*/
+UINT32 WriteRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len, UINT32 flags)
+{
+ UINT32 writeLen = 0;
+ UINT32 writePoint = ringBuf->writePoint;
+ UINT32 readPoint = ringBuf->readPoint;
+
+ /* Èë²ÎÅÐ¶Ï */
+ if (!IsRingBufferValid(ringBuf) || buf == NULL || len == 0)
+ {
+ return 0;
+ }
+ if( writePoint >= ringBuf->capacity || readPoint >= ringBuf->capacity )
+ {
+ return 0;
+ }
+
+ if (writePoint >= readPoint)
+ {
+ if (ringBuf->capacity - writePoint > len)
+ {
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf + writePoint, buf, len); }
+ else { memcpy(ringBuf->buf + writePoint, buf, len); }
+ ringBuf->writePoint += len;
+ writeLen = len;
+ }
+ else if ((ringBuf->capacity - writePoint + readPoint - 1) >= len)
+ {
+ UINT32 copyLen = ringBuf->capacity - writePoint;
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf + writePoint, buf, copyLen); }
+ else { memcpy(ringBuf->buf + writePoint, buf, copyLen); }
+
+ copyLen = len - copyLen;
+
+ if (copyLen > 0)
+ {
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf, buf + (len - copyLen), copyLen); }
+ else { memcpy(ringBuf->buf, buf + (len - copyLen), copyLen); }
+ }
+
+ ringBuf->writePoint = copyLen;
+ writeLen = len;
+ }
+ }
+ else
+ {
+ if (readPoint - writePoint - 1 >= len)
+ {
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf + writePoint, buf, len); }
+ else { memcpy(ringBuf->buf + writePoint, buf, len); }
+ ringBuf->writePoint += len;
+ writeLen = len;
+ }
+ }
+
+ return writeLen;
+}
+
+/**
+* @brief ¶Áȡһ¶Î»·Ðλº³åÇøµÄÊý¾Ýµ½Ä¿±ê»º´æ
+* @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
+* @param[in] buf Ä¿±ê»º´æÖ¸Õë
+* @param[in] len Ä¿±ê»º´æ³¤¶È
+* @param[in] flags Ä¿±ê»º´æÄÚ´æÀàÐÍ£º0:ÄÚºË̬,1:Óû§Ì¬
+* @return ·µ»Ø¶ÁÈ¡³¤¶È
+* @note
+* @see
+*/
+UINT32 ReadRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len, UINT32 flags)
+{
+ UINT32 readLen = 0;
+ UINT32 writePoint = ringBuf->writePoint;
+ UINT32 readPoint = ringBuf->readPoint;
+
+ /* ²ÎÊý¼ì²é */
+ if (!IsRingBufferValid(ringBuf) || buf == NULL || len == 0)
+ {
+ return 0;
+ }
+ if( writePoint >= ringBuf->capacity || readPoint >= ringBuf->capacity )
+ {
+ return 0;
+ }
+ if (writePoint > readPoint)
+ {
+ readLen = writePoint - readPoint;
+ readLen = (readLen >= len) ? len : readLen;
+
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf, ringBuf->buf + readPoint, readLen); }
+ else { memcpy(buf, ringBuf->buf + readPoint, readLen); }
+ ringBuf->readPoint += readLen;
+ }
+ else if (writePoint < readPoint)
+ {
+ readLen = ringBuf->capacity - readPoint + writePoint;
+ readLen = (readLen >= len) ? len : readLen;
+
+ if (ringBuf->capacity - readPoint >= readLen)
+ {
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf, ringBuf->buf + readPoint, readLen); }
+ else { memcpy(buf, ringBuf->buf + readPoint, readLen); }
+ ringBuf->readPoint = (ringBuf->readPoint + readLen) % ringBuf->capacity;
+ }
+ else
+ {
+ UINT32 copyLen = ringBuf->capacity - readPoint;
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf, ringBuf->buf + readPoint, copyLen); }
+ else { memcpy(buf, ringBuf->buf + readPoint, copyLen); }
+
+ copyLen = readLen - copyLen;
+ if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf + (readLen - copyLen), ringBuf->buf, copyLen); }
+ else { memcpy(buf + (readLen - copyLen), ringBuf->buf, copyLen);}
+
+ ringBuf->readPoint = copyLen;
+ }
+ }
+
+ return readLen;
+}
+
+/**
+* @brief »ñÈ¡µ±Ç°Ring BufferÖпÕÏÐÇøµÄ´óС
+* @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
+* @return ·µ»Ø×Ö½ÚÊý
+* @note
+* @see
+*/
+UINT32 GetRingBufferSize(T_RINGBUFFER *ringBuf)
+{
+ UINT32 writePoint = ringBuf->writePoint;
+ UINT32 readPoint = ringBuf->readPoint;
+ UINT32 bufSize = 0;
+
+ if (!IsRingBufferValid(ringBuf))
+ {
+ return 0;
+ }
+
+ if (writePoint > readPoint)
+ {
+ bufSize = writePoint - readPoint;
+ }
+ else if (writePoint < readPoint)
+ {
+ bufSize = ringBuf->capacity - readPoint + writePoint;
+ }
+
+ return bufSize;
+}
+
+/**
+* @brief ½«»º³åÇøÖÿÕ
+* @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
+* @return void
+* @note
+* @see
+*/
+VOID EmptyRingBuffer(T_RINGBUFFER *ringBuf)
+{
+ if (IsRingBufferValid(ringBuf))
+ {
+ ringBuf->readPoint = ringBuf->writePoint;
+ }
+}
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/ringbuf.h b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/ringbuf.h
new file mode 100644
index 0000000..f141c42
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/ringbuf.h
@@ -0,0 +1,131 @@
+/**
+ *
+ * @file commgt_api.h
+ * @brief
+ * This file is part of tools.
+ * ¹¤¾ßCommAgt½Ó¿Ú¹«¹²ÉùÃ÷
+ *
+ * @details
+ * @author Tools Team.
+ * @email
+ * @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
+ * @warning
+ * @date 2019/02/02
+ * @version 1.4
+ * @pre
+ * @post
+ *
+ * @par
+ * Change History :
+ * ---------------------------------------------------------------------------
+ * date version author description
+ * ---------------------------------------------------------------------------
+ * 2013/01/14 1.0 lu.xieji Create file
+ * 2018/09/24 1.1 jiang.fenglin ºË¼äͨÐŹ²ÏíÄÚ´æÓÉ1Mµ÷ÕûΪ512K
+ * 2018/09/25 1.2 dai.kang »·Ðλº³åÇøÄÚ´æÓÉ3.5Mµ÷ÕûΪ2M
+ * 2018/12/25 1.3 dai.kang »·Ðλº³åÇøÄÚ´æÓɾ²Ì¬·ÖÅäµ÷ÕûΪzOss_GetUB¶¯Ì¬·Ö±ð
+ * 2019/02/02 1.4 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
+ * ---------------------------------------------------------------------------
+ *
+ *
+ */
+
+#ifndef RINGBUF_H_
+#define RINGBUF_H_
+
+#include "logcat_drv.h"
+
+#define ZCAT_MEM_TYPE_KERNEL 0
+#define ZCAT_MEM_TYPE_USER 1
+
+// ´óС¶ÔÆë
+#define ALIGNED_SIZE(size, alignment) (((size) + (alignment)) & ~(alignment))
+
+/* ´òÓ¡»º³åÇø */
+typedef struct
+{
+ UINT32 capacity; /* »º³åÇøÈÝÁ¿*/
+ volatile UINT32 readPoint; /* ¶ÁÖ¸Õë */
+ volatile UINT32 writePoint; /* дָÕë */
+ UINT32 symbol; /* ¿ØÖÆ¿é±êʶ·û */
+ UINT8 buf[1]; /* ´òÓ¡»º³åÇø */
+} T_RINGBUFFER;
+
+
+/**
+ * @brief ´´½¨ÐèÒªµÄ»º³åÇø
+ * Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
+ * @param[in] buf »º³åÇøµØÖ·
+ * @param[in] bufSize »º³åÇø´óС
+ * @return ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
+ * @note
+ * @see
+ */
+T_RINGBUFFER* CreateRingBuffer(UINT8 *buf, UINT32 bufSize);
+
+/**
+ * @brief ´´½¨ÐèÒªµÄ»º³åÇø,²¢ÇÒÖ¸¶¨±ê¼ÇλµÄÖµ
+ * Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
+ * @param[in] buf »º³åÇøµØÖ·
+ * @param[in] bufSize »º³åÇø´óС
+ * @param[in] bufSize ±ê¼Çλ
+ * @return ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
+ * @note
+ * @see
+ */
+T_RINGBUFFER* CreateRingBufferWithSymbol(UINT8 *buf, UINT32 bufSize, UINT32 symbol);
+
+/**
+ * @brief Åжϻº³åÇøÊÇ·ñÓÐЧ
+ * @param[in] ringBuf »·Ðλº³å
+ * @return ÊÇ·µ»ØTRUE,·ñ·µ»ØFALSE
+ * @note
+ * @see
+ */
+BOOL IsRingBufferValid(T_RINGBUFFER *ringBuf);
+
+/**
+ * @brief ½«»º³åÇøÖÿÕ
+ * @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
+ * @return void
+ * @note
+ * @see
+ */
+VOID EmptyRingBuffer(T_RINGBUFFER *ringBuf);
+
+/**
+ * @brief ½«Êý¾ÝдÈë»·Ðλº³å
+ * @param[in] ringBuf »·Ðλº³åÖ¸Õë
+ * @param[in] buf Êý¾Ý»º´æÖ¸Õë
+ * @param[in] len Êý¾Ý³¤¶È
+ * @param[in] flags Êý¾Ý»º´æÄÚ´æÀàÐÍ£º0:ÄÚºË̬,1:Óû§Ì¬
+ * @return ·µ»ØÐ´ÈëµÄʵ¼Ê³¤¶È
+ * @note
+ * @see
+ */
+UINT32 WriteRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len, UINT32 flags);
+
+/**
+ * @brief ¶Áȡһ¶Î»·Ðλº³åÇøµÄÊý¾Ýµ½Ä¿±ê»º´æ
+ * @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
+ * @param[in] buf Ä¿±ê»º´æÖ¸Õë
+ * @param[in] len Ä¿±ê»º´æ³¤¶È
+ * @param[in] flags Ä¿±ê»º´æÄÚ´æÀàÐÍ£º0:ÄÚºË̬,1:Óû§Ì¬
+ * @return ·µ»Ø¶ÁÈ¡³¤¶È
+ * @note
+ * @see
+ */
+UINT32 ReadRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len, UINT32 flags);
+
+/**
+ * @brief »ñÈ¡µ±Ç°Ring BufferÖпÕÏÐÇøµÄ´óС
+ * @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
+ * @return ·µ»Ø×Ö½ÚÊý
+ * @note
+ * @see
+ */
+UINT32 GetRingBufferSize(T_RINGBUFFER *ringBuf);
+
+
+#endif /*RINGBUF_H_*/
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/zcat_device.c b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/zcat_device.c
new file mode 100755
index 0000000..e6bc7c6
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/zcat_device.c
@@ -0,0 +1,31 @@
+/**
+ *
+ * @file zcat_device.c
+ * @brief
+ * This file is part of ZCAT.
+ * zcat´¦Àíapp²àlogµÄÐéÄâÉ豸
+ *
+ * @details
+ * @author Tools Team.
+ * @email
+ * @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
+ * @warning
+ * @date 2019/02/12
+ * @version 1.1
+ * @pre
+ * @post
+ *
+ * @par
+ * Change History :
+ * ---------------------------------------------------------------------------
+ * date version author description
+ * ---------------------------------------------------------------------------
+ * 2015/07/08 1.0 wang.qing Create file
+ * 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
+ * 2019/02/22 1.1 jiang.fenglin ¹Ø±Õzcat_device.cÎļþ,»Ö¸´logcat_drv_printf.c
+ * ---------------------------------------------------------------------------
+ *
+ *
+ */
+
+