This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

synthetic target fixes


The synthetic target has not worked properly with some recent Linux
kernels on certain processors, e.g. 2.6.10-1.770FC3 on an AMD Athlon.
Something goes wrong in the kernel signal handling code, such that
when the signal handler is invoked the return address on the stack is
0x00000420 instead of 0xffffe420. The result is a SEGV when the
SIGALRM or SIGIO signal handler returns. I haven't been able to figure
out why this has started happening, but the patch below implements a
workaround: instead of returning directly the signal handler will now
exit via a system call. This is roughly what glibc does.

There is also a small clean-up of the clock configuration options in
the CDL.

Bart

Index: hal/synth/arch/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/arch/current/ChangeLog,v
retrieving revision 1.27
diff -u -r1.27 ChangeLog
--- ChangeLog	15 Dec 2004 14:01:38 -0000	1.27
+++ ChangeLog	11 Mar 2005 18:50:36 -0000
@@ -1,3 +1,13 @@
+2005-03-11  Bart Veer  <bartv@ecoscentric.com>
+
+	* src/synth_intr.c (synth_hardware_init): allow the platform to
+	customize the sigaction structures.
+
+	* include/hal_io.h: add more signal-related definitions
+
+	* cdl/hal_synth.cdl: change the clock calculations, so that users
+	only need to specify RTC_PERIOD
+
 2004-12-14  Alexander Neundorf <neundorf@kde.org>
 	    Andrew Lunn        <andrew.lunn@ascom.ch>
 
Index: hal/synth/arch/current/include/hal_io.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/arch/current/include/hal_io.h,v
retrieving revision 1.12
diff -u -r1.12 hal_io.h
--- hal/synth/arch/current/include/hal_io.h	15 Dec 2004 14:01:39 -0000	1.12
+++ hal/synth/arch/current/include/hal_io.h	11 Mar 2005 17:17:41 -0000
@@ -76,6 +76,8 @@
 
 #include <cyg/infra/cyg_type.h>
 
+#include <cyg/hal/var_io.h>     // Variant-specific definitions
+
 //-----------------------------------------------------------------------------
 // IO Register address.
 // This type is for recording the address of an IO register.
@@ -231,8 +233,10 @@
 #define CYG_HAL_SYS_SA_NOCLDSTOP        0x00000001
 #define CYG_HAL_SYS_SA_NOCLDWAIT        0x00000002
 #define CYG_HAL_SYS_SA_SIGINFO          0x00000004
+#define CYG_HAL_SYS_SA_RESTORER         0x04000000
 #define CYG_HAL_SYS_SA_RESTART          0x10000000
 #define CYG_HAL_SYS_SA_NODEFER          0x40000000
+
 #define CYG_HAL_SYS_SIG_BLOCK           0
 #define CYG_HAL_SYS_SIG_UNBLOCK         1
 #define CYG_HAL_SYS_SIG_SETMASK         2
@@ -275,11 +279,17 @@
 #define CYG_HAL_SYS_SIGISMEMBER(_set_, _bit_)                                                   \
     (0 != ((_set_)->hal_sig_bits[CYG_HAL_SYS__SIGELT(_bit_ - 1)] & CYG_HAL_SYS__SIGMASK(_bit_ - 1)))
 
+// The kernel sigaction structure has changed, to allow for >32
+// signals. This is the old version, i.e. a struct old_sigaction, for
+// use with the sigaction() system call rather than rt_sigaction(). It
+// is preferred to the more modern version because gdb knows about
+// rt_sigaction() and will start intercepting signals, but it seems to
+// ignore sigaction().
 struct cyg_hal_sys_sigaction {
     void        (*hal_handler)(int);
     long        hal_mask;
     int         hal_flags;
-    void        (*hal_bogus)(int);
+    void        (*hal_restorer)(void);
 };
 
 // Time support.
Index: hal/synth/arch/current/src/synth_intr.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/arch/current/src/synth_intr.c,v
retrieving revision 1.6
diff -u -r1.6 synth_intr.c
--- hal/synth/arch/current/src/synth_intr.c	30 Mar 2003 17:52:44 -0000	1.6
+++ hal/synth/arch/current/src/synth_intr.c	11 Mar 2005 17:17:49 -0000
@@ -8,6 +8,7 @@
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 eCosCentric Ltd
 // Copyright (C) 2002 Bart Veer
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 //
@@ -1278,8 +1279,11 @@
     // instead of having the signal handler return immediately.
     action.hal_mask     = 0;
     action.hal_flags    = CYG_HAL_SYS_SA_NODEFER;
-    action.hal_bogus    = (void (*)(int)) 0;
     action.hal_handler  = &synth_alrm_sighandler;
+    action.hal_restorer = (void (*)(void)) 0;
+#ifdef CYG_HAL_SYS_SIGACTION_ADJUST
+    CYG_HAL_SYS_SIGACTION_ADJUST(CYG_HAL_SYS_SIGALRM, &action);
+#endif    
     if (0 != cyg_hal_sys_sigaction(CYG_HAL_SYS_SIGALRM, &action, (struct cyg_hal_sys_sigaction*) 0)) {
         CYG_FAIL("Failed to install signal handler for SIGALRM");
     }
Index: hal/synth/arch/current/cdl/hal_synth.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/arch/current/cdl/hal_synth.cdl,v
retrieving revision 1.7
diff -u -r1.7 hal_synth.cdl
--- hal/synth/arch/current/cdl/hal_synth.cdl	15 Dec 2004 14:01:39 -0000	1.7
+++ hal/synth/arch/current/cdl/hal_synth.cdl	11 Mar 2005 17:17:39 -0000
@@ -81,25 +81,33 @@
     cdl_component CYGNUM_HAL_RTC_CONSTANTS {
         display       "Real-time clock constants."
         description   "
-            These values are used in the usec field of the itimerval structure
-            when using getitimer/setitimer."
+            In the synthetic target the system clock is implemented using
+            Linux setitimer() and a SIGALRM signal. The PERIOD value is the
+            number of microseconds between signals, the usec field of an
+            itimerval structure. It should be a multiple of 10000 because
+            Linux will not generate signals at a finer grain than that.
+            The NUMERATOR and DENOMINATOR are derived from the period."
         flavor        none
     
+        cdl_option CYGNUM_HAL_RTC_PERIOD {
+            display       "Real-time clock period"
+            flavor        data
+            default_value 10000
+	    requires	  { 0 == (CYGNUM_HAL_RTC_PERIOD % 10000) }
+	    description "
+                This option corresponds to the number of microseconds between
+                clock interrupts."
+        }
         cdl_option CYGNUM_HAL_RTC_NUMERATOR {
             display       "Real-time clock numerator"
             flavor        data
-            default_value 1000000000
+            calculated    CYGNUM_HAL_RTC_DENOMINATOR * 1000 * CYGNUM_HAL_RTC_PERIOD
         }
         cdl_option CYGNUM_HAL_RTC_DENOMINATOR {
             display       "Real-time clock denominator"
             flavor        data
             default_value 100
         }
-        cdl_option CYGNUM_HAL_RTC_PERIOD {
-            display       "Real-time clock period"
-            flavor        data
-            default_value 10000
-        }
     }
     # What to do when idling
     cdl_option CYGIMP_HAL_IDLE_THREAD_SPIN {
Index: hal/synth/i386linux/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/i386linux/current/ChangeLog,v
retrieving revision 1.12
diff -u -r1.12 ChangeLog
--- hal/synth/i386linux/current/ChangeLog	15 Dec 2004 14:02:31 -0000	1.12
+++ hal/synth/i386linux/current/ChangeLog	11 Mar 2005 17:17:51 -0000
@@ -1,3 +1,8 @@
+2005-03-11  Bart Veer  <bartv@ecoscentric.com>
+
+	* include/var_io.h, src/syscall-i386-linux-1.0.S:
+	Improve support for returning from signal handlers
+
 2004-12-14  Alexander Neundorf <neundorf@kde.org>
 
 	* src/syscall-i386-linux-1.0.S:	Add ipc system call
Index: hal/synth/i386linux/current/include/var_io.h
===================================================================
RCS file: hal/synth/i386linux/current/include/var_io.h
diff -N hal/synth/i386linux/current/include/var_io.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ hal/synth/i386linux/current/include/var_io.h	11 Mar 2005 17:17:53 -0000
@@ -0,0 +1,101 @@
+#ifndef CYGONCE_HAL_VAR_IO_H
+#define CYGONCE_HAL_VAR_IO_H
+
+//=============================================================================
+//
+//      var_io.h
+//
+//      Processor-specific I/O support
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2005 eCosCentric Ltd
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   bartv
+// Date:        2003-10-08
+// Usage:       #include <cyg/hal/hal_io.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+// In theory an application signal handler can just return straight to
+// the kernel. In reality this is usually the case as well, but with
+// some kernel versions on some processors it is necessary instead to
+// exit via a sigreturn system call.
+externC void    cyg_hal_sys_restore(void);
+externC void    cyg_hal_sys_restore_rt(void);
+
+#define CYG_HAL_SYS_SIGACTION_ADJUST(_sig_, _sigaction_)    \
+    CYG_MACRO_START                                         \
+    (_sigaction_)->hal_flags    |= CYG_HAL_SYS_SA_RESTORER; \
+    (_sigaction_)->hal_restorer = &cyg_hal_sys_restore;     \
+    CYG_MACRO_END
+
+// Additional information passed to a signal handler. This is useful
+// for e.g. profiling.
+struct cyg_hal_sys_sigcontext {
+    unsigned short  hal_gs;
+    unsigned short  hal_gsh;
+    unsigned short  hal_fs;
+    unsigned short  hal_fsh;
+    unsigned short  hal_es;
+    unsigned short  hal_esh;
+    unsigned short  hal_ds;
+    unsigned short  hal_dsh;
+    unsigned long   hal_edi;
+    unsigned long   hal_esi;
+    unsigned long   hal_ebp;
+    unsigned long   hal_esp;
+    unsigned long   hal_ebx;
+    unsigned long   hal_edx;
+    unsigned long   hal_ecx;
+    unsigned long   hal_eax;
+    unsigned long   hal_trapno;
+    unsigned long   hal_err;
+    unsigned long   hal_eip;
+    unsigned short  hal_cs;
+    unsigned short  hal_csh;
+    unsigned long   hal_eflags;
+    unsigned long   hal_esp_at_signal;
+    unsigned short  hal_ss;
+    unsigned short  hal_ssh;
+    void*           hal_fpstate;
+    unsigned long   hal_oldmask;
+    unsigned long   hal_cr2;
+};
+
+//--------------------------------------------------------------------------
+#endif // CYGONCE_HAL_VAR_IO_H
+// End of var_io.h
Index: hal/synth/i386linux/current/src/syscall-i386-linux-1.0.S
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/synth/i386linux/current/src/syscall-i386-linux-1.0.S,v
retrieving revision 1.9
diff -u -r1.9 syscall-i386-linux-1.0.S
--- hal/synth/i386linux/current/src/syscall-i386-linux-1.0.S	15 Dec 2004 14:02:31 -0000	1.9
+++ hal/synth/i386linux/current/src/syscall-i386-linux-1.0.S	11 Mar 2005 17:17:54 -0000
@@ -8,6 +8,7 @@
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2005 eCosCentric Ltd.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
 //
 // eCos is free software; you can redistribute it and/or modify it under
@@ -441,3 +442,28 @@
 STATCALL2(fstat)
 SYSCALL2(mkdir)
 SYSCALL5(ipc)
+
+// ----------------------------------------------------------------------------
+// Special support for returning from a signal handler. In theory no special
+// action is needed, but with some versions of the kernel on some
+// architectures that is not good enough. Instead returning has to happen
+// via another system call.         
+
+        .align 16
+        .global cyg_hal_sys_restore_rt
+cyg_hal_sys_restore_rt:
+        movl    $SYS_rt_sigreturn, %eax
+        int     $0x80
+1:              
+        .type __restore_rt,@function
+        .size __restore_rt,1b - __restore_rt
+                
+        .align 8
+        .global cyg_hal_sys_restore
+cyg_hal_sys_restore:
+        popl    %eax
+        movl    $SYS_sigreturn, %eax
+        int     $0x80
+1:              
+        .type __restore,@function
+        .size __restore,1b - __restore



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]