This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
synthetic target fixes
- From: Bart Veer <bartv at ecoscentric dot com>
- To: ecos-patches at ecos dot sourceware dot org
- Date: Fri, 11 Mar 2005 19:03:06 +0000 (GMT)
- Subject: 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