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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [compat/] [posix/] [current/] [src/] [except.cxx] - Blame information for rev 810

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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