OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [language/] [c/] [libc/] [signals/] [v2_0/] [src/] [siginit.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//========================================================================
2
//
3
//      siginit.cxx
4
//
5
//      ISO C and POSIX 1003.1 signals implementation
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):     jlarmour
44
// Contributors:  
45
// Date:          2000-04-18
46
// Purpose:       Provide implementation of ISO C and POSIX 1003.1 signals
47
// Description:   This file initializes all hardware exceptions,
48
//                initializes the signal handler table and provides the
49
//                default action function for signals
50
// Usage:         
51
//
52
//####DESCRIPTIONEND####
53
//
54
//========================================================================
55
 
56
// CONFIGURATION
57
 
58
#include <pkgconf/libc_signals.h>  // libc signals configuration
59
 
60
// INCLUDES
61
 
62
#include <cyg/infra/cyg_type.h>    // Common type definitions and support
63
#include <signal.h>                // Main signals definitions
64
#include <cyg/infra/cyg_ass.h>     // Assertion infrastructure
65
#include <cyg/infra/cyg_trac.h>    // Tracing infrastructure
66
#include <stdlib.h>                // exit()
67
 
68
#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
69
# include <pkgconf/kernel.h>       // required for kernel includes
70
# include <cyg/kernel/except.hxx>  // Kernel exception API
71
# include <cyg/kernel/thread.hxx>  // Cyg_Thread::self()
72
# include <cyg/kernel/thread.inl>  // inline definitions for above
73
# include <cyg/kernel/intr.hxx>    // Interrupt enable
74
# include <cyg/hal/hal_intr.h>     // HAL interrupt control
75
#endif
76
 
77
#ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE
78
# include <pkgconf/kernel.h>       // required for kernel includes
79
# include <cyg/kernel/mutex.hxx>
80
#endif
81
 
82
// TYPE DEFINITIONS
83
 
84
// define dummy class to allow initialization of cyg_libc_signal_handlers
85
 
86
class Cyg_libc_signals_dummy_init_class {
87
public:
88
    Cyg_libc_signals_dummy_init_class();
89
};
90
 
91
#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
92
 
93
struct exception_signal_mapping_t {
94
    cyg_code exception;
95
    int signal;
96
};
97
 
98
// EXTERNS
99
 
100
extern cyg_exception_handler cyg_null_exception_handler;
101
 
102
#endif // ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
103
 
104
// GLOBALS
105
 
106
// main signal handlers
107
__sighandler_t cyg_libc_signal_handlers[CYGNUM_LIBC_SIGNALS];
108
 
109
#ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE
110
Cyg_Mutex cyg_libc_signal_handlers_mutex CYG_INIT_PRIORITY(LIBC);
111
#endif
112
 
113
// STATICS
114
 
115
// dummy object to invoke constructor
116
static Cyg_libc_signals_dummy_init_class
117
cyg_libc_signals_dummy_init_obj CYG_INIT_PRIORITY(LIBC);
118
 
119
#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
120
 
121
# ifdef CYGDBG_USE_TRACING
122
static cyg_uint8 cyg_libc_signals_hwhandler_trace_level =
123
  CYGNUM_LIBC_SIGNALS_HWHANDLER_TRACE_LEVEL;
124
# define TL1 (0 < cyg_libc_signals_hwhandler_trace_level)
125
# endif
126
 
127
# ifdef CYGSEM_LIBC_SIGNALS_CHAIN_HWEXCEPTIONS
128
// old exception info so we can chain
129
// FIXME: consider malloced linked list config option
130
static struct {
131
    cyg_exception_handler *old_handler;
132
    CYG_ADDRWORD old_data;
133
} exception_chain_data[CYGNUM_HAL_EXCEPTION_COUNT];
134
# endif
135
 
136
// struct that maps exceptions to signals
137
static const struct exception_signal_mapping_t
138
exception_signal_mapping[] = {
139
 
140
#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
141
    {CYGNUM_HAL_EXCEPTION_DATA_ACCESS, SIGBUS},
142
#endif
143
#ifdef CYGNUM_HAL_EXCEPTION_DATA_WRITE
144
    {CYGNUM_HAL_EXCEPTION_DATA_WRITE, SIGBUS},
145
#endif
146
#ifdef CYGNUM_HAL_EXCEPTION_CODE_ACCESS
147
    {CYGNUM_HAL_EXCEPTION_CODE_ACCESS, SIGBUS},
148
#endif    
149
#ifdef CYGNUM_HAL_EXCEPTION_CODE_WRITE
150
    {CYGNUM_HAL_EXCEPTION_CODE_WRITE, SIGBUS},
151
#endif    
152
#ifdef CYGNUM_HAL_EXCEPTION_CODE_EXECUTE
153
    {CYGNUM_HAL_EXCEPTION_CODE_EXECUTE, SIGBUS},
154
#endif    
155
#ifdef CYGNUM_HAL_EXCEPTION_IO_ACCESS
156
    {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},
157
#endif    
158
#ifdef CYGNUM_HAL_EXCEPTION_IO_WRITE
159
    {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},
160
#endif    
161
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
162
    {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, SIGSEGV},
163
#endif    
164
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE
165
    {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE, SIGSEGV},
166
#endif    
167
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS
168
    {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS, SIGSEGV},
169
#endif    
170
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE
171
    {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE, SIGSEGV},
172
#endif    
173
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS
174
    {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS, SIGSEGV},
175
#endif    
176
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE
177
    {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE, SIGSEGV},
178
#endif    
179
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS
180
    {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS, SIGSEGV},
181
#endif    
182
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE
183
    {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE, SIGSEGV},
184
#endif    
185
#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
186
    {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, SIGBUS},
187
#endif    
188
#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE
189
    {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE, SIGBUS},
190
#endif    
191
#ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS
192
    {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS, SIGBUS},
193
#endif    
194
#ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE
195
    {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE, SIGBUS},
196
#endif    
197
#ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
198
    {CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, SIGILL},
199
#endif    
200
#ifdef CYGNUM_HAL_EXCEPTION_INTERRUPT
201
    {CYGNUM_HAL_EXCEPTION_INTERRUPT, SIGINT},
202
#endif    
203
#ifdef CYGNUM_HAL_EXCEPTION_TRAP
204
    {CYGNUM_HAL_EXCEPTION_TRAP, SIGTRAP},
205
#endif    
206
#ifdef CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO
207
    {CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO, SIGFPE},
208
#endif    
209
#ifdef CYGNUM_HAL_EXCEPTION_OVERFLOW
210
    {CYGNUM_HAL_EXCEPTION_OVERFLOW, SIGFPE},
211
#endif    
212
#ifdef CYGNUM_HAL_EXCEPTION_BOUNDS
213
    {CYGNUM_HAL_EXCEPTION_BOUNDS, SIGSEGV},
214
#endif
215
#ifdef CYGNUM_HAL_EXCEPTION_SINGLE_STEP
216
    {CYGNUM_HAL_EXCEPTION_SINGLE_STEP, SIGTRAP},
217
#endif
218
#ifdef CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP
219
    {CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP, SIGTRAP},
220
#endif
221
#ifdef CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP
222
    {CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP, SIGTRAP},
223
#endif
224
#ifdef CYGNUM_HAL_EXCEPTION_DATA_BP
225
    {CYGNUM_HAL_EXCEPTION_DATA_BP, SIGTRAP},
226
#endif
227
#ifdef CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP
228
    {CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP, SIGTRAP},
229
#endif
230
#ifdef CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW
231
    {CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW, SIGSEGV},
232
#endif
233
#ifdef CYGNUM_HAL_EXCEPTION_STACK_FAULT
234
    {CYGNUM_HAL_EXCEPTION_STACK_FAULT, SIGSEGV},
235
#endif
236
#ifdef CYGNUM_HAL_EXCEPTION_PARITY
237
    {CYGNUM_HAL_EXCEPTION_PARITY, SIGBUS},
238
#endif
239
#ifdef CYGNUM_HAL_EXCEPTION_FPU
240
    {CYGNUM_HAL_EXCEPTION_FPU, SIGFPE},
241
#endif
242
#ifdef CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL
243
    {CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL, SIGFPE},
244
#endif
245
#ifdef CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW
246
    {CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW, SIGFPE},
247
#endif
248
#ifdef CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW
249
    {CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW, SIGFPE},
250
#endif
251
#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
252
    {CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, SIGFPE},
253
#endif
254
#ifdef CYGNUM_HAL_EXCEPTION_SYSTEM_CALL
255
    {CYGNUM_HAL_EXCEPTION_SYSTEM_CALL, SIGSYS},
256
#endif
257
    {0, 0} // dummy value to ensure compiler is happy
258
};
259
 
260
 
261
// FUNCTIONS
262
 
263
/////////////////////////////////////////
264
// cyg_libc_signals_hwexcept_handler() //
265
/////////////////////////////////////////
266
 
267
// FIXME: should be able to get this work with
268
// CYGSEM_KERNEL_EXCEPTIONS_DECODE disabled as well as enabled
269
static void
270
cyg_libc_signals_hwexcept_handler( CYG_ADDRWORD data, cyg_code exception,
271
                                   CYG_ADDRWORD info)
272
{
273
    int signal = (int)data;
274
    int ret;
275
 
276
    CYG_REPORT_FUNCNAME("cyg_libc_signals_hwexcept_handler");
277
 
278
    CYG_REPORT_FUNCARG3( "data = %08x, exception = %d, info = %08x",
279
                         data, exception, info );
280
 
281
#ifdef CYGSEM_LIBC_SIGNALS_BAD_SIGNAL_FATAL 
282
    CYG_PRECONDITION((signal > 0) && (signal < CYGNUM_LIBC_SIGNALS),
283
                     "Signal number not valid!");
284
#endif
285
 
286
// chain first as it may be more useful more low-level stuff needed
287
#ifdef CYGSEM_LIBC_SIGNALS_CHAIN_HWEXCEPTIONS
288
    // map exception to 0..CYGNUM_HAL_EXCEPTION_COUNT
289
    exception -= CYGNUM_HAL_EXCEPTION_MIN;
290
 
291
    // special case for null handler since it is only for uncaught exceptions
292
 
293
    if (exception_chain_data[exception].old_handler !=
294
        cyg_null_exception_handler) {
295
        (*exception_chain_data[exception].old_handler)(
296
            exception_chain_data[exception].old_data, exception, info);
297
        CYG_TRACE0(TL1, "Chained exception handler returned");
298
    } // if
299
#endif
300
 
301
#ifndef CYGSEM_LIBC_SIGNALS_BAD_SIGNAL_FATAL
302
    // if not fatal, silently return
303
    if ((signal <= 0) || (signal >= CYGNUM_LIBC_SIGNALS)) {
304
        CYG_REPORT_RETURN();
305
        return;
306
    }
307
#endif
308
 
309
    CYG_TRACE0(TL1, "Enabling interrupts");
310
    HAL_ENABLE_INTERRUPTS();
311
 
312
    CYG_TRACE0(TL1, "Raising signal");
313
    ret = raise(signal);
314
 
315
    if (ret) {
316
        CYG_TRACE1(TL1, "raise() returned non-zero value %d!!!", ret);
317
    } // if
318
 
319
    CYG_REPORT_RETURN();
320
} // cyg_libc_signals_hwexcept_handler()
321
 
322
 
323
//////////////////
324
// reg_except() //
325
//////////////////
326
 
327
static void inline
328
reg_except( cyg_code exception, int signal )
329
{
330
    Cyg_Thread::self()->register_exception(
331
        exception, &cyg_libc_signals_hwexcept_handler, (CYG_ADDRWORD)signal,
332
#ifdef CYGSEM_LIBC_SIGNALS_CHAIN_HWEXCEPTIONS
333
        &exception_chain_data[exception -
334
                             CYGNUM_HAL_EXCEPTION_MIN].old_handler,
335
        &exception_chain_data[exception - CYGNUM_HAL_EXCEPTION_MIN].old_data
336
#else
337
        NULL, NULL
338
#endif
339
        );
340
 
341
} // reg_except();
342
 
343
#endif // ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
344
 
345
///////////////////////////////////////////////////
346
// Cyg_libc_signals_dummy_init_class constructor //
347
///////////////////////////////////////////////////
348
 
349
Cyg_libc_signals_dummy_init_class::Cyg_libc_signals_dummy_init_class()
350
{
351
    cyg_ucount8 i;
352
 
353
    CYG_REPORT_FUNCNAME("Cyg_libc_signals_dummy_init_class constructor");
354
 
355
    // FIXME: some should be SIG_IGN?
356
    for (i=0; i<CYGNUM_LIBC_SIGNALS; i++)
357
        cyg_libc_signal_handlers[i] = SIG_DFL;
358
 
359
#ifdef CYGSEM_LIBC_SIGNALS_HWEXCEPTIONS
360
    // go through the entire array of exceptions, _but_ subtract 1 for
361
    // the dummy at the end
362
    for (i=0; i < (sizeof(exception_signal_mapping) /
363
                   sizeof(exception_signal_mapping_t) - 1); i++) {
364
        CYG_ASSERT( (exception_signal_mapping[i].exception <=
365
                    CYGNUM_HAL_EXCEPTION_MAX) &&
366
                    (exception_signal_mapping[i].exception >=
367
                    CYGNUM_HAL_EXCEPTION_MIN),
368
                    "Asked to register bad exception");
369
 
370
        CYG_ASSERT( (exception_signal_mapping[i].signal > 0) &&
371
                    (exception_signal_mapping[i].signal <
372
                     CYGNUM_LIBC_SIGNALS), "Asked to register bad signal" );
373
 
374
        reg_except( exception_signal_mapping[i].exception,
375
                    exception_signal_mapping[i].signal);
376
    }
377
#endif
378
 
379
    CYG_REPORT_RETURN();
380
} // Cyg_libc_signals_dummy_init_class() constructor
381
 
382
 
383
////////////////////////////////////////
384
// cyg_libc_signals_default_handler() //
385
////////////////////////////////////////
386
 
387
// Default signal handler - SIG_DFL
388
externC void
389
cyg_libc_signals_default_handler(int sig)
390
{
391
    CYG_REPORT_FUNCNAME( "cyg_libc_signals_default_handler" );
392
 
393
    CYG_REPORT_FUNCARG1( "signal number = %d", sig );
394
 
395
    exit(1000 + sig); // FIXME
396
 
397
    CYG_REPORT_RETURN();
398
} // cyg_libc_signals_default_handler()
399
 
400
#ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE
401
/////////////////////////////////////
402
// cyg_libc_signals_lock_do_lock() //
403
/////////////////////////////////////
404
 
405
externC cyg_bool
406
cyg_libc_signals_lock_do_lock(void)
407
{
408
    cyg_bool ret;
409
    CYG_REPORT_FUNCNAMETYPE("cyg_libc_signals_lock_do_lock", "returning %d");
410
 
411
    ret = cyg_libc_signal_handlers_mutex.lock();
412
 
413
    CYG_REPORT_RETVAL(ret);
414
 
415
    return ret;
416
} // cyg_libc_signals_lock_do_lock()
417
 
418
///////////////////////////////////////
419
// cyg_libc_signals_lock_do_unlock() //
420
///////////////////////////////////////
421
 
422
externC void
423
cyg_libc_signals_lock_do_unlock(void)
424
{
425
    CYG_REPORT_FUNCNAME("cyg_libc_signals_lock_do_unlock");
426
 
427
    cyg_libc_signal_handlers_mutex.unlock();
428
 
429
    CYG_REPORT_RETURN();
430
} // cyg_libc_signals_lock_do_unlock()
431
 
432
#endif // ifdef CYGSEM_LIBC_SIGNALS_THREAD_SAFE
433
 
434
// EOF siginit.cxx

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.