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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [compat/] [posix/] [v2_0/] [src/] [except.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      except.cxx
4
//
5
//      POSIX exception translation
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:                2000-03-27
46
// Purpose:             POSIX exception translation
47
// Description:         This file contains code to translate eCos hardware
48
//                      exceptions into POSIX signals.
49
//              
50
//              
51
//
52
//####DESCRIPTIONEND####
53
//
54
//==========================================================================
55
 
56
#include <pkgconf/hal.h>
57
#include <pkgconf/kernel.h>
58
#include <pkgconf/posix.h>
59
 
60
#include <cyg/kernel/ktypes.h>          // base kernel types
61
#include <cyg/infra/cyg_trac.h>         // tracing macros
62
#include <cyg/infra/cyg_ass.h>          // assertion macros
63
 
64
#include <cyg/infra/diag.h>
65
 
66
#include "pprivate.h"                   // POSIX private header
67
 
68
#include <signal.h>                     // our header
69
 
70
#include <cyg/kernel/thread.inl>
71
 
72
//==========================================================================
73
// Translation table from eCos exceptions to POSIX signals.
74
 
75
static const struct
76
{
77
    cyg_code    exception;
78
    int         signal;
79
} exception_signal_mapping[] =
80
{
81
#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
82
    {CYGNUM_HAL_EXCEPTION_DATA_ACCESS, SIGBUS},
83
#endif
84
#ifdef CYGNUM_HAL_EXCEPTION_DATA_WRITE
85
    {CYGNUM_HAL_EXCEPTION_DATA_WRITE, SIGBUS},
86
#endif
87
#ifdef CYGNUM_HAL_EXCEPTION_CODE_ACCESS
88
    {CYGNUM_HAL_EXCEPTION_CODE_ACCESS, SIGBUS},
89
#endif    
90
#ifdef CYGNUM_HAL_EXCEPTION_CODE_WRITE
91
    {CYGNUM_HAL_EXCEPTION_CODE_WRITE, SIGBUS},
92
#endif    
93
#ifdef CYGNUM_HAL_EXCEPTION_CODE_EXECUTE
94
    {CYGNUM_HAL_EXCEPTION_CODE_EXECUTE, SIGBUS},
95
#endif    
96
#ifdef CYGNUM_HAL_EXCEPTION_IO_ACCESS
97
    {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},
98
#endif    
99
#ifdef CYGNUM_HAL_EXCEPTION_IO_WRITE
100
    {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},
101
#endif    
102
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
103
    {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, SIGSEGV},
104
#endif    
105
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE
106
    {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE, SIGSEGV},
107
#endif    
108
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS
109
    {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS, SIGSEGV},
110
#endif    
111
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE
112
    {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE, SIGSEGV},
113
#endif    
114
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS
115
    {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS, SIGSEGV},
116
#endif    
117
#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE
118
    {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE, SIGSEGV},
119
#endif    
120
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS
121
    {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS, SIGSEGV},
122
#endif    
123
#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE
124
    {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE, SIGSEGV},
125
#endif    
126
#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
127
    {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, SIGBUS},
128
#endif    
129
#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE
130
    {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE, SIGBUS},
131
#endif    
132
#ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS
133
    {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS, SIGBUS},
134
#endif    
135
#ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE
136
    {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE, SIGBUS},
137
#endif    
138
#ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
139
    {CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, SIGILL},
140
#endif    
141
#ifdef CYGNUM_HAL_EXCEPTION_INTERRUPT
142
    {CYGNUM_HAL_EXCEPTION_INTERRUPT, SIGINT},
143
#endif    
144
#ifdef CYGNUM_HAL_EXCEPTION_TRAP
145
    {CYGNUM_HAL_EXCEPTION_TRAP, SIGTRAP},
146
#endif    
147
#ifdef CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO
148
    {CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO, SIGFPE},
149
#endif    
150
#ifdef CYGNUM_HAL_EXCEPTION_OVERFLOW
151
    {CYGNUM_HAL_EXCEPTION_OVERFLOW, SIGFPE},
152
#endif    
153
#ifdef CYGNUM_HAL_EXCEPTION_BOUNDS
154
    {CYGNUM_HAL_EXCEPTION_BOUNDS, SIGSEGV},
155
#endif
156
#ifdef CYGNUM_HAL_EXCEPTION_SINGLE_STEP
157
    {CYGNUM_HAL_EXCEPTION_SINGLE_STEP, SIGTRAP},
158
#endif
159
#ifdef CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP
160
    {CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP, SIGTRAP},
161
#endif
162
#ifdef CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP
163
    {CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP, SIGTRAP},
164
#endif
165
#ifdef CYGNUM_HAL_EXCEPTION_DATA_BP
166
    {CYGNUM_HAL_EXCEPTION_DATA_BP, SIGTRAP},
167
#endif
168
#ifdef CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP
169
    {CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP, SIGTRAP},
170
#endif
171
#ifdef CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW
172
    {CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW, SIGSEGV},
173
#endif
174
#ifdef CYGNUM_HAL_EXCEPTION_STACK_FAULT
175
    {CYGNUM_HAL_EXCEPTION_STACK_FAULT, SIGSEGV},
176
#endif
177
#ifdef CYGNUM_HAL_EXCEPTION_PARITY
178
    {CYGNUM_HAL_EXCEPTION_PARITY, SIGBUS},
179
#endif
180
#ifdef CYGNUM_HAL_EXCEPTION_FPU
181
    {CYGNUM_HAL_EXCEPTION_FPU, SIGFPE},
182
#endif
183
#ifdef CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL
184
    {CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL, SIGFPE},
185
#endif
186
#ifdef CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW
187
    {CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW, SIGFPE},
188
#endif
189
#ifdef CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW
190
    {CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW, SIGFPE},
191
#endif
192
#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
193
    {CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, SIGFPE},
194
#endif
195
#ifdef CYGNUM_HAL_EXCEPTION_SYSTEM_CALL
196
    {CYGNUM_HAL_EXCEPTION_SYSTEM_CALL, SIGSYS},
197
#endif
198
    {0, 0} // dummy value to ensure compiler is happy
199
};
200
 
201
//==========================================================================
202
// POSIX exception handler
203
 
204
static void cyg_posix_exception_handler(
205
    CYG_ADDRWORD        data,                   // user supplied data == signal number
206
    cyg_code            exception_number,       // exception being raised
207
    CYG_ADDRWORD        exception_info          // any exception specific info
208
    )
209
{
210
    int signo = 0;
211
 
212
    pthread_info *self = pthread_self_info();
213
 
214
    if( self == NULL )
215
    {
216
        // Not a POSIX thread, just return
217
        return;
218
    }
219
 
220
#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
221
 
222
    signo = data;
223
 
224
#else
225
 
226
    for( int i = 0; exception_signal_mapping[i].signal != 0; i++ )
227
    {
228
        if( exception_signal_mapping[i].exception == exception_number )
229
        {
230
            signo = exception_signal_mapping[i].signal;
231
            break;
232
        }
233
    }
234
 
235
#endif
236
 
237
    if( sigismember( &self->sigmask, signo ) )
238
    {
239
        // The signal is masked in the current thread. POSIX says that
240
        // the behaviour is undefined here. We choose to ignore it.
241
 
242
        return;
243
    }
244
 
245
    // The kernel exception handler may have disabled interrupts, so
246
    // we (re-)enable them here. From this point on we are running in
247
    // a context that is effectively just pushed onto the stack of the
248
    // current thread. If we return we will unwind and resume
249
    // execution from the excepting code. We can also, in theory,
250
    // longjump out of the signal handler, and although that is
251
    // deprecated, we make sure in cyg_deliver_signals() that it is
252
    // possible to do it.
253
 
254
    HAL_ENABLE_INTERRUPTS();
255
 
256
    struct sigevent sev;
257
 
258
    sev.sigev_notify           = SIGEV_SIGNAL;
259
    sev.sigev_signo            = signo;
260
    sev.sigev_value.sival_ptr  = (void *)exception_info;
261
 
262
    // Generate the signal
263
    cyg_sigqueue( &sev, SI_EXCEPT );
264
 
265
    // And try to deliver it
266
    cyg_deliver_signals();
267
}
268
 
269
//==========================================================================
270
// Install all the exception handlers
271
 
272
static void install_handlers( Cyg_Thread *thread)
273
{
274
#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
275
 
276
    // With decoded exceptions, we must install a separate exception
277
    // handler for each supported exception.
278
 
279
    for( int i = 0; exception_signal_mapping[i].signal != 0; i++ )
280
    {
281
        thread->register_exception( exception_signal_mapping[i].exception,
282
                                    cyg_posix_exception_handler,
283
                                    exception_signal_mapping[i].signal,,
284
                                    NULL,
285
                                    NULL);
286
    }
287
 
288
#else
289
 
290
    // Otherwise there is just one exception handler for all exceptions.
291
 
292
    thread->register_exception( CYGNUM_HAL_EXCEPTION_MIN,
293
                                cyg_posix_exception_handler,
294
                                0,
295
                                NULL,
296
                                NULL);
297
 
298
#endif    
299
 
300
}
301
 
302
//==========================================================================
303
// Initialization
304
 
305
externC void cyg_posix_exception_start()
306
{
307
#ifdef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
308
 
309
    // With global exceptions, we only need to install a single static
310
    // set of exception handlers. Note that by this point in system
311
    // initialization the idle thread should be installed as the
312
    // current thread, so we pass a pointer to that to
313
    // install_handlers(). The identity of the thread passed is
314
    // actually irrelevant in this case and is just used as a handle
315
    // into the thread class.
316
 
317
    install_handlers( Cyg_Thread::self() );
318
 
319
#endif    
320
}
321
 
322
//==========================================================================
323
// Per thread exception initialization and destruction
324
 
325
externC void cyg_pthread_exception_init(pthread_info *thread)
326
{
327
#ifndef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
328
 
329
    // With non-global exceptions we must install a new set of handlers
330
    // for each thread.
331
 
332
    install_handlers( thread->thread );
333
 
334
#endif
335
}
336
 
337
externC void cyg_pthread_exception_destroy(pthread_info *thread)
338
{
339
    // Nothing to do at present.
340
}
341
 
342
// -------------------------------------------------------------------------
343
// EOF except.cxx

powered by: WebSVN 2.1.0

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