]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/kernel/v2_0/src/instrmnt/meminst.cxx
dd86748bd4ad0e2be7cd6ff31e15bc4e069cb4bd
[karo-tx-redboot.git] / packages / kernel / v2_0 / src / instrmnt / meminst.cxx
1 //==========================================================================
2 //
3 //      instrmnt/meminst.cxx
4 //
5 //      Memory buffer instrumentation functions
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):   nickg
44 // Contributors: nickg, andrew.lunn@ascom.ch
45 // Date:        1997-10-27
46 // Purpose:     Instrumentation functions
47 // Description: The functions in this file are implementations of the
48 //              standard instrumentation functions that place records
49 //              into a memory buffer.
50 //
51 //####DESCRIPTIONEND####
52 //
53 //==========================================================================
54
55 #include <pkgconf/kernel.h>
56
57 #include <cyg/kernel/ktypes.h>         // base kernel types
58 #include <cyg/infra/cyg_trac.h>        // tracing macros
59 #include <cyg/infra/cyg_ass.h>         // assertion macros
60 #include <cyg/kernel/instrmnt.h>       // instrumentation
61
62 #include <cyg/kernel/intr.hxx>         // interrupt control
63 #include <cyg/kernel/sched.hxx>        // scheduler defines
64
65 #include <cyg/kernel/sched.inl>        // scheduler inlines
66 #include <cyg/kernel/clock.inl>        // clock inlines
67
68 #ifdef CYGPKG_KERNEL_INSTRUMENT
69
70 // -------------------------------------------------------------------------
71 // Instrumentation record.
72
73 struct Instrument_Record
74 {
75     CYG_WORD16  type;                   // record type
76     CYG_WORD16  thread;                 // current thread id
77     CYG_WORD    timestamp;              // 32 bit timestamp
78     CYG_WORD    arg1;                   // first arg
79     CYG_WORD    arg2;                   // second arg
80 };
81
82 // -------------------------------------------------------------------------
83 // Buffer base and end. This buffer must be a whole number of 
84
85 #ifdef CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
86
87 externC Instrument_Record       instrument_buffer[];
88 externC cyg_uint32              instrument_buffer_size;
89
90 #else
91
92 extern "C"
93 {
94     
95 Instrument_Record       instrument_buffer[CYGNUM_KERNEL_INSTRUMENT_BUFFER_SIZE];
96    
97 cyg_uint32              instrument_buffer_size = CYGNUM_KERNEL_INSTRUMENT_BUFFER_SIZE;
98     
99 };
100
101 #endif
102
103 extern "C"
104 {
105
106 #define instrument_buffer_start instrument_buffer[0]
107 #define instrument_buffer_end   instrument_buffer[instrument_buffer_size]
108
109 extern "C"
110 {
111 Instrument_Record       *instrument_buffer_pointer = &instrument_buffer_start;
112 };
113
114 #ifdef CYGDBG_KERNEL_INSTRUMENT_FLAGS
115
116 // This array contains a 32 bit word for each event class. The
117 // bits in the word correspond to events. By setting or clearing
118 // the appropriate bit, the selected instrumentation event may
119 // be enabled or disabled dynamically.
120     
121 cyg_uint32 instrument_flags[(CYG_INSTRUMENT_CLASS_MAX>>8)+1];
122     
123 #endif
124     
125 };
126
127 // -------------------------------------------------------------------------
128
129 #ifdef CYGPKG_KERNEL_SMP_SUPPORT
130
131 HAL_SPINLOCK_TYPE instrument_lock = HAL_SPINLOCK_INIT_CLEAR;
132
133 #else
134
135 #define HAL_SPINLOCK_SPIN( __lock )
136
137 #define HAL_SPINLOCK_CLEAR( __lock )
138
139 #endif
140
141 // -------------------------------------------------------------------------
142
143 void cyg_instrument( cyg_uint32 type, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2 )
144 {
145
146     cyg_uint32 old_ints;
147
148 #ifdef CYGDBG_KERNEL_INSTRUMENT_FLAGS    
149     
150     cyg_ucount8 cl = (type>>8)&0xff;
151     cyg_ucount8 event = type&0xff;
152
153     if( instrument_flags[cl] & (1<<event) )
154 #endif        
155     {
156         HAL_DISABLE_INTERRUPTS(old_ints);
157         HAL_SPINLOCK_SPIN( instrument_lock );
158         
159         Instrument_Record *p = instrument_buffer_pointer;
160         Cyg_Thread *t = Cyg_Scheduler::get_current_thread();
161         p->type             = type;
162         p->thread           = (t==0)?0x0FFF:t->get_unique_id();
163 #ifdef CYGPKG_KERNEL_SMP_SUPPORT
164         // Add CPU id to in top 4 bytes of thread id
165         p->thread           = (p->thread&0x0FFF)|(CYG_KERNEL_CPU_THIS()<<12);
166 #endif        
167 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK        
168 //        p->timestamp        = Cyg_Clock::real_time_clock->current_value_lo();
169         HAL_CLOCK_READ( &p->timestamp );
170 #else
171         p->timestamp        = 0;
172 #endif
173         p->arg1             = arg1;
174         p->arg2             = arg2;
175     
176         p++;
177 #ifdef CYGDBG_KERNEL_INSTRUMENT_BUFFER_WRAP
178         if( p == &instrument_buffer_end )
179             instrument_buffer_pointer = &instrument_buffer_start;
180         else instrument_buffer_pointer = p;
181 #else
182         // when not wrapping, just continue to put further entries
183         // in the last slot.
184         if( p != &instrument_buffer_end )
185             instrument_buffer_pointer = p;
186 #endif
187         HAL_SPINLOCK_CLEAR( instrument_lock );        
188         HAL_RESTORE_INTERRUPTS(old_ints);
189     }
190     
191     return;
192 }
193
194 // -------------------------------------------------------------------------
195 // Functions to enable and disable selected instrumentation events
196 // when the flags are enabled.
197
198 #ifdef CYGDBG_KERNEL_INSTRUMENT_FLAGS
199
200 externC void cyg_instrument_enable( cyg_uint32 cl, cyg_uint32 event)
201 {
202     if( 0 != event )
203         instrument_flags[cl>>8] |= 1<<event;
204     else
205         instrument_flags[cl>>8] = ~0;
206 }
207
208 externC void cyg_instrument_disable( cyg_uint32 cl, cyg_uint32 event)
209 {
210     if( 0 != event )
211         instrument_flags[cl>>8] &= ~(1<<event);
212     else
213         instrument_flags[cl>>8] = 0;
214
215 }
216
217 externC cyg_bool cyg_instrument_state( cyg_uint32 cl, cyg_uint32 event)
218 {
219     return (instrument_flags[cl>>8] & (1<<event)) != 0;
220 }
221
222 #endif
223
224 // -------------------------------------------------------------------------
225
226 #ifdef CYGDBG_KERNEL_INSTRUMENT_MSGS
227 #define CYGDBG_KERNEL_INSTRUMENT_MSGS_DEFINE_TABLE
228 #include <cyg/kernel/instrument_desc.h>
229 #define NELEM(x) (sizeof(x)/sizeof*(x))
230 externC char * cyg_instrument_msg(CYG_WORD16 type) {
231
232   struct instrument_desc_s *record;
233   struct instrument_desc_s *end_record;
234   CYG_WORD cl, event;
235
236   record = instrument_desc;
237   end_record = &instrument_desc[NELEM(instrument_desc)-1];
238   cl = type & 0xff00;
239   event = type & 0x00ff;
240
241   while ((record != end_record) && (record->num != cl)) {
242     record++;
243   }
244
245   if (record->num == cl) {
246     record++;
247     while ((record != end_record) && (record->num != event) &&
248            (record->num < 0xff)) {
249       record++;
250     }
251
252     if (record->num == event) {
253       return (record->msg);
254     }
255   }
256   return("Unknown event");
257 }
258 #endif // CYGDBG_KERNEL_INSTRUMENT_MSGS
259 #endif // CYGPKG_KERNEL_INSTRUMENT
260
261 // EOF instrmnt/meminst.cxx