unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / infra / v2_0 / src / buffer.cxx
1 //==========================================================================
2 //
3 //      buffer.cxx
4 //
5 //      Memory buffered trace and assert 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
45 // Date:        1998-10-16
46 // Purpose:     Buffered Trace and assert functions
47 // Description: The functions in this file are a buffered implementation
48 //              of the standard trace and assert functions. These store
49 //              trace messages in a memory buffer and emit them when an
50 //              assert is hit, or when requested to.
51 //
52 //####DESCRIPTIONEND####
53 //
54 //==========================================================================
55
56 #include <pkgconf/system.h>
57 #include <pkgconf/infra.h>
58
59 #ifdef CYGDBG_INFRA_DEBUG_TRACE_ASSERT_BUFFER
60
61 #include <cyg/infra/cyg_type.h>         // base types
62 #include <cyg/infra/cyg_trac.h>         // tracing macros
63 #include <cyg/infra/cyg_ass.h>          // assertion macros
64
65 #include <pkgconf/hal.h>                // HAL configury
66 #include <cyg/infra/diag.h>             // HAL polled output
67 #include <cyg/hal/hal_arch.h>           // architectural stuff for...
68 #include <cyg/hal/hal_intr.h>           // interrupt control
69
70 #ifdef CYGPKG_KERNEL
71 #include <pkgconf/kernel.h>             // kernel configury
72 #include <cyg/kernel/thread.hxx>        // thread id to print
73 #include <cyg/kernel/sched.hxx>         // ancillaries for above
74 #include <cyg/kernel/thread.inl>        // ancillaries for above
75 #endif
76
77 // -------------------------------------------------------------------------
78 // Local Configuration: hack me!
79
80 // these are generally:
81 //      if 0, feature is disabled
82 //      if 1, feature is enabled, printing is default width
83 //      if >1, field is padded up to that width if necessary
84 //              (not truncated ever)
85
86 #define CYG_FILENAME    20
87 #define CYG_THREADID    1
88 #define CYG_LINENUM     4
89 #define CYG_FUNCNAME    100
90 #define CYG_DIAG_PRINTF 1
91 #define CYG_FUNC_INDENT 2
92
93 #ifndef CYGPKG_KERNEL
94 # undef  CYG_THREADID
95 # define CYG_THREADID 0
96 #endif
97
98 #if CYG_FUNCNAME == 1
99 #define CYG_FBUF_SIZE   100
100 #else
101 #define CYG_FBUF_SIZE   (CYG_FUNCNAME+20)
102 #endif
103
104 // -------------------------------------------------------------------------
105 // Trace buffer
106
107 #ifdef CYGDBG_USE_TRACING
108
109 struct Cyg_TraceRecord
110 {
111     cyg_uint32          what;
112     cyg_uint32          tid;
113     const char          *function;
114     const char          *file;
115     const char          *message;
116     cyg_uint32          line;
117     cyg_uint32          narg;
118     CYG_ADDRWORD        arg[8];
119 };
120
121 Cyg_TraceRecord cyg_infra_trace_buffer[CYGDBG_INFRA_DEBUG_TRACE_BUFFER_SIZE];
122
123 static cyg_uint32 cyg_infra_trace_buffer_pos = 0;
124
125 static cyg_bool cyg_infra_trace_buffer_enable = true;
126
127 static cyg_bool cyg_infra_trace_buffer_wrap = false;
128
129 // -------------------------------------------------------------------------
130 // Functions to trim file names and function names down to printable lengths
131 // (these are shared between trace and assert functions)
132
133 #if 0
134 static const char *tracepremsgs[] = {
135     "  INFO:",
136     "ENTER :",
137     "ARGS  :",
138     "RETURN:",
139     "bad code"
140 };
141 #endif
142
143 static const char *tracepremsgs[] = {
144     "'",
145     "{{",
146     "((",
147     "}}",
148     "bad code"
149 };
150
151 static const char *tracepostmsgs[] = {
152     "'",
153     "",
154     "))",
155     "",
156     "bad code"
157 };
158
159 static void
160 write_whattrace( cyg_uint32 what )
161 {
162 #if CYG_FUNC_INDENT
163     static cyg_int32 cyg_indent = 0;
164     if ( 3 == what )
165         cyg_indent -= CYG_FUNC_INDENT;
166     cyg_int32 i = cyg_indent;
167     for ( ; i > 0; i-- )
168         diag_write_string( " " );
169 #endif // CYG_FUNC_INDENT
170     diag_write_string( tracepremsgs[ what > 4 ? 4 : what ] );
171 #if CYG_FUNC_INDENT
172     if ( 1 == what )
173         cyg_indent += CYG_FUNC_INDENT;
174 #endif // CYG_FUNC_INDENT
175 }
176
177 static void
178 write_whattracepost( cyg_uint32 what )
179 {
180     diag_write_string( tracepostmsgs[ what > 4 ? 4 : what ] );
181 }
182
183
184 #endif // CYGDBG_USE_TRACING
185
186 // -------------------------------------------------------------------------
187
188 #if defined(CYGDBG_USE_TRACING) || defined(CYGDBG_USE_ASSERTS)
189
190 static const char *trim_file(const char *file)
191 {
192 #if CYG_FILENAME
193     if ( NULL == file )
194         file = "<nofile>";
195
196 #if 1 == CYG_FILENAME
197     const char *f = file;
198     while( *f ) f++;
199     while( *f != '/' && f != file ) f--;
200     return f==file?f:(f+1);
201 #else
202     static char fbuf2[100];
203     const char *f = file;
204     char *g = fbuf2;
205     while( *f ) f++;
206     while( *f != '/' && f != file ) f--;
207     if ( f > file ) f++;
208     while( *f ) *g++ = *f++;
209     while( CYG_FILENAME > (g - fbuf2) ) *g++ = ' ';
210     *g = 0;
211     return fbuf2;
212 #endif
213 #else
214     return "";
215 #endif
216 }
217
218 static const char *trim_func(const char *func)
219 {
220 #if CYG_FUNCNAME
221     static char fbuf[CYG_FBUF_SIZE];
222     cyg_count32 i;
223     
224     if ( NULL == func )
225         func = "<nofunc>";
226
227     for( i = 0; func[i] && func[i] != '(' && i < CYG_FBUF_SIZE-4 ; i++ )
228         fbuf[i] = func[i];
229
230     fbuf[i++] = '(';
231     fbuf[i++] = ')';
232     fbuf[i  ] = 0;
233     i=0;
234 #if 1 == CYG_FUNCNAME
235     return &fbuf[i];
236 #else
237     char *p = &fbuf[i];
238     while ( *p ) p++;
239     while ( CYG_FUNCNAME > (p - (&fbuf[i])) ) *p++ = ' ';    
240     *p = 0;
241     return &fbuf[i];
242 #endif
243 #else
244     return "";
245 #endif
246 }
247
248 static void write_lnum( cyg_uint32 lnum)
249 {
250 #if CYG_LINENUM
251     diag_write_char('[');
252 #if 1 < CYG_LINENUM
253     cyg_uint32 i, j;
254     for ( i = 2, j = 100; i < CYG_LINENUM ; i++, j *= 10 )
255         if ( lnum < j )
256             diag_write_char(' ');
257 #endif    
258     diag_write_dec(lnum);
259     diag_write_char(']');
260     diag_write_char(' ');
261 #endif
262 }
263
264 #endif // defined(CYGDBG_USE_TRACING) || defined(CYGDBG_USE_ASSERTS)
265
266 // -------------------------------------------------------------------------
267
268 #if defined(CYGDBG_USE_TRACING) || defined(CYGDBG_USE_ASSERTS)
269
270 #if CYG_THREADID
271 static cyg_uint32 get_tid(void)
272 {
273     
274     Cyg_Thread *t = Cyg_Thread::self();
275     cyg_uint16 tid = 0xFFFF;
276
277     if( t != NULL ) tid = t->get_unique_id();
278
279     return tid;
280 }
281 #else
282 # define get_tid() (0xFFFF)
283 #endif
284
285 #endif // defined(CYGDBG_USE_TRACING) || defined(CYGDBG_USE_ASSERTS)
286
287 #ifdef CYGDBG_USE_ASSERTS
288 static void write_thread_id()
289 {
290 #if CYG_THREADID    
291     cyg_uint16 tid = get_tid();
292
293     diag_write_char('<');
294     diag_write_hex(tid);
295     diag_write_char('>');
296 #endif
297 }
298 #endif
299
300 // -------------------------------------------------------------------------
301 // Trace functions:
302
303 #ifdef CYGDBG_USE_TRACING
304
305 static void print_trace_buffer(void)
306 {
307     cyg_count32 start = cyg_infra_trace_buffer_pos;
308     cyg_count32 end = start;
309     cyg_count32 i;
310
311     // If the buffer has wrapped we want to display the records from
312     // the current pos and around back to the same place. If the buffer
313     // has not wrapped, we want to display from the start to pos.
314     
315     if( !cyg_infra_trace_buffer_wrap )
316         start = 0;
317
318     i = start;
319     do
320     {
321         Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[i];
322         cyg_uint32 old_ints;
323
324         const char *psz_msg = rec->message;
325         
326
327         HAL_DISABLE_INTERRUPTS(old_ints);
328         DIAG_DEVICE_START_SYNC();
329
330         if ( NULL == psz_msg )
331             psz_msg = "<nomsg>";
332
333         diag_write_string( "TRACE: " );
334 #if CYG_THREADID
335         diag_write_char('<');
336         diag_write_hex(rec->tid);
337         diag_write_char('>');
338 #endif        
339         diag_write_string(trim_file(rec->file));
340         write_lnum(rec->line);
341         diag_write_string(trim_func(rec->function));
342         diag_write_char(' ');
343         write_whattrace( rec->what );
344 #if CYG_DIAG_PRINTF
345         diag_printf( psz_msg,
346                      rec->arg[0], rec->arg[1],
347                      rec->arg[2], rec->arg[3],
348                      rec->arg[4], rec->arg[5],
349                      rec->arg[6], rec->arg[7] );
350 #else
351         diag_write_string(psz_msg);
352         diag_write_char(' ');
353
354         for( cyg_count8 j = 0; j < rec->narg ; j++ )
355         {
356             diag_write_hex(rec->arg[j]);
357             diag_write_char(' ');
358         }
359 #endif    
360         write_whattracepost( rec->what );
361         diag_write_char('\n');    
362
363         DIAG_DEVICE_END_SYNC();
364         HAL_RESTORE_INTERRUPTS(old_ints);
365
366         i++;
367         if( i == CYGDBG_INFRA_DEBUG_TRACE_BUFFER_SIZE )
368             i = 0;
369         
370     } while( i != end );
371
372 }    
373
374 static void increment_buffer_pos()
375 {
376     cyg_infra_trace_buffer_pos++;
377     
378     if( cyg_infra_trace_buffer_pos == CYGDBG_INFRA_DEBUG_TRACE_BUFFER_SIZE )
379     {
380 #if defined(CYGDBG_INFRA_DEBUG_TRACE_BUFFER_WRAP)
381         cyg_infra_trace_buffer_pos = 0;
382         cyg_infra_trace_buffer_wrap = true;
383 #elif defined(CYGDBG_INFRA_DEBUG_TRACE_BUFFER_HALT)
384         cyg_infra_trace_buffer_enable = false;
385 #elif defined(CYGDBG_INFRA_DEBUG_TRACE_BUFFER_PRINT)
386         cyg_infra_trace_buffer_pos = 0;
387         print_trace_buffer();
388 #else
389 #error No trace buffer full mode set
390 #endif
391     }
392
393 }
394
395 // -------------------------------------------------------------------------
396
397 externC void
398 cyg_tracenomsg( const char *psz_func, const char *psz_file, cyg_uint32 linenum )
399 {
400     cyg_uint32 old_ints;
401
402     if( !cyg_infra_trace_buffer_enable ) return;
403     
404     HAL_DISABLE_INTERRUPTS(old_ints);
405
406     Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos];
407
408     rec->what           = 0;
409     rec->tid            = get_tid();
410     rec->function       = psz_func;
411     rec->file           = psz_file;
412     rec->line           = linenum;
413     rec->message        = 0;
414     rec->narg           = 0;
415
416     increment_buffer_pos();
417     
418     HAL_RESTORE_INTERRUPTS(old_ints);
419     
420 };
421
422 // provide every other one of these as a space/caller bloat compromise.
423
424 externC void
425 cyg_tracemsg( cyg_uint32 what, 
426               const char *psz_func, const char *psz_file, cyg_uint32 linenum,
427               const char *psz_msg )
428 {
429     cyg_uint32 old_ints;
430
431     if( !cyg_infra_trace_buffer_enable ) return;
432
433     HAL_DISABLE_INTERRUPTS(old_ints);
434
435     Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos];
436
437     rec->what           = what;    
438     rec->tid            = get_tid();
439     rec->function       = psz_func;
440     rec->file           = psz_file;
441     rec->line           = linenum;
442     rec->message        = psz_msg;
443     rec->narg           = 0;
444
445     increment_buffer_pos();
446
447     HAL_RESTORE_INTERRUPTS(old_ints);
448
449 };
450
451 externC void
452 cyg_tracemsg2( cyg_uint32 what, 
453                const char *psz_func, const char *psz_file, cyg_uint32 linenum,
454                const char *psz_msg,
455                CYG_ADDRWORD arg0,  CYG_ADDRWORD arg1 )
456 {
457     cyg_uint32 old_ints;
458
459     if( !cyg_infra_trace_buffer_enable ) return;
460
461     HAL_DISABLE_INTERRUPTS(old_ints);
462
463     Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos];
464
465     rec->what           = what;    
466     rec->tid            = get_tid();
467     rec->function       = psz_func;
468     rec->file           = psz_file;
469     rec->line           = linenum;
470     rec->message        = psz_msg;
471     rec->narg           = 2;
472
473     rec->arg[0]         = arg0;
474     rec->arg[1]         = arg1;
475     
476     increment_buffer_pos();
477     
478     HAL_RESTORE_INTERRUPTS(old_ints);
479 };
480
481 externC void
482 cyg_tracemsg4( cyg_uint32 what, 
483                const char *psz_func, const char *psz_file, cyg_uint32 linenum,
484                const char *psz_msg,
485                CYG_ADDRWORD arg0,  CYG_ADDRWORD arg1,
486                CYG_ADDRWORD arg2,  CYG_ADDRWORD arg3 )
487 {
488     cyg_uint32 old_ints;
489
490     if( !cyg_infra_trace_buffer_enable ) return;
491
492     HAL_DISABLE_INTERRUPTS(old_ints);
493
494     Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos];
495
496     rec->what           = what;    
497     rec->tid            = get_tid();
498     rec->function       = psz_func;
499     rec->file           = psz_file;
500     rec->line           = linenum;
501     rec->message        = psz_msg;
502     rec->narg           = 4;
503
504     rec->arg[0]         = arg0;
505     rec->arg[1]         = arg1;
506     rec->arg[2]         = arg2;
507     rec->arg[3]         = arg3;
508     
509     increment_buffer_pos();
510     
511     HAL_RESTORE_INTERRUPTS(old_ints);
512 };
513
514 externC void
515 cyg_tracemsg6( cyg_uint32 what, 
516                const char *psz_func, const char *psz_file, cyg_uint32 linenum,
517                const char *psz_msg,
518                CYG_ADDRWORD arg0,  CYG_ADDRWORD arg1,
519                CYG_ADDRWORD arg2,  CYG_ADDRWORD arg3,
520                CYG_ADDRWORD arg4,  CYG_ADDRWORD arg5 )
521 {
522     cyg_uint32 old_ints;
523
524     if( !cyg_infra_trace_buffer_enable ) return;
525
526     HAL_DISABLE_INTERRUPTS(old_ints);
527
528     Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos];
529
530     rec->what           = what;    
531     rec->tid            = get_tid();
532     rec->function       = psz_func;
533     rec->file           = psz_file;
534     rec->line           = linenum;
535     rec->message        = psz_msg;
536     rec->narg           = 6;
537
538     rec->arg[0]         = arg0;
539     rec->arg[1]         = arg1;
540     rec->arg[2]         = arg2;
541     rec->arg[3]         = arg3;
542     rec->arg[4]         = arg4;
543     rec->arg[5]         = arg5;
544     
545     increment_buffer_pos();
546     
547     HAL_RESTORE_INTERRUPTS(old_ints);
548 };
549
550 externC void
551 cyg_tracemsg8( cyg_uint32 what, 
552                const char *psz_func, const char *psz_file, cyg_uint32 linenum,
553                const char *psz_msg,
554                CYG_ADDRWORD arg0,  CYG_ADDRWORD arg1,
555                CYG_ADDRWORD arg2,  CYG_ADDRWORD arg3,
556                CYG_ADDRWORD arg4,  CYG_ADDRWORD arg5,
557                CYG_ADDRWORD arg6,  CYG_ADDRWORD arg7 )
558 {
559     cyg_uint32 old_ints;
560
561     if( !cyg_infra_trace_buffer_enable ) return;
562
563     HAL_DISABLE_INTERRUPTS(old_ints);
564
565     Cyg_TraceRecord *rec = &cyg_infra_trace_buffer[cyg_infra_trace_buffer_pos];
566
567     rec->what           = what;    
568     rec->tid            = get_tid();
569     rec->function       = psz_func;
570     rec->file           = psz_file;
571     rec->line           = linenum;
572     rec->message        = psz_msg;
573     rec->narg           = 6;
574
575     rec->arg[0]         = arg0;
576     rec->arg[1]         = arg1;
577     rec->arg[2]         = arg2;
578     rec->arg[3]         = arg3;
579     rec->arg[4]         = arg4;
580     rec->arg[5]         = arg5;
581     rec->arg[6]         = arg6;
582     rec->arg[7]         = arg7;
583     
584     increment_buffer_pos();
585     
586     HAL_RESTORE_INTERRUPTS(old_ints);
587 };
588
589 // -------------------------------------------------------------------------
590
591 externC void
592 cyg_trace_print(void)
593 {
594     cyg_bool old_enable = cyg_infra_trace_buffer_enable;
595     cyg_infra_trace_buffer_enable = false;
596     print_trace_buffer();
597     cyg_infra_trace_buffer_pos = 0;
598     cyg_infra_trace_buffer_wrap = false;
599     cyg_infra_trace_buffer_enable = old_enable;
600 }
601
602
603 // -------------------------------------------------------------------------
604
605 externC void
606 cyg_trace_dump(void)
607 {
608 #if defined(CYGPKG_KERNEL) && defined(CYG_DIAG_PRINTF)
609
610     {
611         diag_printf("\nScheduler:\n\n");
612
613         Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler;
614
615         diag_printf("Lock:                %d\n",sched->get_sched_lock() );
616
617 # ifdef CYGVAR_KERNEL_THREADS_NAME
618     
619         diag_printf("Current Thread:      %s\n",sched->get_current_thread()->get_name());
620
621 # else
622
623         diag_printf("Current Thread:    %d\n",sched->get_current_thread()->get_unique_id());
624     
625 # endif
626
627     }
628     
629 # ifdef CYGVAR_KERNEL_THREADS_LIST
630
631     {
632         Cyg_Thread *t = Cyg_Thread::get_list_head();
633
634         diag_printf("\nThreads:\n\n");
635     
636         while( NULL != t )
637         {
638             cyg_uint32 state = t->get_state();
639             char tstate[7];
640             char *tstate1 = "SCUKX";
641             static char *(reasons[8]) =
642             {
643                 "NONE",                           // No recorded reason
644                 "WAIT",                           // Wait with no timeout
645                 "DELAY",                          // Simple time delay
646                 "TIMEOUT",                        // Wait with timeout/timeout expired
647                 "BREAK",                          // forced break out of sleep
648                 "DESTRUCT",                       // wait object destroyed[note]
649                 "EXIT",                           // forced termination
650                 "DONE"                            // Wait/delay complete
651             };
652
653             if( 0 != state )
654             {
655                 // Knock out chars that do not correspond to set bits.
656                 for( int i = 0; i < 6 ; i++ )
657                     if( 0 == (state & (1<<i)) )
658                         tstate[i] = ' ';
659                     else tstate[i] = tstate1[i];
660                 tstate[6] = 0;
661             }
662             else tstate[0] = 'R', tstate[1] = 0;
663
664 #   ifdef CYGVAR_KERNEL_THREADS_NAME
665         
666             diag_printf( "%20s pri = %3d state = %6s id = %3d\n",
667                          t->get_name(),
668                          t->get_priority(),
669                          tstate,
670                          t->get_unique_id()
671                 );
672 #   else
673
674             diag_printf( "Thread %3d        pri = %3d state = %6s\n",
675                          t->get_unique_id(),
676                          t->get_priority(),
677                          tstate
678                 );
679
680 #   endif        
681             diag_printf( "%20s stack base = %08x ptr = %08x size = %08x\n",
682                          "",
683                          t->get_stack_base(),
684 #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
685                          t->get_saved_context(),
686 #else
687                          0,
688 #endif
689                          t->get_stack_size()
690                 );
691
692             diag_printf( "%20s sleep reason %8s wake reason %8s\n",
693                          "",
694                          reasons[t->get_sleep_reason()],
695                          reasons[t->get_wake_reason()]
696                 );
697
698             diag_printf( "%20s queue = %08x      wait info = %08x\n",
699                          "",
700                          t->get_current_queue(),
701                          t->get_wait_info()
702                          );
703
704             diag_printf("\n");
705             t = t->get_list_next();
706         }
707
708     }
709 # endif // CYGVAR_KERNEL_THREADS_LIST
710     
711 #endif // CYG_DIAG_PRINTF
712 }
713
714 #endif // CYGDBG_USE_TRACING
715
716 // -------------------------------------------------------------------------
717 // Assert functions:
718
719 #ifdef CYGDBG_USE_ASSERTS
720
721 externC void
722 cyg_assert_fail( const char *psz_func, const char *psz_file,
723                  cyg_uint32 linenum, const char *psz_msg ) __THROW
724 {
725     cyg_uint32 old_ints;
726
727     HAL_DISABLE_INTERRUPTS(old_ints);
728     DIAG_DEVICE_START_SYNC();
729
730     diag_write_string("ASSERT FAIL: ");
731     write_thread_id();
732     diag_write_string(trim_file(psz_file));
733     write_lnum(linenum);
734     diag_write_string(trim_func(psz_func));
735     diag_write_char(' ');
736     diag_write_string(psz_msg);
737     diag_write_char('\n');
738
739 #ifdef CYGDBG_INFRA_DEBUG_TRACE_BUFFER_PRINT_ON_ASSERT
740
741     cyg_trace_print();
742     cyg_trace_dump();
743
744 #endif
745     
746 #ifdef CYGHWR_TEST_PROGRAM_EXIT
747     CYGHWR_TEST_PROGRAM_EXIT();
748 #endif
749     for(;;);
750     
751 //    DIAG_DEVICE_END_SYNC();
752 //    HAL_RESTORE_INTERRUPTS(old_ints);
753 };
754
755 extern "C"
756 {
757 extern unsigned long _stext;
758 extern unsigned long _etext;
759
760 unsigned long stext_addr = (unsigned long)&_stext;
761 unsigned long etext_addr = (unsigned long)&_etext;
762 };
763
764 externC cyg_bool cyg_check_data_ptr(const void *ptr)
765 {
766     unsigned long p = (unsigned long)ptr;
767     
768     if( p == 0 ) return false;
769
770     if( p > stext_addr && p < etext_addr ) return false;
771
772     return true;
773 }
774
775 externC cyg_bool cyg_check_func_ptr(void (*ptr)(void))
776 {
777     unsigned long p = (unsigned long)ptr;
778     
779     if( p == 0 ) return false;
780
781     if( p < stext_addr && p > etext_addr ) return false;
782
783     return true;
784 }
785
786 #endif // CYGDBG_USE_ASSERTS
787
788 #endif // CYGDBG_INFRA_DEBUG_TRACE_ASSERT_BUFFER
789
790 // -------------------------------------------------------------------------
791 // EOF buffer.cxx