diff packages/kernel/current/src/common/except.cxx @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children 443894e2e912
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/kernel/current/src/common/except.cxx
@@ -0,0 +1,230 @@
+//==========================================================================
+//
+//	common/except.cxx
+//
+//	Exception handling implementation
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//
+// -------------------------------------------
+// The contents of this file are subject to the Cygnus eCos Public License
+// Version 1.0 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://sourceware.cygnus.com/ecos
+// 
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
+// License for the specific language governing rights and limitations under
+// the License.
+// 
+// The Original Code is eCos - Embedded Cygnus Operating System, released
+// September 30, 1998.
+// 
+// The Initial Developer of the Original Code is Cygnus.  Portions created
+// by Cygnus are Copyright (C) 1998 Cygnus Solutions.  All Rights Reserved.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): 	nickg
+// Contributors:	nickg
+// Date:	1998-04-09
+// Purpose:	Exception handling implementation
+// Description:	This file contains the code that registers and delivers
+//              exceptions.
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/ktypes.h>         // base kernel types
+#include <cyg/infra/cyg_trac.h>        // tracing macros
+#include <cyg/infra/cyg_ass.h>         // assertion macros
+#include <cyg/kernel/instrmnt.h>       // instrumentation
+
+#include <cyg/kernel/except.hxx>       // our header
+
+#include <cyg/hal/hal_arch.h>          // architecture definitions
+#include <cyg/hal/hal_intr.h>          // vector definitions
+
+#include <cyg/kernel/thread.hxx>       // thread interface
+
+#include <cyg/kernel/thread.inl>       // thread inlines
+
+#ifdef CYGPKG_KERNEL_EXCEPTIONS
+
+// -------------------------------------------------------------------------
+// Null exception handler. This is used to capture exceptions that are
+// not caught by user supplied handlers.
+
+void cyg_null_exception_handler(
+    CYG_ADDRWORD        data,                   // user supplied data
+    cyg_code            exception_number,       // exception being raised
+    CYG_ADDRWORD        exception_info          // any exception specific info
+    )
+{
+    CYG_TRACE1( 1, "Uncaught exception: %d", exception_number);
+}
+
+// -------------------------------------------------------------------------
+// Exception Controller constructor.
+
+Cyg_Exception_Control::Cyg_Exception_Control()
+{
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+
+    for( int i = 0; i < CYG_EXCEPTION_COUNT ; i++ )
+        exception_handler[i] = cyg_null_exception_handler,
+            exception_data[i] = 0;
+#else
+
+    exception_handler = cyg_null_exception_handler;    
+    exception_data = 0;
+    
+#endif
+
+}
+
+// -------------------------------------------------------------------------
+// Exception registation. Stores the handler function and data to be used
+// for handling the given exception number. Where exceptions are not decoded
+// only a single handler may be registered for all exceptions. This function
+// also returns the old values of the exception handler and data to allow
+// chaining to be implemented.
+
+void Cyg_Exception_Control::register_exception(
+    cyg_code                exception_number,       // exception number
+    cyg_exception_handler   handler,                // handler function
+    CYG_ADDRWORD            data,                   // data argument
+    cyg_exception_handler   **old_handler,          // handler function
+    CYG_ADDRWORD            *old_data               // data argument
+    )
+{
+    CYG_REPORT_FUNCTION();
+
+    CYG_ASSERT( exception_number <= CYG_EXCEPTION_MAX,
+                "Out of range exception number");
+    CYG_ASSERT( exception_number >= CYG_EXCEPTION_MIN,
+                "Out of range exception number");
+
+
+    // Should we complain if there is already a registered
+    // handler, or should we just replace is silently?
+    
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+
+    if( old_handler != NULL )
+        *old_handler = exception_handler[exception_number];
+    if( old_data != NULL )
+        *old_data = exception_data[exception_number];
+    exception_handler[exception_number] = handler;
+    exception_data[exception_number] = data;
+    
+#else
+    
+    if( old_handler != NULL )
+        *old_handler = exception_handler;
+    if( old_data != NULL )
+        *old_data = exception_data;
+    exception_handler = handler;
+    exception_data = data;
+    
+#endif
+    
+}
+
+// -------------------------------------------------------------------------
+// Exception deregistation. Revert the handler for the exception number
+// to the default.
+
+void Cyg_Exception_Control::deregister_exception(
+    cyg_code                exception_number        // exception number
+    )
+{
+    CYG_REPORT_FUNCTION();
+
+    CYG_ASSERT( exception_number <= CYG_EXCEPTION_MAX,
+                "Out of range exception number");
+    CYG_ASSERT( exception_number >= CYG_EXCEPTION_MIN,
+                "Out of range exception number");
+
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+
+    exception_handler[exception_number] = cyg_null_exception_handler;
+    exception_data[exception_number] = 0;
+    
+#else
+    
+    exception_handler = cyg_null_exception_handler;
+    exception_data = 0;
+    
+#endif
+    
+}
+
+// -------------------------------------------------------------------------
+// Exception delivery. Call the appropriate exception handler.
+
+void Cyg_Exception_Control::deliver_exception(
+    cyg_code            exception_number,       // exception being raised
+    CYG_ADDRWORD        exception_info          // exception specific info
+    )
+{
+    cyg_exception_handler *handler = NULL;
+    CYG_ADDRWORD data = 0;
+
+    CYG_ASSERT( exception_number <= CYG_EXCEPTION_MAX,
+                "Out of range exception number");
+    CYG_ASSERT( exception_number >= CYG_EXCEPTION_MIN,
+                "Out of range exception number");
+    
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+
+    handler = exception_handler[exception_number];
+    data = exception_data[exception_number];
+    
+#else
+    
+    handler = exception_handler;
+    data = exception_data;
+    
+#endif
+
+    // The handler will always be a callable function: either the user's
+    // registered function or the null handler. So it is always safe to
+    // just go ahead and call it.
+    
+    handler( data, exception_number, exception_info );
+    
+}
+
+// -------------------------------------------------------------------------
+// Exception delivery function called from the HAL as a result of a
+// hardware exception being raised.
+
+externC void deliver_exception( CYG_WORD code, CYG_ADDRWORD data )
+{
+    Cyg_Thread::self()->deliver_exception( code, data );
+}
+
+// -------------------------------------------------------------------------
+// Where exceptions are global, there is a single static instance of the
+// exception control object. Define it here.
+
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
+
+Cyg_Exception_Control Cyg_Thread::exception_control;
+
+#endif
+
+// -------------------------------------------------------------------------
+
+#endif
+
+// -------------------------------------------------------------------------
+// EOF common/except.cxx