[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/tracker.c b/upstream/linux-5.10/kernel/tracker.c
new file mode 100755
index 0000000..6f7e1ab
--- /dev/null
+++ b/upstream/linux-5.10/kernel/tracker.c
@@ -0,0 +1,459 @@
+/*
+ * tracker.c - System accounting over taskstats interface
+ *
+ * Copyright (C) Jay Lan,	<jlan@sgi.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/timer.h>
+#include <linux/uaccess.h>
+#include <linux/export.h>
+#include <linux/sched/clock.h>
+#include "ram_config.h"
+
+/*******************************************************************************
+*                                   ºê¶¨Òå                                     *
+*******************************************************************************/
+#define _OS_LINUX                    1
+
+#if defined(_OS_TOS)
+# define OS_STATISTIC_IRAM_BASE    (IRAM_BASE_ADDR_OS_STATISTIC_PSCPU)
+# define OS_STATISTIC_TIME         zDrvTimer_Stamp()
+#elif defined(_OS_LINUX)
+# define OS_STATISTIC_IRAM_BASE    g_zxic_trace_apcpu_addr //(IRAM_BASE_ADDR_OS_STATISTIC_APCPU)
+# define OS_STATISTIC_TIME         (cpu_clock(0)>>10)
+#else
+# error "unknown os"
+#endif
+
+
+
+#define OS_IRAM_STATISTIC_CNT         (5)
+#define OS_IRAM_STATISTIC_NAME_LEN    (16)
+#define OS_DDR_STATISTIC_CNT          (1000)
+
+#define OS_IRAM_THREAD_SWAPIN      (OS_STATISTIC_IRAM_BASE)
+#define OS_IRAM_IRQ_START          (OS_IRAM_THREAD_SWAPIN + sizeof(t_os_iram_thread_statistic))
+#define OS_IRAM_IRQ_END            (OS_IRAM_IRQ_START + sizeof(t_os_iram_statistic))
+
+#if defined(_OS_TOS)
+#define OS_IRAM_DSR_START          (OS_IRAM_IRQ_END + sizeof(t_os_iram_statistic))
+#define OS_IRAM_DSR_END            (OS_IRAM_DSR_START + sizeof(t_os_iram_statistic))
+#elif defined(_OS_LINUX)
+#define OS_IRAM_SOFTIRQ_START      (OS_IRAM_IRQ_END + sizeof(t_os_iram_statistic))
+#define OS_IRAM_SOFTIRQ_END        (OS_IRAM_SOFTIRQ_START + sizeof(t_os_iram_statistic))
+#define OS_IRAM_TIMER_START        (OS_IRAM_SOFTIRQ_END + sizeof(t_os_iram_statistic))
+#define OS_IRAM_TIMER_END          (OS_IRAM_TIMER_START + sizeof(t_os_iram_statistic))
+#endif
+
+#define os_statistic_check()       *((volatile unsigned long *)OS_STATISTIC_IRAM_BASE)
+#define os_statistic_enabled()     g_os_statistic_enable 
+
+/*******************************************************************************
+*                                   Êý¾Ý½á¹¹¶¨Òå                               *
+*******************************************************************************/
+typedef volatile struct {
+    unsigned int cnt;
+    unsigned int index;
+    struct {
+        unsigned char name[OS_IRAM_STATISTIC_NAME_LEN];
+        unsigned int data2;
+    } statistics[OS_IRAM_STATISTIC_CNT];
+}t_os_iram_thread_statistic;
+
+typedef volatile struct {
+    unsigned int cnt;
+    unsigned int index;
+    struct {
+        unsigned int data1;
+        unsigned int data2;
+    } statistics[OS_IRAM_STATISTIC_CNT];
+}t_os_iram_statistic;
+
+typedef struct {
+    unsigned int cnt;
+    unsigned int index;
+    struct {
+        unsigned int data1;
+        unsigned int data2;
+    } statistics[OS_DDR_STATISTIC_CNT];
+}t_os_ddr_statistic;
+
+/*******************************************************************************
+*                                   È«¾Ö±äÁ¿                                   *
+*******************************************************************************/
+#if defined(_OS_LINUX)
+volatile  static char *g_zxic_trace_apcpu_addr;
+#endif
+
+volatile  static int g_os_statistic_enable;
+volatile  static unsigned int g_os_statistic_cnt;
+
+volatile  static t_os_iram_thread_statistic *g_os_iram_swapin_statistic;
+volatile  static t_os_iram_statistic        *g_os_iram_irq_start_statistic;
+volatile  static t_os_iram_statistic        *g_os_iram_irq_end_statistic;
+
+#if defined(_OS_TOS)
+static t_os_iram_statistic *g_os_iram_dsr_start_statistic;
+static t_os_iram_statistic *g_os_iram_dsr_end_statistic;
+#elif defined(_OS_LINUX)
+volatile  static t_os_iram_statistic *g_os_iram_softirq_start_statistic;
+volatile  static t_os_iram_statistic *g_os_iram_softirq_end_statistic;
+volatile  static t_os_iram_statistic *g_os_iram_timer_start_statistic;
+volatile  static t_os_iram_statistic *g_os_iram_timer_end_statistic;
+#endif
+
+volatile  static t_os_ddr_statistic *g_os_ddr_swapin_statistic;
+volatile  static t_os_ddr_statistic *g_os_ddr_irq_start_statistic;
+volatile  static t_os_ddr_statistic *g_os_ddr_irq_end_statistic;
+
+#if defined(_OS_TOS)
+static t_os_ddr_statistic *g_os_ddr_dsr_start_statistic;
+static t_os_ddr_statistic *g_os_ddr_dsr_end_statistic;
+#elif defined(_OS_LINUX)
+volatile  static t_os_ddr_statistic *g_os_ddr_softirq_start_statistic;
+volatile  static t_os_ddr_statistic *g_os_ddr_softirq_end_statistic;
+volatile  static t_os_ddr_statistic *g_os_ddr_timer_start_statistic;
+volatile  static t_os_ddr_statistic *g_os_ddr_timer_end_statistic;
+#endif
+
+/*******************************************************************************
+*                                   È«¾Öº¯ÊýÉùÃ÷                               *
+*******************************************************************************/
+void os_statistic_enable(void);
+/*******************************************************************************
+*                                   ¾Ö²¿º¯Êý                                   *
+*******************************************************************************/
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:     ¹ì¼£Í³¼Æµ½IRAM
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý)  iram_addr: µØÖ· 
+                data:      ʼþÏî
+                time:      ʱ¼ä
+*   (´«³ö²ÎÊý)  void
+* ·µ »Ø Öµ:     void
+* ÆäËü˵Ã÷:     ÎÞ
+*******************************************************************************/
+static inline void os_statistic_in_iram(volatile void *iram_addr, void *data, unsigned long time)
+{
+    unsigned long       index;
+    t_os_iram_statistic *iram;
+
+    iram = (t_os_iram_statistic *)iram_addr;
+    
+    index = iram->index;
+    if(index >= OS_IRAM_STATISTIC_CNT)
+    {
+        index = 0;
+    }
+
+    iram->statistics[index].data1 = (unsigned int)data;
+    iram->statistics[index].data2 = time;
+    index++;
+
+    iram->index = index;
+    iram->cnt = g_os_statistic_cnt;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:     Ï̹߳켣ͳ¼Æµ½IRAM
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý)  iram_addr: µØÖ· 
+                data:      ʼþÏî
+                time:      ʱ¼ä
+*   (´«³ö²ÎÊý)  void
+* ·µ »Ø Öµ:     void
+* ÆäËü˵Ã÷:     ÎÞ
+*******************************************************************************/
+static inline void os_statistic_thread_in_iram(volatile void *iram_addr, void *data, unsigned long time)
+{
+    unsigned long              index;
+    t_os_iram_thread_statistic *iram;
+
+    iram = (t_os_iram_thread_statistic *)iram_addr;
+    
+    index = iram->index;
+    if(index >= OS_IRAM_STATISTIC_CNT)
+    {
+        index = 0;
+    }
+
+#if defined(_OS_TOS)
+    strncpy((char *)(iram->statistics[index].name), cyg_thread_get_name((cyg_handle_t)data), OS_IRAM_STATISTIC_NAME_LEN - 1);
+#elif defined(_OS_LINUX)
+    strncpy((char *)(iram->statistics[index].name), ((struct task_struct *)data)->comm, OS_IRAM_STATISTIC_NAME_LEN - 1);
+#else
+# error "unkown os"
+#endif
+    iram->statistics[index].name[OS_IRAM_STATISTIC_NAME_LEN - 1] = 0;
+    iram->statistics[index].data2 = time;
+    index++;
+
+    iram->index = index;
+    iram->cnt = g_os_statistic_cnt;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:     ¹ì¼£Í³¼Æµ½DDR
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý)  iram_addr: µØÖ· 
+                data:      ʼþÏî
+                time:      ʱ¼ä
+*   (´«³ö²ÎÊý)  void
+* ·µ »Ø Öµ:     void
+* ÆäËü˵Ã÷:     ÎÞ
+*******************************************************************************/
+static inline void os_statistic_in_ddr(void *ddr_addr, void *data, unsigned long time)
+{
+    unsigned long              index;
+    t_os_ddr_statistic         *ddr;
+
+    ddr  = (t_os_ddr_statistic *)ddr_addr;
+    
+    index = ddr->index;
+    if (index >= OS_DDR_STATISTIC_CNT)
+    {
+        index = 0;
+    }
+    ddr->statistics[index].data1 = (unsigned int)data;
+    ddr->statistics[index].data2 = time;
+    index++;
+
+    ddr->index = index;
+    ddr->cnt   = g_os_statistic_cnt;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:     ¹ì¼£Í³¼Æµ½DDR
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý)  iram_addr: µØÖ· 
+                data:      ʼþÏî
+                time:      ʱ¼ä
+*   (´«³ö²ÎÊý)  void
+* ·µ »Ø Öµ:     void
+* ÆäËü˵Ã÷:     ÎÞ
+*******************************************************************************/
+static inline void os_statistic_info_update(void)
+{
+    g_os_statistic_cnt++;
+}
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:     ¶¨Ê±Æ÷»Øµ÷¹³×Ó
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý)  
+*   (´«³ö²ÎÊý)  void
+* ·µ »Ø Öµ:     void
+* ÆäËü˵Ã÷:     ÎÞ
+*******************************************************************************/
+static int os_statistic_delayed_work_timer_fn(unsigned long data)
+{
+    int sec = 0;
+    msleep(20000);
+    while(!os_statistic_check())
+    {
+        //³¬¹ý40s£¬Ö±½ÓÍ˳ö
+        if(sec >= 4)
+            return 0;
+        msleep(10000);
+        sec++;
+    }
+    os_statistic_enable();
+    return 0;
+}
+
+/*******************************************************************************
+*                                 È«¾Öº¯ÊýʵÏÖ                                 *
+*******************************************************************************/
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:     ʹÄܹ켣ͳ¼Æ¹¦ÄÜ
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý)  address: ¼Ç¼µ½IRAMÖеĵØÖ· 
+                size:    IRAM¿Õ¼ä´óС
+*   (´«³ö²ÎÊý)  void
+* ·µ »Ø Öµ:     void
+* ÆäËü˵Ã÷:     ÎÞ
+*******************************************************************************/
+void os_statistic_enable(void)
+{
+#if defined(_OS_TOS)
+    g_os_iram_swapin_statistic        = (t_os_iram_thread_statistic *)OS_IRAM_THREAD_SWAPIN;
+    g_os_iram_irq_start_statistic     = (t_os_iram_statistic *)OS_IRAM_IRQ_START;
+    g_os_iram_irq_end_statistic       = (t_os_iram_statistic *)OS_IRAM_IRQ_END;
+    g_os_iram_dsr_start_statistic     = (t_os_iram_statistic *)OS_IRAM_DSR_START;
+    g_os_iram_dsr_end_statistic       = (t_os_iram_statistic *)OS_IRAM_DSR_END;
+
+    g_os_ddr_swapin_statistic         = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
+    g_os_ddr_irq_start_statistic      = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
+    g_os_ddr_irq_end_statistic        = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
+    g_os_ddr_dsr_start_statistic      = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
+    g_os_ddr_dsr_end_statistic        = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
+#elif defined(_OS_LINUX)
+    g_os_iram_swapin_statistic        = (t_os_iram_thread_statistic *)OS_IRAM_THREAD_SWAPIN;    
+    g_os_iram_irq_start_statistic     = (t_os_iram_statistic *)OS_IRAM_IRQ_START;    
+    g_os_iram_irq_end_statistic       = (t_os_iram_statistic *)OS_IRAM_IRQ_END;    
+    g_os_iram_softirq_start_statistic = (t_os_iram_statistic *)OS_IRAM_SOFTIRQ_START;    
+    g_os_iram_softirq_end_statistic   = (t_os_iram_statistic *)OS_IRAM_SOFTIRQ_END;    
+    g_os_iram_timer_start_statistic   = (t_os_iram_statistic *)OS_IRAM_TIMER_START;    
+    g_os_iram_timer_end_statistic     = (t_os_iram_statistic *)OS_IRAM_TIMER_END;
+
+    g_os_ddr_swapin_statistic         = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
+    g_os_ddr_irq_start_statistic      = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
+    g_os_ddr_irq_end_statistic        = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
+    g_os_ddr_softirq_start_statistic  = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
+    g_os_ddr_softirq_end_statistic    = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
+    g_os_ddr_timer_start_statistic    = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
+    g_os_ddr_timer_end_statistic      = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
+
+#else
+# error "unkown os"
+#endif
+    if ((unsigned int )g_os_iram_timer_end_statistic - (unsigned int )g_os_iram_swapin_statistic > (unsigned int )IRAM_BASE_LEN_OS_STATISTIC_PSCPU )
+    {
+        BUG();
+    }
+    g_os_statistic_enable = 1;
+}
+EXPORT_SYMBOL(os_statistic_enable);
+
+void zxic_trace_task_switch(struct task_struct *next)
+{
+	unsigned long time;
+    if (!g_os_statistic_enable)
+        return ;
+
+    time = OS_STATISTIC_TIME;
+    os_statistic_thread_in_iram(g_os_iram_swapin_statistic, next, time);
+    os_statistic_in_ddr(g_os_ddr_swapin_statistic, next, time);
+    os_statistic_info_update();
+}
+
+void zxic_trace_irq_enter(u32 irq)
+{
+	unsigned long time;
+    if (!g_os_statistic_enable)
+        return ;
+
+    time = OS_STATISTIC_TIME;
+    os_statistic_in_iram(g_os_iram_irq_start_statistic, irq, time);
+    os_statistic_in_ddr(g_os_ddr_irq_start_statistic, irq, time);
+    os_statistic_info_update();
+}
+
+void zxic_trace_irq_exit(u32 irq)
+{
+	unsigned long time;
+    if (!g_os_statistic_enable)
+        return ;
+
+    time = OS_STATISTIC_TIME;
+    os_statistic_in_iram(g_os_iram_irq_end_statistic, irq, time);
+    os_statistic_in_ddr(g_os_ddr_irq_end_statistic, irq, time);
+    os_statistic_info_update();
+}
+
+void zxic_trace_softirq_enter(u32 vec_nr)
+{
+	unsigned long time;
+    if (!g_os_statistic_enable)
+        return ;
+
+    time = OS_STATISTIC_TIME;
+    os_statistic_in_iram(g_os_iram_softirq_start_statistic, vec_nr, time);
+    os_statistic_in_ddr(g_os_ddr_softirq_start_statistic, vec_nr, time);
+    os_statistic_info_update();
+}
+
+void zxic_trace_softirq_exit(u32 vec_nr)
+{
+	unsigned long time;
+    if (!g_os_statistic_enable)
+        return ;
+
+    time = OS_STATISTIC_TIME;
+    os_statistic_in_iram(g_os_iram_softirq_end_statistic, vec_nr, time);
+    os_statistic_in_ddr(g_os_ddr_softirq_end_statistic, vec_nr, time);
+    os_statistic_info_update();
+}
+
+void zxic_trace_timer_enter(void *func)
+{
+	unsigned long time;
+    if (!g_os_statistic_enable)
+        return ;
+
+    time = OS_STATISTIC_TIME;
+    os_statistic_in_iram(g_os_iram_timer_start_statistic, func, time);
+    os_statistic_in_ddr(g_os_ddr_timer_start_statistic, func, time);
+    os_statistic_info_update();
+}
+
+void zxic_trace_timer_exit(void *func)
+{
+	unsigned long time;
+    if (!g_os_statistic_enable)
+        return ;
+
+    time = OS_STATISTIC_TIME;
+    os_statistic_in_iram(g_os_iram_timer_end_statistic, func, time);
+    os_statistic_in_ddr(g_os_ddr_timer_end_statistic, func, time);
+    os_statistic_info_update();
+}
+
+
+/*******************************************************************************
+* ¹¦ÄÜÃèÊö:     ¹ì¼£Í³¼Æµ½DDR
+* ²ÎÊý˵Ã÷:     
+*   (´«Èë²ÎÊý)  iram_addr: µØÖ· 
+                data:      ʼþÏî
+                time:      ʱ¼ä
+*   (´«³ö²ÎÊý)  void
+* ·µ »Ø Öµ:     void
+* ÆäËü˵Ã÷:     ÎÞ
+*******************************************************************************/
+int __init zxic_enable_tracer(void)
+{
+    struct timer_list timer;
+    struct task_struct *task;
+
+#ifdef IRAM_BASE_ADDR_VA
+    g_zxic_trace_apcpu_addr = IRAM_BASE_ADDR_OS_STATISTIC_PSCPU;
+#else
+    g_zxic_trace_apcpu_addr = ioremap(IRAM_BASE_ADDR_OS_STATISTIC_PSCPU, IRAM_BASE_LEN_OS_STATISTIC_PSCPU);
+#endif
+
+    /*
+    init_timer(&timer);
+    timer.expires = jiffies + 40*HZ;//msecs_to_jiffies(40*1000);//ÑÓ³Ù40Ãë
+    timer.data = 0;
+    timer.function = os_statistic_delayed_work_timer_fn;
+    setup_timer(&timer, os_statistic_delayed_work_timer_fn, 0);
+    add_timer(&timer);
+    */
+    //task = kthread_create(os_statistic_delayed_work_timer_fn, 0, "g_zxic_trace_sync_thread", 0);
+    //wake_up_process(task);
+    os_statistic_enable();
+    return 0x0;
+}
+module_init(zxic_enable_tracer);
+
+