| [1] | 1 | /* | 
|---|
 | 2 |  * kern/cpu-trace.h - Per-CPU, In-core trace system | 
|---|
 | 3 |  *  | 
|---|
 | 4 |  * Copyright (c) 2008,2009,2010,2011,2012 Ghassan Almaless | 
|---|
 | 5 |  * Copyright (c) 2011,2012 UPMC Sorbonne Universites | 
|---|
 | 6 |  * | 
|---|
 | 7 |  * This file is part of ALMOS-kernel. | 
|---|
 | 8 |  * | 
|---|
 | 9 |  * ALMOS-kernel is free software; you can redistribute it and/or modify it | 
|---|
 | 10 |  * under the terms of the GNU General Public License as published by | 
|---|
 | 11 |  * the Free Software Foundation; version 2.0 of the License. | 
|---|
 | 12 |  * | 
|---|
 | 13 |  * ALMOS-kernel is distributed in the hope that it will be useful, but | 
|---|
 | 14 |  * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
 | 15 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
 | 16 |  * General Public License for more details. | 
|---|
 | 17 |  * | 
|---|
 | 18 |  * You should have received a copy of the GNU General Public License | 
|---|
 | 19 |  * along with ALMOS-kernel; if not, write to the Free Software Foundation, | 
|---|
 | 20 |  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 
|---|
 | 21 |  */ | 
|---|
 | 22 |  | 
|---|
 | 23 | #ifndef _CPU_TRACE_H_ | 
|---|
 | 24 | #define _CPU_TRACE_H_ | 
|---|
 | 25 |  | 
|---|
 | 26 | #include <config.h> | 
|---|
 | 27 | #include <types.h> | 
|---|
 | 28 | #include <kdmsg.h> | 
|---|
 | 29 |  | 
|---|
 | 30 | /** Opaque CPU trace recorder */ | 
|---|
 | 31 | struct cpu_trace_recorder_s; | 
|---|
 | 32 |  | 
|---|
 | 33 | /** Write CPU trace information to current CPU recorder */ | 
|---|
 | 34 | #define cpu_trace_write(_cpu,func) | 
|---|
 | 35 |  | 
|---|
 | 36 | /** Dump CPU trace log to specified tty */ | 
|---|
 | 37 | static inline void cpu_trace_dump(struct cpu_s *cpu); | 
|---|
 | 38 |  | 
|---|
 | 39 |  | 
|---|
 | 40 | /////////////////////////////////////////////////////////////////////// | 
|---|
 | 41 | //                         Private Section                           // | 
|---|
 | 42 | /////////////////////////////////////////////////////////////////////// | 
|---|
 | 43 |  | 
|---|
 | 44 | #define CPU_TRACE_LOG_LENGTH      100 | 
|---|
 | 45 |  | 
|---|
 | 46 | /** Private trace info structure */ | 
|---|
 | 47 | typedef struct cpu_trace_info_s | 
|---|
 | 48 | { | 
|---|
 | 49 |         uint_t time_stamp; | 
|---|
 | 50 |         void *func_addr; | 
|---|
 | 51 |         uint_t stack_ptr; | 
|---|
 | 52 |         void *thread_ptr; | 
|---|
 | 53 |         uint_t line; | 
|---|
 | 54 | }cpu_trace_info_t; | 
|---|
 | 55 |  | 
|---|
 | 56 | /** Opaque CPU trace recorder */ | 
|---|
 | 57 | struct cpu_trace_recorder_s | 
|---|
 | 58 | { | 
|---|
 | 59 |         uint_t current_index; | 
|---|
 | 60 |         cpu_trace_info_t log[CPU_TRACE_LOG_LENGTH]; | 
|---|
 | 61 | }; | 
|---|
 | 62 |  | 
|---|
 | 63 |  | 
|---|
 | 64 | #if CONFIG_CPU_TRACE | 
|---|
 | 65 | #undef  cpu_trace_write | 
|---|
 | 66 | #define cpu_trace_write(_cpu,func)                                      \ | 
|---|
 | 67 |         do{{                                                            \ | 
|---|
 | 68 |                         uint_t state;                                   \ | 
|---|
 | 69 |                         cpu_disable_all_irq(&state);                    \ | 
|---|
 | 70 |                         cpu_trace_info_t *info = &(_cpu)->trace_recorder->log[(_cpu)->trace_recorder->current_index]; \ | 
|---|
 | 71 |                         info->time_stamp = cpu_time_stamp();            \ | 
|---|
 | 72 |                         info->func_addr  = (func);                      \ | 
|---|
 | 73 |                         info->stack_ptr  = cpu_get_stack();             \ | 
|---|
 | 74 |                         info->thread_ptr = cpu_get_current_thread();    \ | 
|---|
 | 75 |                         (_cpu)->trace_recorder->current_index = ((_cpu)->trace_recorder->current_index  + 1) % CPU_TRACE_LOG_LENGTH; \ | 
|---|
 | 76 |                         cpu_restore_irq(state);                         \ | 
|---|
 | 77 |                 }}while(0) | 
|---|
 | 78 |  | 
|---|
 | 79 | static inline void cpu_trace_dump(struct cpu_s *cpu) | 
|---|
 | 80 | { | 
|---|
 | 81 |         register uint_t i; | 
|---|
 | 82 |         register cpu_trace_info_t *info; | 
|---|
 | 83 |    | 
|---|
 | 84 |         except_dmsg("------------------------------------------\n"); | 
|---|
 | 85 |         except_dmsg("TRACE DUMP FOR CPU %d\n", cpu->gid); | 
|---|
 | 86 |  | 
|---|
 | 87 |         for(i=0; i < CPU_TRACE_LOG_LENGTH; i++) | 
|---|
 | 88 |         { | 
|---|
 | 89 |                 info = &cpu->trace_recorder->log[i]; | 
|---|
 | 90 |                 except_dmsg("Entry %d\n", i); | 
|---|
 | 91 |                 except_dmsg("\tTimeStamp %d\n\tFunction: %x\n\tLine %d\n\tStack %x\n\tThread %x\n", | 
|---|
 | 92 |                             info->time_stamp, info->func_addr, info->line, info->stack_ptr, info->thread_ptr); | 
|---|
 | 93 |         } | 
|---|
 | 94 |         except_dmsg("---> Current_index: %d\n", cpu->trace_recorder->current_index); | 
|---|
 | 95 | } | 
|---|
 | 96 |  | 
|---|
 | 97 | #else | 
|---|
 | 98 |  | 
|---|
 | 99 | #define cpu_trace_write(_cpu,func) | 
|---|
 | 100 |  | 
|---|
 | 101 | static inline void cpu_trace_dump(struct cpu_s *cpu) | 
|---|
 | 102 | { | 
|---|
 | 103 |         /* Nothing to do */ | 
|---|
 | 104 | } | 
|---|
 | 105 |  | 
|---|
 | 106 | #endif  /* CONFIG_CPU_TRACE */ | 
|---|
 | 107 |  | 
|---|
 | 108 | #endif  /* _CPU_TRACE_H_ */ | 
|---|