blob: 792818bce53ab1ae7f8808368dd9cc3ea64d6436 [file] [log] [blame]
xf.lied996a22025-03-13 23:49:05 -07001/*
2 * tracker.c - System accounting over taskstats interface
3 *
4 * Copyright (C) Jay Lan, <jlan@sgi.com>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/jiffies.h>
23#include <linux/slab.h>
24#include <linux/timer.h>
25#include <linux/delay.h>
26#include <linux/kthread.h>
27#include <linux/timer.h>
28#include <linux/uaccess.h>
29#include <linux/export.h>
30#include <linux/sched/clock.h>
31#include "ram_config.h"
32
33/*******************************************************************************
34* ºê¶¨Òå *
35*******************************************************************************/
36#define _OS_LINUX 1
37
38#if defined(_OS_TOS)
39# define OS_STATISTIC_IRAM_BASE (IRAM_BASE_ADDR_OS_STATISTIC_PSCPU)
40# define OS_STATISTIC_TIME zDrvTimer_Stamp()
41#elif defined(_OS_LINUX)
42# define OS_STATISTIC_IRAM_BASE g_zxic_trace_apcpu_addr //(IRAM_BASE_ADDR_OS_STATISTIC_APCPU)
43# define OS_STATISTIC_TIME (cpu_clock(0)>>10)
44#else
45# error "unknown os"
46#endif
47
48
49
50#define OS_IRAM_STATISTIC_CNT (5)
51#define OS_IRAM_STATISTIC_NAME_LEN (16)
52#define OS_DDR_STATISTIC_CNT (1000)
53
54#define OS_IRAM_THREAD_SWAPIN (OS_STATISTIC_IRAM_BASE)
55#define OS_IRAM_IRQ_START (OS_IRAM_THREAD_SWAPIN + sizeof(t_os_iram_thread_statistic))
56#define OS_IRAM_IRQ_END (OS_IRAM_IRQ_START + sizeof(t_os_iram_statistic))
57
58#if defined(_OS_TOS)
59#define OS_IRAM_DSR_START (OS_IRAM_IRQ_END + sizeof(t_os_iram_statistic))
60#define OS_IRAM_DSR_END (OS_IRAM_DSR_START + sizeof(t_os_iram_statistic))
61#elif defined(_OS_LINUX)
62#define OS_IRAM_SOFTIRQ_START (OS_IRAM_IRQ_END + sizeof(t_os_iram_statistic))
63#define OS_IRAM_SOFTIRQ_END (OS_IRAM_SOFTIRQ_START + sizeof(t_os_iram_statistic))
64#define OS_IRAM_TIMER_START (OS_IRAM_SOFTIRQ_END + sizeof(t_os_iram_statistic))
65#define OS_IRAM_TIMER_END (OS_IRAM_TIMER_START + sizeof(t_os_iram_statistic))
xf.li6b423c72025-03-14 00:07:42 -070066#define OS_IRAM_RESET_REASON_START (OS_STATISTIC_IRAM_BASE + 0x800 - sizeof(T_Reset_Reason))
xf.lied996a22025-03-13 23:49:05 -070067#endif
68
69#define os_statistic_check() *((volatile unsigned long *)OS_STATISTIC_IRAM_BASE)
70#define os_statistic_enabled() g_os_statistic_enable
71
72/*******************************************************************************
73* Êý¾Ý½á¹¹¶¨Òå *
74*******************************************************************************/
75typedef volatile struct {
76 unsigned int cnt;
77 unsigned int index;
78 struct {
79 unsigned char name[OS_IRAM_STATISTIC_NAME_LEN];
80 unsigned int data2;
81 } statistics[OS_IRAM_STATISTIC_CNT];
82}t_os_iram_thread_statistic;
83
84typedef volatile struct {
85 unsigned int cnt;
86 unsigned int index;
87 struct {
88 unsigned int data1;
89 unsigned int data2;
90 } statistics[OS_IRAM_STATISTIC_CNT];
91}t_os_iram_statistic;
92
93typedef struct {
94 unsigned int cnt;
95 unsigned int index;
96 struct {
97 unsigned int data1;
98 unsigned int data2;
99 } statistics[OS_DDR_STATISTIC_CNT];
100}t_os_ddr_statistic;
101
xf.li6b423c72025-03-14 00:07:42 -0700102typedef struct
103{
104 char ramdump_reason[32]; //±ÈÈ磺ramdump_ap_appname
105 char kernel_reboot[32]; //±ÈÈ磺reboot_ap_appname
106} T_Reset_Reason;
107
xf.lied996a22025-03-13 23:49:05 -0700108/*******************************************************************************
109* È«¾Ö±äÁ¿ *
110*******************************************************************************/
111#if defined(_OS_LINUX)
112volatile static char *g_zxic_trace_apcpu_addr;
113#endif
114
115volatile static int g_os_statistic_enable;
116volatile static unsigned int g_os_statistic_cnt;
117
118volatile static t_os_iram_thread_statistic *g_os_iram_swapin_statistic;
119volatile static t_os_iram_statistic *g_os_iram_irq_start_statistic;
120volatile static t_os_iram_statistic *g_os_iram_irq_end_statistic;
121
122#if defined(_OS_TOS)
123static t_os_iram_statistic *g_os_iram_dsr_start_statistic;
124static t_os_iram_statistic *g_os_iram_dsr_end_statistic;
125#elif defined(_OS_LINUX)
126volatile static t_os_iram_statistic *g_os_iram_softirq_start_statistic;
127volatile static t_os_iram_statistic *g_os_iram_softirq_end_statistic;
128volatile static t_os_iram_statistic *g_os_iram_timer_start_statistic;
129volatile static t_os_iram_statistic *g_os_iram_timer_end_statistic;
130#endif
131
132volatile static t_os_ddr_statistic *g_os_ddr_swapin_statistic;
133volatile static t_os_ddr_statistic *g_os_ddr_irq_start_statistic;
134volatile static t_os_ddr_statistic *g_os_ddr_irq_end_statistic;
135
136#if defined(_OS_TOS)
137static t_os_ddr_statistic *g_os_ddr_dsr_start_statistic;
138static t_os_ddr_statistic *g_os_ddr_dsr_end_statistic;
139#elif defined(_OS_LINUX)
140volatile static t_os_ddr_statistic *g_os_ddr_softirq_start_statistic;
141volatile static t_os_ddr_statistic *g_os_ddr_softirq_end_statistic;
142volatile static t_os_ddr_statistic *g_os_ddr_timer_start_statistic;
143volatile static t_os_ddr_statistic *g_os_ddr_timer_end_statistic;
xf.li6b423c72025-03-14 00:07:42 -0700144volatile T_Reset_Reason *g_os_reset_reason;
xf.lied996a22025-03-13 23:49:05 -0700145#endif
146
147/*******************************************************************************
148* È«¾Öº¯ÊýÉùÃ÷ *
149*******************************************************************************/
150void os_statistic_enable(void);
151/*******************************************************************************
152* ¾Ö²¿º¯Êý *
153*******************************************************************************/
154/*******************************************************************************
155* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½IRAM
156* ²ÎÊý˵Ã÷:
157* (´«Èë²ÎÊý) iram_addr: µØÖ·
158 data: ʼþÏî
159 time: ʱ¼ä
160* (´«³ö²ÎÊý) void
161* ·µ »Ø Öµ: void
162* ÆäËü˵Ã÷: ÎÞ
163*******************************************************************************/
164static inline void os_statistic_in_iram(volatile void *iram_addr, void *data, unsigned long time)
165{
166 unsigned long index;
167 t_os_iram_statistic *iram;
168
169 iram = (t_os_iram_statistic *)iram_addr;
170
171 index = iram->index;
172 if(index >= OS_IRAM_STATISTIC_CNT)
173 {
174 index = 0;
175 }
176
177 iram->statistics[index].data1 = (unsigned int)data;
178 iram->statistics[index].data2 = time;
179 index++;
180
181 iram->index = index;
182 iram->cnt = g_os_statistic_cnt;
183}
184
185/*******************************************************************************
186* ¹¦ÄÜÃèÊö: Ï̹߳켣ͳ¼Æµ½IRAM
187* ²ÎÊý˵Ã÷:
188* (´«Èë²ÎÊý) iram_addr: µØÖ·
189 data: ʼþÏî
190 time: ʱ¼ä
191* (´«³ö²ÎÊý) void
192* ·µ »Ø Öµ: void
193* ÆäËü˵Ã÷: ÎÞ
194*******************************************************************************/
195static inline void os_statistic_thread_in_iram(volatile void *iram_addr, void *data, unsigned long time)
196{
197 unsigned long index;
198 t_os_iram_thread_statistic *iram;
199
200 iram = (t_os_iram_thread_statistic *)iram_addr;
201
202 index = iram->index;
203 if(index >= OS_IRAM_STATISTIC_CNT)
204 {
205 index = 0;
206 }
207
208#if defined(_OS_TOS)
209 strncpy((char *)(iram->statistics[index].name), cyg_thread_get_name((cyg_handle_t)data), OS_IRAM_STATISTIC_NAME_LEN - 1);
210#elif defined(_OS_LINUX)
211 strncpy((char *)(iram->statistics[index].name), ((struct task_struct *)data)->comm, OS_IRAM_STATISTIC_NAME_LEN - 1);
212#else
213# error "unkown os"
214#endif
215 iram->statistics[index].name[OS_IRAM_STATISTIC_NAME_LEN - 1] = 0;
216 iram->statistics[index].data2 = time;
217 index++;
218
219 iram->index = index;
220 iram->cnt = g_os_statistic_cnt;
221}
222
223/*******************************************************************************
224* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½DDR
225* ²ÎÊý˵Ã÷:
226* (´«Èë²ÎÊý) iram_addr: µØÖ·
227 data: ʼþÏî
228 time: ʱ¼ä
229* (´«³ö²ÎÊý) void
230* ·µ »Ø Öµ: void
231* ÆäËü˵Ã÷: ÎÞ
232*******************************************************************************/
233static inline void os_statistic_in_ddr(void *ddr_addr, void *data, unsigned long time)
234{
235 unsigned long index;
236 t_os_ddr_statistic *ddr;
237
238 ddr = (t_os_ddr_statistic *)ddr_addr;
239
240 index = ddr->index;
241 if (index >= OS_DDR_STATISTIC_CNT)
242 {
243 index = 0;
244 }
245 ddr->statistics[index].data1 = (unsigned int)data;
246 ddr->statistics[index].data2 = time;
247 index++;
248
249 ddr->index = index;
250 ddr->cnt = g_os_statistic_cnt;
251}
252
253/*******************************************************************************
254* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½DDR
255* ²ÎÊý˵Ã÷:
256* (´«Èë²ÎÊý) iram_addr: µØÖ·
257 data: ʼþÏî
258 time: ʱ¼ä
259* (´«³ö²ÎÊý) void
260* ·µ »Ø Öµ: void
261* ÆäËü˵Ã÷: ÎÞ
262*******************************************************************************/
263static inline void os_statistic_info_update(void)
264{
265 g_os_statistic_cnt++;
266}
267
268/*******************************************************************************
269* ¹¦ÄÜÃèÊö: ¶¨Ê±Æ÷»Øµ÷¹³×Ó
270* ²ÎÊý˵Ã÷:
271* (´«Èë²ÎÊý)
272* (´«³ö²ÎÊý) void
273* ·µ »Ø Öµ: void
274* ÆäËü˵Ã÷: ÎÞ
275*******************************************************************************/
276static int os_statistic_delayed_work_timer_fn(unsigned long data)
277{
278 int sec = 0;
279 msleep(20000);
280 while(!os_statistic_check())
281 {
282 //³¬¹ý40s£¬Ö±½ÓÍ˳ö
283 if(sec >= 4)
284 return 0;
285 msleep(10000);
286 sec++;
287 }
288 os_statistic_enable();
289 return 0;
290}
291
292/*******************************************************************************
293* È«¾Öº¯ÊýʵÏÖ *
294*******************************************************************************/
295/*******************************************************************************
296* ¹¦ÄÜÃèÊö: ʹÄܹ켣ͳ¼Æ¹¦ÄÜ
297* ²ÎÊý˵Ã÷:
298* (´«Èë²ÎÊý) address: ¼Ç¼µ½IRAMÖеĵØÖ·
299 size: IRAM¿Õ¼ä´óС
300* (´«³ö²ÎÊý) void
301* ·µ »Ø Öµ: void
302* ÆäËü˵Ã÷: ÎÞ
303*******************************************************************************/
304void os_statistic_enable(void)
305{
306#if defined(_OS_TOS)
307 g_os_iram_swapin_statistic = (t_os_iram_thread_statistic *)OS_IRAM_THREAD_SWAPIN;
308 g_os_iram_irq_start_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_START;
309 g_os_iram_irq_end_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_END;
310 g_os_iram_dsr_start_statistic = (t_os_iram_statistic *)OS_IRAM_DSR_START;
311 g_os_iram_dsr_end_statistic = (t_os_iram_statistic *)OS_IRAM_DSR_END;
312
313 g_os_ddr_swapin_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
314 g_os_ddr_irq_start_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
315 g_os_ddr_irq_end_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
316 g_os_ddr_dsr_start_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
317 g_os_ddr_dsr_end_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
318#elif defined(_OS_LINUX)
319 g_os_iram_swapin_statistic = (t_os_iram_thread_statistic *)OS_IRAM_THREAD_SWAPIN;
320 g_os_iram_irq_start_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_START;
321 g_os_iram_irq_end_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_END;
322 g_os_iram_softirq_start_statistic = (t_os_iram_statistic *)OS_IRAM_SOFTIRQ_START;
323 g_os_iram_softirq_end_statistic = (t_os_iram_statistic *)OS_IRAM_SOFTIRQ_END;
324 g_os_iram_timer_start_statistic = (t_os_iram_statistic *)OS_IRAM_TIMER_START;
325 g_os_iram_timer_end_statistic = (t_os_iram_statistic *)OS_IRAM_TIMER_END;
326
327 g_os_ddr_swapin_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
328 g_os_ddr_irq_start_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
329 g_os_ddr_irq_end_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
330 g_os_ddr_softirq_start_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
331 g_os_ddr_softirq_end_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
332 g_os_ddr_timer_start_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
333 g_os_ddr_timer_end_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
334
335#else
336# error "unkown os"
337#endif
338 if ((unsigned int )g_os_iram_timer_end_statistic - (unsigned int )g_os_iram_swapin_statistic > (unsigned int )IRAM_BASE_LEN_OS_STATISTIC_PSCPU )
339 {
340 BUG();
341 }
342 g_os_statistic_enable = 1;
343}
344EXPORT_SYMBOL(os_statistic_enable);
345
346void zxic_trace_task_switch(struct task_struct *next)
347{
348 unsigned long time;
349 if (!g_os_statistic_enable)
350 return ;
351
352 time = OS_STATISTIC_TIME;
353 os_statistic_thread_in_iram(g_os_iram_swapin_statistic, next, time);
354 os_statistic_in_ddr(g_os_ddr_swapin_statistic, next, time);
355 os_statistic_info_update();
356}
357
358void zxic_trace_irq_enter(u32 irq)
359{
360 unsigned long time;
361 if (!g_os_statistic_enable)
362 return ;
363
364 time = OS_STATISTIC_TIME;
365 os_statistic_in_iram(g_os_iram_irq_start_statistic, irq, time);
366 os_statistic_in_ddr(g_os_ddr_irq_start_statistic, irq, time);
367 os_statistic_info_update();
368}
369
370void zxic_trace_irq_exit(u32 irq)
371{
372 unsigned long time;
373 if (!g_os_statistic_enable)
374 return ;
375
376 time = OS_STATISTIC_TIME;
377 os_statistic_in_iram(g_os_iram_irq_end_statistic, irq, time);
378 os_statistic_in_ddr(g_os_ddr_irq_end_statistic, irq, time);
379 os_statistic_info_update();
380}
381
382void zxic_trace_softirq_enter(u32 vec_nr)
383{
384 unsigned long time;
385 if (!g_os_statistic_enable)
386 return ;
387
388 time = OS_STATISTIC_TIME;
389 os_statistic_in_iram(g_os_iram_softirq_start_statistic, vec_nr, time);
390 os_statistic_in_ddr(g_os_ddr_softirq_start_statistic, vec_nr, time);
391 os_statistic_info_update();
392}
393
394void zxic_trace_softirq_exit(u32 vec_nr)
395{
396 unsigned long time;
397 if (!g_os_statistic_enable)
398 return ;
399
400 time = OS_STATISTIC_TIME;
401 os_statistic_in_iram(g_os_iram_softirq_end_statistic, vec_nr, time);
402 os_statistic_in_ddr(g_os_ddr_softirq_end_statistic, vec_nr, time);
403 os_statistic_info_update();
404}
405
406void zxic_trace_timer_enter(void *func)
407{
408 unsigned long time;
409 if (!g_os_statistic_enable)
410 return ;
411
412 time = OS_STATISTIC_TIME;
413 os_statistic_in_iram(g_os_iram_timer_start_statistic, func, time);
414 os_statistic_in_ddr(g_os_ddr_timer_start_statistic, func, time);
415 os_statistic_info_update();
416}
417
418void zxic_trace_timer_exit(void *func)
419{
420 unsigned long time;
421 if (!g_os_statistic_enable)
422 return ;
423
424 time = OS_STATISTIC_TIME;
425 os_statistic_in_iram(g_os_iram_timer_end_statistic, func, time);
426 os_statistic_in_ddr(g_os_ddr_timer_end_statistic, func, time);
427 os_statistic_info_update();
428}
xf.li6b423c72025-03-14 00:07:42 -0700429/*
430reason: 1 for ramdump, 2 for reboot
431cpu: ap/cap/rpm/phy
432app: current->comm
433*/
434/* Started by AICoder, pid:pf139dce4f7776c149ec081b508bae14e6084ede */
435void zxic_reset_reason(int reason, const char *cpu, const char *app)
436{
437 char buffer[32];
xf.lied996a22025-03-13 23:49:05 -0700438
xf.li6b423c72025-03-14 00:07:42 -0700439 memset(buffer, 0, sizeof(buffer));
440 switch (reason)
441 {
442 case 1:
443 snprintf(buffer, 32, "reset_ramdump_%s_%s", cpu, app);
444 memcpy(g_os_reset_reason->ramdump_reason, buffer, sizeof(buffer));
445 break;
446 case 2:
447 snprintf(buffer, 32, "reset_kreboot_%s_%s", cpu, app);
448 memcpy(g_os_reset_reason->kernel_reboot, buffer, sizeof(buffer));
449 break;
450 default:
451 break;
452 }
453}
454/* Ended by AICoder, pid:pf139dce4f7776c149ec081b508bae14e6084ede */
xf.lied996a22025-03-13 23:49:05 -0700455
456/*******************************************************************************
457* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½DDR
458* ²ÎÊý˵Ã÷:
459* (´«Èë²ÎÊý) iram_addr: µØÖ·
460 data: ʼþÏî
461 time: ʱ¼ä
462* (´«³ö²ÎÊý) void
463* ·µ »Ø Öµ: void
464* ÆäËü˵Ã÷: ÎÞ
465*******************************************************************************/
466int __init zxic_enable_tracer(void)
467{
468 struct timer_list timer;
469 struct task_struct *task;
470
471#ifdef IRAM_BASE_ADDR_VA
472 g_zxic_trace_apcpu_addr = IRAM_BASE_ADDR_OS_STATISTIC_PSCPU;
473#else
xf.li6b423c72025-03-14 00:07:42 -0700474 g_zxic_trace_apcpu_addr = ioremap(IRAM_BASE_ADDR_OS_STATISTIC_PSCPU, IRAM_BASE_LEN_OS_STATISTIC_PSCPU + IRAM_BASE_LEN_OS_STATISTIC_PHYCPU + IRAM_BASE_LEN_OS_STATISTIC_APCPU);
xf.lied996a22025-03-13 23:49:05 -0700475#endif
476
xf.li6b423c72025-03-14 00:07:42 -0700477 g_os_reset_reason = (T_Reset_Reason *)OS_IRAM_RESET_REASON_START;
xf.lied996a22025-03-13 23:49:05 -0700478 /*
479 init_timer(&timer);
480 timer.expires = jiffies + 40*HZ;//msecs_to_jiffies(40*1000);//ÑÓ³Ù40Ãë
481 timer.data = 0;
482 timer.function = os_statistic_delayed_work_timer_fn;
483 setup_timer(&timer, os_statistic_delayed_work_timer_fn, 0);
484 add_timer(&timer);
485 */
486 //task = kthread_create(os_statistic_delayed_work_timer_fn, 0, "g_zxic_trace_sync_thread", 0);
487 //wake_up_process(task);
488 os_statistic_enable();
489 return 0x0;
490}
491module_init(zxic_enable_tracer);
492
493