]> git.kernelconcepts.de Git - karo-tx-redboot.git/commitdiff
Initial revision
authorlothar <lothar>
Mon, 3 Nov 2008 11:39:03 +0000 (11:39 +0000)
committerlothar <lothar>
Mon, 3 Nov 2008 11:39:03 +0000 (11:39 +0000)
188 files changed:
packages/compat/linux/v2_0/ChangeLog [new file with mode: 0644]
packages/compat/linux/v2_0/cdl/linux.cdl [new file with mode: 0644]
packages/compat/linux/v2_0/include/asm/atomic.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/asm/bug.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/asm/page.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/asm/semaphore.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/TODO [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/compiler.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/completion.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/config.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/crc32.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/errno.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/fs.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/init.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/kernel.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/list.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/mtd/compatmac.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/mtd/mtd.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/pagemap.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/rbtree.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/rwsem.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/sched.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/slab.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/spinlock.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/stat.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/string.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/timer.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/types.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/version.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/vmalloc.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/wait.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/workqueue.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/zlib.h [new file with mode: 0644]
packages/compat/linux/v2_0/include/linux/zutil.h [new file with mode: 0644]
packages/compat/linux/v2_0/src/rbtree.c [new file with mode: 0644]
packages/compat/posix/v2_0/ChangeLog [new file with mode: 0644]
packages/compat/posix/v2_0/cdl/posix.cdl [new file with mode: 0644]
packages/compat/posix/v2_0/cdl/pthread.cdl [new file with mode: 0644]
packages/compat/posix/v2_0/doc/posix.sgml [new file with mode: 0644]
packages/compat/posix/v2_0/include/export.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/limits.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/mutex.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/muttypes.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/pthread.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/semaphore.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/signal.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/sigsetjmp.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/time.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/types.h [new file with mode: 0644]
packages/compat/posix/v2_0/include/utsname.h [new file with mode: 0644]
packages/compat/posix/v2_0/src/except.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/misc.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/mqueue.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/mutex.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/pprivate.h [new file with mode: 0644]
packages/compat/posix/v2_0/src/pthread.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/sched.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/sem.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/signal.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/startup.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/src/time.cxx [new file with mode: 0644]
packages/compat/posix/v2_0/tests/mqueue1.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/mqueue2.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/mutex3.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/pthread1.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/pthread2.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/pthread3.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/signal1.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/signal2.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/signal3.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/sigsetjmp.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/timer1.c [new file with mode: 0644]
packages/compat/posix/v2_0/tests/tm_basic.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/ChangeLog [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/flags.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/mboxes.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/mempoolfixed.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/mempoolvar.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/semas.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/tasks.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/uitron.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/cdl/version.cdl [new file with mode: 0644]
packages/compat/uitron/v2_0/doc/uitron.sgml [new file with mode: 0644]
packages/compat/uitron/v2_0/include/uit_func.h [new file with mode: 0644]
packages/compat/uitron/v2_0/include/uit_func.inl [new file with mode: 0644]
packages/compat/uitron/v2_0/include/uit_ifnc.h [new file with mode: 0644]
packages/compat/uitron/v2_0/include/uit_ifnc.inl [new file with mode: 0644]
packages/compat/uitron/v2_0/include/uit_objs.hxx [new file with mode: 0644]
packages/compat/uitron/v2_0/include/uit_type.h [new file with mode: 0644]
packages/compat/uitron/v2_0/src/uit_func.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/src/uit_ifnc.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/src/uit_objs.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test1.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test2.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test3.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test4.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test5.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test6.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test7.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test8.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/test9.c [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx2.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx3.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx4.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx5.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx6.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx7.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx8.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcx9.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testcxx.cxx [new file with mode: 0644]
packages/compat/uitron/v2_0/tests/testintr.cxx [new file with mode: 0644]
packages/cygmon/v2_0/ChangeLog [new file with mode: 0644]
packages/cygmon/v2_0/cdl/cygmon.cdl [new file with mode: 0644]
packages/cygmon/v2_0/misc/Notes_CygMon_PID [new file with mode: 0644]
packages/cygmon/v2_0/misc/arm/arm-mon.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/arm/board.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/arm/cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/arm/cpu_info.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/board.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bplist-dynamic.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/breakpoints.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/arm/gdb-cpu.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/arm/gdb-cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/arm/gdb.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/arm/insn.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/arm/singlestep.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/bsp.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/breakpoint.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/bsp.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/bsp_cache.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/bsp_if.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/bsp_if.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/console-io.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/debug-io.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/gdb-cpu.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/gdb-cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/gdb.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/generic-mem.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/hex-utils.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/printf.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/shared-data.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/singlestep.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/sprintf.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/syscall.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/syscall.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/sysinfo.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/common/vprintf.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/dbg-threads-api.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/defs.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/gdb-data.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/hex-utils.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mips/gdb-cpu.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mips/gdb-cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mips/gdb.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mips/insn.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mips/singlestep.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mn10300/gdb-cpu.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mn10300/gdb-cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mn10300/gdb.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mn10300/insn.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/bsp/mn10300/singlestep.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/cpu-mon.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/cpu_info.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/ecos_bsp.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/ecos_dummy.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/fmt_util.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/generic-stub.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/generic_fmt32.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/generic_mem.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/ledit.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/ledit.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/mips/board.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/mips/cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/mips/cpu_info.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/mips/mips-mon.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/mn10300/board.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/mn10300/cpu.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/mn10300/cpu_info.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/mn10300/mn10300-mon.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/monitor.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/monitor.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/monitor_cmd.c [new file with mode: 0644]
packages/cygmon/v2_0/misc/monitor_cmd.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/stub-tservice.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/tservice.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/unistd.h [new file with mode: 0644]
packages/cygmon/v2_0/misc/utils.c [new file with mode: 0644]

diff --git a/packages/compat/linux/v2_0/ChangeLog b/packages/compat/linux/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..a7463da
--- /dev/null
@@ -0,0 +1,95 @@
+2005-03-27  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * include/linux/kernel.h (PTR_ERR): Should be an unsigned long,
+       not an intager, at least that is what Linux uses.
+
+2005-01-22  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * include/linux/spinlock.h (DEFINE_SPINLOCK): Added.
+       * include/linux/slab.h (vfree): Added vmalloc and vfree which map
+       to malloc and free.
+       * include/linux/rwsem.h: New file. eCos does not have read/write
+       semaphores so these are mapped to normal semaphores.
+       
+2004-08-12  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * include/linux/spinlock.h: Add CYG_UNUSED_PARAM() calls to avoid
+       compiler warnings.
+
+2004-08-04  Gary Thomas <gary@mlbassoc.com>
+
+       * include/linux/list.h (list_for_each_entry): New macro needed for
+       latest jffs2 code.
+
+2003-11-12  Thomas Koeller <thomas.koeller@baslerweb.com>
+
+        * cdl/linux.cdl:
+        * include/asm/page.h:
+        Make page size configurable via cdl.
+
+2003-10-18  Gary Thomas  <gary@mlbassoc.com>
+
+        * src/rbtree.c (rb_erase): Fix bug in red-black tree which caused
+        node corruption - merge from external sources, found by Scott 
+       Wilkerson.
+
+2003-10-18  Savin Zlobec <savin@elatec.si>
+
+        * include/linux/rbtree.h: 
+        Fixed 'pointer of type `void *' used in subtraction' compiler warrning.
+
+2003-07-27  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * include/linux/init.h: 
+       * include/linux/vmalloc.h: New dummy files so that jffs2 will
+       compile.
+
+2003-07-27  Michael Checky  <Michael_Checky@ThermoKing.com>
+            Andrew Lunn <andrew.lunn@ascom.ch>
+       
+       * include/linux/kernel.h: Changed the #define IS_ERR to work correctly
+       negative error values returned by the jffs2 code.
+
+2003-06-10  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * include/linux/stat.h: Removed #defines which has been added to 
+       the main eCos sys/stat.h. 
+
+2003-01-21  David Woodhouse  <dwmw2@infradead.org>
+
+       * New package.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003 Red Hat.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/compat/linux/v2_0/cdl/linux.cdl b/packages/compat/linux/v2_0/cdl/linux.cdl
new file mode 100644 (file)
index 0000000..d9b93aa
--- /dev/null
@@ -0,0 +1,76 @@
+# ====================================================================
+#
+#      linux.cdl
+#
+#      Linux compatibility layer data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      dwmw2
+# Contributors:   tkoeller
+# Date:           2003-01-08
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_LINUX_COMPAT {
+    display       "Linux compatibility layer"
+    include_dir   ""
+    description   "
+       eCos supports a basic Linux compatibility Layer providing various
+        functions, equivalents or stubs expected by Linux kernel code, for
+        assistance in porting drivers and file system code from Linux.
+        Note this does not provide Linux compatibility to applications."
+
+    compile      rbtree.c
+
+    cdl_option CYGNUM_LINUX_COMPAT_PAGE_SIZE_EXPONENT {
+        display         "Define page size"
+        flavor          data
+        legal_values    10 to 16
+        default_value   12
+        no_define
+        define          PAGE_SHIFT
+        description     "
+            Define the page size. The value entered here is used as an
+            exponent X in the expression 2^^X to ensure that the page
+            size is always an integer power of two."  
+     } 
+}
+
+# EOF linux.cdl
diff --git a/packages/compat/linux/v2_0/include/asm/atomic.h b/packages/compat/linux/v2_0/include/asm/atomic.h
new file mode 100644 (file)
index 0000000..5cb72ff
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __ASM_ATOMIC_H__
+#define __ASM_ATOMIC_H__
+
+#define atomic_t int
+#define atomic_inc(atom) (*atom)++
+#define atomic_dec(atom) (*atom)--
+#define atomic_read(atom) (*atom)
+
+
+#endif /* __ASM_ATOMIC_H__ */
diff --git a/packages/compat/linux/v2_0/include/asm/bug.h b/packages/compat/linux/v2_0/include/asm/bug.h
new file mode 100644 (file)
index 0000000..060eb27
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ASM_BUG_H__
+#define __ASM_BUG_H__
+
+#define BUG() do { diag_printf("BUG() at %s %d\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
+
+#endif /* __ASM_BUG_H__ */
diff --git a/packages/compat/linux/v2_0/include/asm/page.h b/packages/compat/linux/v2_0/include/asm/page.h
new file mode 100644 (file)
index 0000000..d77a39a
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __ASM_PAGE_H__
+#define __ASM_PAGE_H__
+
+#include <pkgconf/linux_compat.h>
+
+/* These aren't used by much yet. If that changes, you might want
+   to make them actually correct :) */
+#define PAGE_SIZE  (0x1 << PAGE_SHIFT)
+
+
+#endif /* __ASM_PAGE_H__ */
diff --git a/packages/compat/linux/v2_0/include/asm/semaphore.h b/packages/compat/linux/v2_0/include/asm/semaphore.h
new file mode 100644 (file)
index 0000000..e816155
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __ASM_SEMAPHORE_H__
+#define __ASM_SEMAPHORE_H__
+
+#include <cyg/hal/drv_api.h>
+
+struct semaphore {
+       cyg_drv_mutex_t x;
+};
+
+#define DECLARE_MUTEX(x) struct semaphore x = { { 0 } };
+#define DECLARE_MUTEX_LOCKED(x) struct semaphore x = { { 1 } };
+
+#define init_MUTEX(sem) cyg_drv_mutex_init((cyg_drv_mutex_t *)sem)
+#define init_MUTEX_LOCKED(sem) do { cyg_drv_mutex_init((cyg_drv_mutex_t *)sem); cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem); } while(0)
+#define down(sem) cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem)
+#define down_interruptible(sem) ({ cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem), 0; })
+#define down_trylock(sem) cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem)
+#define up(sem) cyg_drv_mutex_unlock((cyg_drv_mutex_t *)sem)
+
+#endif /* __ASM_SEMAPHORE_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/TODO b/packages/compat/linux/v2_0/include/linux/TODO
new file mode 100644 (file)
index 0000000..df8a6d1
--- /dev/null
@@ -0,0 +1,11 @@
+
+This contains a very limited set of Linux-compatibility headers, initially
+just for getting JFFS2 to build.
+
+Some things are simply stubs which don't _work_, to allow the JFFS2 code
+to compile. Note that you may need to implement these _properly_ in order
+to use these for making other Linux code work, or indeed for making the 
+JFFS2 NAND support work.
+
+The non-working parts include, but are not limited to: 
+       workqueue.h, wait.h, timer.h, spinlock.h, sched.h, compiler.h
diff --git a/packages/compat/linux/v2_0/include/linux/compiler.h b/packages/compat/linux/v2_0/include/linux/compiler.h
new file mode 100644 (file)
index 0000000..fb25365
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __LINUX_COMPILER_H__
+#define __LINUX_COMPILER_H__
+
+#define likely(x) (x)
+#define unlikely(x) (x)
+
+#endif /* __LINUX_COMPILER_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/completion.h b/packages/compat/linux/v2_0/include/linux/completion.h
new file mode 100644 (file)
index 0000000..f131af8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __LINUX_COMPLETION_H__
+#define __LINUX_COMPLETION_H__
+
+struct completion { } ;
+
+#endif /* __LINUX_COMPLETION_H__ */
+
diff --git a/packages/compat/linux/v2_0/include/linux/config.h b/packages/compat/linux/v2_0/include/linux/config.h
new file mode 100644 (file)
index 0000000..986e10b
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef __LINUX_CONFIG_H__
+#define __LINUX_CONFIG_H__
+
+
+#endif /* __LINUX_CONFIG_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/crc32.h b/packages/compat/linux/v2_0/include/linux/crc32.h
new file mode 100644 (file)
index 0000000..8d19a1e
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef CRC32_H
+#define CRC32_H
+
+#include <cyg/crc/crc.h>
+
+#define crc32(val, s, len) cyg_crc32_accumulate(val, (unsigned char *)s, len)
+
+#endif
diff --git a/packages/compat/linux/v2_0/include/linux/errno.h b/packages/compat/linux/v2_0/include/linux/errno.h
new file mode 100644 (file)
index 0000000..339f4fc
--- /dev/null
@@ -0,0 +1 @@
+#include <errno.h>
diff --git a/packages/compat/linux/v2_0/include/linux/fs.h b/packages/compat/linux/v2_0/include/linux/fs.h
new file mode 100644 (file)
index 0000000..c2f173a
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __LINUX_FS_H__
+#define __LINUX_FS_H__
+
+#include <linux/stat.h>
+/*
+ * File types
+ */
+#define DT_UNKNOWN     0
+#define DT_DIR         4
+#define DT_REG         8
+
+
+#endif /* __LINUX_FS_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/init.h b/packages/compat/linux/v2_0/include/linux/init.h
new file mode 100644 (file)
index 0000000..e4c702f
--- /dev/null
@@ -0,0 +1,3 @@
+#ifndef __LINUX_INIT_H__
+#define __LINUX_INIT_H__
+#endif
diff --git a/packages/compat/linux/v2_0/include/linux/kernel.h b/packages/compat/linux/v2_0/include/linux/kernel.h
new file mode 100644 (file)
index 0000000..3eb52d0
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __LINUX_KERNEL_H__
+#define __LINUX_KERNEL_H__
+#include <cyg/infra/diag.h>
+
+#define jiffies 100
+
+#define ERR_PTR(err) ((void*)(err))
+#define PTR_ERR(err) ((unsigned long)(err))
+#define IS_ERR(err) ((unsigned long)err > (unsigned long)-1000L)
+
+#define CURRENT_TIME cyg_timestamp()
+
+#define        KERN_EMERG              "<0>" // system is unusable
+#define        KERN_ALERT              "<1>" // action must be taken immediately
+#define        KERN_CRIT               "<2>" // critical conditions
+#define        KERN_ERR                "<3>" // error conditions
+#define        KERN_WARNING            "<4>" // warning conditions
+#define        KERN_NOTICE             "<5>" // normal but significant condition
+#define        KERN_INFO               "<6>" // informational
+#define        KERN_DEBUG              "<7>" // debug-level messages
+#define printk diag_printf
+
+#define min(x,y) (x<y?x:y)
+#define max(x,y) (x<y?y:x)
+#define min_t(t, x,y) ((t)x<(t)y?(t)x:(t)y)
+
+
+#endif /* __LINUX_KERNEL_H__ */
+
+
+
+
diff --git a/packages/compat/linux/v2_0/include/linux/list.h b/packages/compat/linux/v2_0/include/linux/list.h
new file mode 100644 (file)
index 0000000..a6b3f46
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * Created by Jonathan Larmour <jlarmour@redhat.com>
+ * 
+ *===========================================================================
+ *####ECOSGPLCOPYRIGHTBEGIN####
+ * -------------------------------------------
+ * This file is part of eCos, the Embedded Configurable Operating System.
+ * Copyright (C) 2003 Red Hat.
+ *
+ * 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.
+ *
+ * Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+ * at http://sources.redhat.com/ecos/ecos-license/
+ * -------------------------------------------
+ *####ECOSGPLCOPYRIGHTEND####
+ *===========================================================================
+ *
+ */
+
+#ifndef CYGONCE_FS_JFFS2_LIST_H
+#define CYGONCE_FS_JFFS2_LIST_H
+
+
+/* -----------------------------------------------------------------------*/
+
+/* Doubly linked list implementation to replace the GPL'd one used in
+   the Linux kernel. */
+
+#include <stddef.h>
+#include <cyg/infra/cyg_type.h>
+
+/* TYPES */
+
+struct list_head {
+    struct list_head *next;
+    struct list_head *prev;
+};
+
+/* MACROS */
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+        struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD( _list_ )              \
+CYG_MACRO_START                               \
+(_list_)->next = (_list_)->prev = (_list_);   \
+CYG_MACRO_END
+
+/* FUNCTIONS */
+
+/* Insert an entry _after_ the specified entry */
+static __inline__ void
+list_add( struct list_head *newent, struct list_head *afterthisent )
+{
+    struct list_head *next = afterthisent->next;
+    newent->next = next;
+    newent->prev = afterthisent;
+    afterthisent->next = newent;
+    next->prev = newent;
+} /* list_add() */
+
+/* Insert an entry _before_ the specified entry */
+static __inline__ void
+list_add_tail( struct list_head *newent, struct list_head *beforethisent )
+{
+    struct list_head *prev = beforethisent->prev;
+    newent->prev = prev;
+    newent->next = beforethisent;
+    beforethisent->prev = newent;
+    prev->next = newent;
+} /* list_add_tail() */
+
+/* Delete the specified entry */
+static __inline__ void
+list_del( struct list_head *ent )
+{
+    ent->prev->next = ent->next;
+    ent->next->prev = ent->prev;
+} /* list_del() */
+
+/* Is this list empty? */
+static __inline__ int
+list_empty( struct list_head *list )
+{
+    return ( list->next == list );
+} /* list_empty() */
+
+/* list_entry - Assuming you have a struct of type _type_ that contains a
+   list which has the name _member_ in that struct type, then given the
+   address of that list in the struct, _list_, this returns the address
+   of the container structure */
+
+#define list_entry( _list_, _type_, _member_ ) \
+    ((_type_ *)((char *)(_list_)-(char *)(offsetof(_type_,_member_))))
+
+/* list_for_each - using _ent_, iterate through list _list_ */
+
+#define list_for_each( _ent_, _list_ )   \
+    for ( (_ent_) = (_list_)->next;      \
+    (_ent_) != (_list_);                 \
+    (_ent_) = (_ent_)->next )
+
+/*
+ * list_for_each_entry - this function can be use to iterate over all
+ * items in a list* _list_ with it's head at _head_ and link _item_
+ */
+#define list_for_each_entry(_list_, _head_, _item_)                     \
+for ((_list_) = list_entry((_head_)->next, typeof(*_list_), _item_); \
+     &((_list_)->_item_) != (_head_);                                 \
+     (_list_) = list_entry((_list_)->_item_.next, typeof(*_list_), _item_))
+
+/* -----------------------------------------------------------------------*/
+#endif /* #ifndef CYGONCE_FS_JFFS2_LIST_H */
+/* EOF list.h */
diff --git a/packages/compat/linux/v2_0/include/linux/mtd/compatmac.h b/packages/compat/linux/v2_0/include/linux/mtd/compatmac.h
new file mode 100644 (file)
index 0000000..cee3749
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef __LINUX_MTD_COMPATMAC_H__
+#define __LINUX_MTD_COMPATMAC_H__
+
+
+#endif /* __LINUX_MTD_COMPATMAC_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/mtd/mtd.h b/packages/compat/linux/v2_0/include/linux/mtd/mtd.h
new file mode 100644 (file)
index 0000000..817d31c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef __LINUX_MTD_MTD_H__
+#define __LINUX_MTD_MTD_H__
+
+
+#endif /* __LINUX_MTD_MTD_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/pagemap.h b/packages/compat/linux/v2_0/include/linux/pagemap.h
new file mode 100644 (file)
index 0000000..fccf9c4
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __LINUX_PAGEMAP_H__
+#define __LINUX_PAGEMAP_H__
+
+#include <asm/bug.h>
+#include <asm/page.h>
+
+#define PAGE_CACHE_SHIFT        PAGE_SHIFT
+#define PAGE_CACHE_SIZE         PAGE_SIZE
+
+#define PageLocked(pg) 1
+#define Page_Uptodate(pg) 0
+#define UnlockPage(pg) 
+#define PAGE_BUG(pg) BUG()
+#define ClearPageUptodate(pg)
+#define SetPageError(pg)
+#define ClearPageError(pg)
+#define SetPageUptodate(pg)
+
+#endif /* __LINUX_PAGEMAP_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/rbtree.h b/packages/compat/linux/v2_0/include/linux/rbtree.h
new file mode 100644 (file)
index 0000000..fef5f71
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef        _LINUX_RBTREE_H
+#define        _LINUX_RBTREE_H
+
+
+struct rb_node {
+       struct rb_node *rb_left;        /* left element */
+       struct rb_node *rb_right;       /* right element */
+       struct rb_node *rb_parent;      /* parent element */
+       int rb_color;                   /* node color */
+};
+
+struct rb_root {
+       struct rb_node *rb_node; /* root of the tree */
+};
+#define NULL ((void *)0)
+#define RB_ROOT ((struct rb_root){NULL})
+#define rb_entry(p, container, field)          \
+       ((container *) ((char *)p - ((char *)&(((container *)0)->field))))
+
+#define RB_BLACK       0
+#define RB_RED         1
+
+
+extern void rb_insert_color(struct rb_node *, struct rb_root *);
+extern void rb_erase(struct rb_node *, struct rb_root *);
+
+/* Find logical next and previous nodes in a tree */
+extern struct rb_node *rb_next(struct rb_node *);
+extern struct rb_node *rb_prev(struct rb_node *);
+extern struct rb_node *rb_first(struct rb_root *);
+
+/* Fast replacement of a single node without remove/rebalance/add/rebalance */
+extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, 
+                           struct rb_root *root);
+
+static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
+                               struct rb_node ** rb_link)
+{
+       node->rb_parent = parent;
+       node->rb_color = RB_RED;
+       node->rb_left = node->rb_right = NULL;
+
+       *rb_link = node;
+}
+
+#endif /* _LINUX_RBTREE_H */
diff --git a/packages/compat/linux/v2_0/include/linux/rwsem.h b/packages/compat/linux/v2_0/include/linux/rwsem.h
new file mode 100644 (file)
index 0000000..d648a15
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __LINUX_RWSEM_H__
+#define __LINUX_RWSEM_H__
+
+// eCos does not have the concept of a read/write semaphore. So just
+// map them onto normal semaphores and hope we don't deadlock
+// somewhere.
+
+#include <asm/semaphore.h>
+
+struct rw_semaphore;
+
+#define down_read(sem) cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem)
+#define down_read_trylock(sem) cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem)
+#define down_write(sem) cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem)
+#define down_write_trylock(sem) cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem)
+#define up_read(sem) cyg_drv_mutex_unlock((cyg_drv_mutex_t *)sem)
+#define up_write(sem) cyg_drv_mutex_unlock((cyg_drv_mutex_t *)sem)
+#define downgrade_write(sem) 
+
+#endif // __LINUX_RWSEM_H__ 
diff --git a/packages/compat/linux/v2_0/include/linux/sched.h b/packages/compat/linux/v2_0/include/linux/sched.h
new file mode 100644 (file)
index 0000000..14a7359
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __LINUX_SCHED_H__
+#define __LINUX_SCHED_H__
+
+#define cond_resched() do { } while(0)
+#define signal_pending(x) (0)
+
+#endif /* __LINUX_SCHED_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/slab.h b/packages/compat/linux/v2_0/include/linux/slab.h
new file mode 100644 (file)
index 0000000..fff3949
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __LINUX_SLAB_H__
+#define __LINUX_SLAB_H__
+
+#include <stdlib.h>
+
+#include <asm/page.h> /* Don't ask. Linux headers are a mess. */
+
+#define kmalloc(x, y) malloc(x)
+#define kfree(x) free(x)
+#define vmalloc(x) malloc(x)
+#define vfree(x) free(x)
+
+#endif /* __LINUX_SLAB_H__ */
+
diff --git a/packages/compat/linux/v2_0/include/linux/spinlock.h b/packages/compat/linux/v2_0/include/linux/spinlock.h
new file mode 100644 (file)
index 0000000..22eba0b
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __LINUX_SPINLOCK_H__
+#define __LINUX_SPINLOCK_H__
+
+
+typedef struct { } spinlock_t;
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { }
+#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
+
+#define spin_lock_init(lock)             \
+CYG_MACRO_START;                         \
+CYG_UNUSED_PARAM(spinlock_t *, lock);    \
+CYG_MACRO_END
+
+#define spin_lock(lock)                  \
+CYG_MACRO_START;                         \
+CYG_UNUSED_PARAM(spinlock_t *, lock);    \
+CYG_MACRO_END
+
+#define spin_unlock(lock)                \
+CYG_MACRO_START;                         \
+CYG_UNUSED_PARAM(spinlock_t *, lock);    \
+CYG_MACRO_END
+
+#define spin_lock_bh(lock)               \
+CYG_MACRO_START;                         \
+CYG_UNUSED_PARAM(spinlock_t *, lock);    \
+CYG_MACRO_END
+
+#define spin_unlock_bh(lock)             \
+CYG_MACRO_START;                         \
+CYG_UNUSED_PARAM(spinlock_t *, lock);    \
+CYG_MACRO_END
+
+#endif /* __LINUX_SPINLOCK_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/stat.h b/packages/compat/linux/v2_0/include/linux/stat.h
new file mode 100644 (file)
index 0000000..a3efd61
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __LINUX_STAT_H__
+#define __LINUX_STAT_H__
+
+
+#include <sys/stat.h>
+
+#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
+#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
+#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
+#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
+
+#endif /* __LINUX_STAT_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/string.h b/packages/compat/linux/v2_0/include/linux/string.h
new file mode 100644 (file)
index 0000000..fc14ba6
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __LINUX_STRING_H__
+#define __LINUX_STRING_H__
+
+#include <string.h>
+
+#endif /* __LINUX_STRING_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/timer.h b/packages/compat/linux/v2_0/include/linux/timer.h
new file mode 100644 (file)
index 0000000..80e9ef5
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __LINUX_TIMER_H__
+#define __LINUX_TIMER_H__
+
+/* Not yet */
+
+struct timer_list { } ;
+
+
+#endif /* __LINUX_TIMER_H__ */
+
diff --git a/packages/compat/linux/v2_0/include/linux/types.h b/packages/compat/linux/v2_0/include/linux/types.h
new file mode 100644 (file)
index 0000000..e58fc25
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __LINUX_TYPES_H__
+#define __LINUX_TYPES_H__
+
+#include "cyg/infra/cyg_type.h"
+
+#define uint8_t cyg_uint8
+#define uint16_t cyg_uint16
+#define uint32_t cyg_uint32
+#define loff_t off_t
+
+#define kvec iovec
+#endif /* __LINUX_TYPES_H__ */
+
diff --git a/packages/compat/linux/v2_0/include/linux/version.h b/packages/compat/linux/v2_0/include/linux/version.h
new file mode 100644 (file)
index 0000000..cca2d73
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef __LINUX_VERSION_H__
+#define __LINUX_VERSION_H__
+
+
+#endif /* __LINUX_VERSION_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/vmalloc.h b/packages/compat/linux/v2_0/include/linux/vmalloc.h
new file mode 100644 (file)
index 0000000..6f18ab2
--- /dev/null
@@ -0,0 +1,3 @@
+#ifndef __LINUX_VMALLOC_H__
+#define __LINUX_VMALLOC_H__
+#endif
diff --git a/packages/compat/linux/v2_0/include/linux/wait.h b/packages/compat/linux/v2_0/include/linux/wait.h
new file mode 100644 (file)
index 0000000..2b422e3
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __LINUX_WAIT_H__
+#define __LINUX_WAIT_H__
+
+
+typedef struct { } wait_queue_head_t;
+
+#define init_waitqueue_head(wait) do{} while (0)
+#define add_wait_queue(wait,new_wait) do{} while (0)
+#define remove_wait_queue(wait,old_wait) do{} while (0)
+#define DECLARE_WAITQUEUE(wait,current) do{} while (0)
+
+static inline void wake_up(wait_queue_head_t *erase_wait)
+{ /* Only used for waking up threads blocks on erases. Not used in eCos */ }
+
+#endif /* __LINUX_WAIT_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/workqueue.h b/packages/compat/linux/v2_0/include/linux/workqueue.h
new file mode 100644 (file)
index 0000000..8c900a4
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __LINUX_WORKQUEUE_H__
+#define __LINUX_WORKQUEUE_H__
+
+/* We don't do this yet */
+struct work_struct { } ;
+
+#define INIT_WORK(x,y,z) /* */
+#define schedule_work(x) do { } while(0)
+#define flush_scheduled_work() do { } while(0)
+
+#endif /* __LINUX_WORKQUEUE_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/zlib.h b/packages/compat/linux/v2_0/include/linux/zlib.h
new file mode 100644 (file)
index 0000000..9de691e
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __LINUX_ZLIB_H__
+#define __LINUX_ZLIB_H__
+
+#include <cyg/compress/zlib.h>
+
+#define zlib_deflateInit(x,y) deflateInit(x,y)
+#define zlib_deflate(x,y) deflate(x,y)
+#define zlib_deflateEnd(x) deflateEnd(x)
+#define zlib_inflateInit(x) inflateInit(x)
+#define zlib_inflateInit2(x,y) inflateInit2(x,y)
+#define zlib_inflate(x,y) inflate(x,y)
+#define zlib_inflateEnd(x) inflateEnd(x)
+
+#endif /* __LINUX_ZLIB_H__ */
diff --git a/packages/compat/linux/v2_0/include/linux/zutil.h b/packages/compat/linux/v2_0/include/linux/zutil.h
new file mode 100644 (file)
index 0000000..c3774ba
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __LINUX_ZUTIL_H__
+#define __LINUX_ZUTIL_H__
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+#endif /* __LINUX_ZUTIL_H__ */
diff --git a/packages/compat/linux/v2_0/src/rbtree.c b/packages/compat/linux/v2_0/src/rbtree.c
new file mode 100644 (file)
index 0000000..1ad19c8
--- /dev/null
@@ -0,0 +1,409 @@
+/*========================================================================
+//
+//      rbtree.c
+//
+//      Red Black tree implementation
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     Niels Provos/OpenBSD
+// Contributors:  dwmw2
+// Date:          2003-01-21
+// Purpose:       This file provides an implementation of red-black trees.
+// Description:   Derived from OpenBSD src/sys/sys/tree.h
+// Usage:         
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/*     $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $    */
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Fields renamed to match Linux ones. */
+#include <linux/rbtree.h>
+
+
+#define RB_HEAD(head)          (head)->rb_node
+#define RB_LEFT(elm)           (elm)->rb_left
+#define RB_RIGHT(elm)          (elm)->rb_right
+#define RB_PARENT(elm)         (elm)->rb_parent
+#define RB_COLOR(elm)          (elm)->rb_color
+
+
+#define RB_SET(elm, parent) do {                               \
+       RB_PARENT(elm) = parent;                                \
+       RB_LEFT(elm) = RB_RIGHT(elm) = NULL;    \
+       RB_COLOR(elm) = RB_RED;                         \
+} while (0)
+
+#define RB_SET_BLACKRED(black, red) do {                       \
+       RB_COLOR(black) = RB_BLACK;                             \
+       RB_COLOR(red) = RB_RED;                                 \
+} while (0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp) do {                    \
+       (tmp) = RB_RIGHT(elm);                                  \
+       if ((RB_RIGHT(elm) = RB_LEFT(tmp))) {                   \
+               RB_PARENT(RB_LEFT(tmp)) = (elm);                \
+       }                                                       \
+       RB_AUGMENT(elm);                                        \
+       if ((RB_PARENT(tmp) = RB_PARENT(elm))) {                \
+               if ((elm) == RB_LEFT(RB_PARENT(elm)))           \
+                       RB_LEFT(RB_PARENT(elm)) = (tmp);        \
+               else                                            \
+                       RB_RIGHT(RB_PARENT(elm)) = (tmp);       \
+       } else                                                  \
+               (head)->rb_node = (tmp);                        \
+       RB_LEFT(tmp) = (elm);                                   \
+       RB_PARENT(elm) = (tmp);                                 \
+       RB_AUGMENT(tmp);                                        \
+       if ((RB_PARENT(tmp)))                                   \
+               RB_AUGMENT(RB_PARENT(tmp));                     \
+} while (0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp) do {                   \
+       (tmp) = RB_LEFT(elm);                                   \
+       if ((RB_LEFT(elm) = RB_RIGHT(tmp))) {                   \
+               RB_PARENT(RB_RIGHT(tmp)) = (elm);               \
+       }                                                       \
+       RB_AUGMENT(elm);                                        \
+       if ((RB_PARENT(tmp) = RB_PARENT(elm))) {                \
+               if ((elm) == RB_LEFT(RB_PARENT(elm)))           \
+                       RB_LEFT(RB_PARENT(elm)) = (tmp);        \
+               else                                            \
+                       RB_RIGHT(RB_PARENT(elm)) = (tmp);       \
+       } else                                                  \
+               (head)->rb_node = (tmp);                        \
+       RB_RIGHT(tmp) = (elm);                                  \
+       RB_PARENT(elm) = (tmp);                                 \
+       RB_AUGMENT(tmp);                                        \
+       if ((RB_PARENT(tmp)))                                   \
+               RB_AUGMENT(RB_PARENT(tmp));                     \
+} while(0)
+
+/* Note args swapped to match Linux */
+void rb_insert_color(struct rb_node *elm, struct rb_root *head)
+{
+       struct rb_node *parent, *gparent, *tmp;
+       while ((parent = RB_PARENT(elm)) &&
+           RB_COLOR(parent) == RB_RED) {
+               gparent = RB_PARENT(parent);
+               if (parent == RB_LEFT(gparent)) {
+                       tmp = RB_RIGHT(gparent);
+                       if (tmp && RB_COLOR(tmp) == RB_RED) {
+                               RB_COLOR(tmp) = RB_BLACK;
+                               RB_SET_BLACKRED(parent, gparent);
+                               elm = gparent;
+                               continue;
+                       }
+                       if (RB_RIGHT(parent) == elm) {
+                               RB_ROTATE_LEFT(head, parent, tmp);
+                               tmp = parent;
+                               parent = elm;
+                               elm = tmp;
+                       }
+                       RB_SET_BLACKRED(parent, gparent);
+                       RB_ROTATE_RIGHT(head, gparent, tmp);
+               } else {
+                       tmp = RB_LEFT(gparent);
+                       if (tmp && RB_COLOR(tmp) == RB_RED) {
+                               RB_COLOR(tmp) = RB_BLACK;
+                               RB_SET_BLACKRED(parent, gparent);
+                               elm = gparent;
+                               continue;
+                       }
+                       if (RB_LEFT(parent) == elm) {
+                               RB_ROTATE_RIGHT(head, parent, tmp);
+                               tmp = parent;
+                               parent = elm;
+                               elm = tmp;
+                       }
+                       RB_SET_BLACKRED(parent, gparent);
+                       RB_ROTATE_LEFT(head, gparent, tmp);
+               }
+       }
+       RB_COLOR(head->rb_node) = RB_BLACK;
+}
+
+
+static void rb_remove_color(struct rb_root *head, struct rb_node *parent,
+                           struct rb_node *elm)
+{
+       struct rb_node *tmp;
+       while ((elm == NULL || RB_COLOR(elm) == RB_BLACK) &&
+           elm != RB_HEAD(head)) {
+               if (RB_LEFT(parent) == elm) {
+                       tmp = RB_RIGHT(parent);
+                       if (RB_COLOR(tmp) == RB_RED) {
+                               RB_SET_BLACKRED(tmp, parent);
+                               RB_ROTATE_LEFT(head, parent, tmp);
+                               tmp = RB_RIGHT(parent);
+                       }
+                       if ((RB_LEFT(tmp) == NULL ||
+                           RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
+                           (RB_RIGHT(tmp) == NULL ||
+                           RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
+                               RB_COLOR(tmp) = RB_RED;
+                               elm = parent;
+                               parent = RB_PARENT(elm);
+                       } else {
+                               if (RB_RIGHT(tmp) == NULL ||
+                                   RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK) {
+                                       struct rb_node *oleft;
+                                       if ((oleft = RB_LEFT(tmp)))
+                                               RB_COLOR(oleft) = RB_BLACK;
+                                       RB_COLOR(tmp) = RB_RED;
+                                       RB_ROTATE_RIGHT(head, tmp, oleft);
+                                       tmp = RB_RIGHT(parent);
+                               }
+                               RB_COLOR(tmp) = RB_COLOR(parent);
+                               RB_COLOR(parent) = RB_BLACK;
+                               if (RB_RIGHT(tmp))
+                                       RB_COLOR(RB_RIGHT(tmp)) = RB_BLACK;
+                               RB_ROTATE_LEFT(head, parent, tmp);
+                               elm = RB_HEAD(head);
+                               break;
+                       }
+               } else {
+                       tmp = RB_LEFT(parent);
+                       if (RB_COLOR(tmp) == RB_RED) {
+                               RB_SET_BLACKRED(tmp, parent);
+                               RB_ROTATE_RIGHT(head, parent, tmp);
+                               tmp = RB_LEFT(parent);
+                       }
+                       if ((RB_LEFT(tmp) == NULL ||
+                           RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) &&
+                           (RB_RIGHT(tmp) == NULL ||
+                           RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) {
+                               RB_COLOR(tmp) = RB_RED;
+                               elm = parent;
+                               parent = RB_PARENT(elm);
+                       } else {
+                               if (RB_LEFT(tmp) == NULL ||
+                                   RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) {
+                                       struct rb_node *oright;
+                                       if ((oright = RB_RIGHT(tmp)))
+                                               RB_COLOR(oright) = RB_BLACK;
+                                       RB_COLOR(tmp) = RB_RED;
+                                       RB_ROTATE_LEFT(head, tmp, oright);
+                                       tmp = RB_LEFT(parent);
+                               }
+                               RB_COLOR(tmp) = RB_COLOR(parent);
+                               RB_COLOR(parent) = RB_BLACK;
+                               if (RB_LEFT(tmp))
+                                       RB_COLOR(RB_LEFT(tmp)) = RB_BLACK;
+                               RB_ROTATE_RIGHT(head, parent, tmp);
+                               elm = RB_HEAD(head);
+                               break;
+                       }
+               }
+       }
+       if (elm)
+               RB_COLOR(elm) = RB_BLACK;
+}
+
+/* Note name changed. Guess why :) */
+void rb_erase(struct rb_node *elm, struct rb_root *head)
+{
+       struct rb_node *child, *parent, *old = elm;
+       int color;
+       if (RB_LEFT(elm) == NULL)
+               child = RB_RIGHT(elm);
+       else if (RB_RIGHT(elm) == NULL)
+               child = RB_LEFT(elm);
+       else {
+               struct rb_node *left;
+               elm = RB_RIGHT(elm);
+               while ((left = RB_LEFT(elm)))
+                       elm = left;
+               child = RB_RIGHT(elm);
+               parent = RB_PARENT(elm);
+               color = RB_COLOR(elm);
+               if (child)
+                       RB_PARENT(child) = parent;
+               if (parent) {
+                       if (RB_LEFT(parent) == elm)
+                               RB_LEFT(parent) = child;
+                       else
+                               RB_RIGHT(parent) = child;
+                       RB_AUGMENT(parent);
+               } else
+                       RB_HEAD(head) = child;
+               if (RB_PARENT(elm) == old)
+                       parent = elm;
+               *(elm) = *(old);
+               if (RB_PARENT(old)) {
+                       if (RB_LEFT(RB_PARENT(old)) == old)
+                               RB_LEFT(RB_PARENT(old)) = elm;
+                       else
+                               RB_RIGHT(RB_PARENT(old)) = elm;
+                       RB_AUGMENT(RB_PARENT(old));
+               } else
+                       RB_HEAD(head) = elm;
+               RB_PARENT(RB_LEFT(old)) = elm;
+               if (RB_RIGHT(old))
+                       RB_PARENT(RB_RIGHT(old)) = elm;
+               if (parent) {
+                       left = parent;
+                       do {
+                               RB_AUGMENT(left);
+                       } while ((left = RB_PARENT(left)));
+               }
+               goto color;
+       }
+       parent = RB_PARENT(elm);
+       color = RB_COLOR(elm);
+       if (child)
+               RB_PARENT(child) = parent;
+       if (parent) {
+               if (RB_LEFT(parent) == elm)
+                       RB_LEFT(parent) = child;
+               else
+                       RB_RIGHT(parent) = child;
+               RB_AUGMENT(parent);
+       } else
+               RB_HEAD(head) = child;
+color:
+       if (color == RB_BLACK)
+               rb_remove_color(head, parent, child);
+}
+
+struct rb_node *rb_next(struct rb_node *elm)
+{
+       if (RB_RIGHT(elm)) {
+               elm = RB_RIGHT(elm);
+               while (RB_LEFT(elm))
+                       elm = RB_LEFT(elm);
+       } else {
+               if (RB_PARENT(elm) &&
+                   (elm == RB_LEFT(RB_PARENT(elm))))
+                       elm = RB_PARENT(elm);
+               else {
+                       while (RB_PARENT(elm) &&
+                           (elm == RB_RIGHT(RB_PARENT(elm))))
+                               elm = RB_PARENT(elm);
+                       elm = RB_PARENT(elm);
+               }
+       }
+       return (elm);
+}
+
+struct rb_node *rb_prev(struct rb_node *elm)
+{
+       if (RB_LEFT(elm)) {
+               elm = RB_LEFT(elm);
+               while (RB_RIGHT(elm))
+                       elm = RB_RIGHT(elm);
+       } else {
+               if (RB_PARENT(elm) &&
+                   (elm == RB_RIGHT(RB_PARENT(elm))))
+                       elm = RB_PARENT(elm);
+               else {
+                       while (RB_PARENT(elm) &&
+                           (elm == RB_LEFT(RB_PARENT(elm))))
+                               elm = RB_PARENT(elm);
+                       elm = RB_PARENT(elm);
+               }
+       }
+       return (elm);
+}
+
+/* These ones are lifted from Linux -- but that's OK because I
+   wrote them. dwmw2. */
+struct rb_node *rb_first(struct rb_root *root)
+{
+        struct rb_node  *n;
+
+        n = root->rb_node;
+        if (!n)
+                return 0;
+        while (n->rb_left)
+                n = n->rb_left;
+        return n;
+}
+
+void rb_replace_node(struct rb_node *victim, struct rb_node *new,
+                     struct rb_root *root)
+{
+        struct rb_node *parent = victim->rb_parent;
+
+        /* Set the surrounding nodes to point to the replacement */
+        if (parent) {
+                if (victim == parent->rb_left)
+                        parent->rb_left = new;
+                else
+                        parent->rb_right = new;
+        } else {
+                root->rb_node = new;
+        }
+        if (victim->rb_left)
+                victim->rb_left->rb_parent = new;
+        if (victim->rb_right)
+                victim->rb_right->rb_parent = new;
+
+        /* Copy the pointers/colour from the victim to the replacement */
+        *new = *victim;
+}
diff --git a/packages/compat/posix/v2_0/ChangeLog b/packages/compat/posix/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..4eed209
--- /dev/null
@@ -0,0 +1,1094 @@
+2004-10-01  Oyvind Harboe  <oyvind.harboe@zylin.com>
+
+       * src/signal.cxx:  place the CYGBLD_ATTRIB_INIT_PRI such that it
+       compiles for gcc 3.4.2 which is more picky about its placement.
+
+2003-12-02  Sandeep  <sandeep@codito.com>
+
+       * src/mqueue.cxx (new): define a placement new instead of using <new>
+
+2003-11-19  Rickard Westman <rickard.westman@27m.se>
+       
+       * src/mqueue.cxx: Fix problem with mq_timedsend() and
+       mq_timedreceive() timing out with zero timeouts even when there is
+       room in the queue.
+
+2003-11-17  Dan Jakubiec <djakubiec@yahoo.com>
+
+       * src/pthread.cxx (pthread_exit): Added code to disable cancellation
+       requests during thread exit.  This allows thread cleanup handlers
+       to issue system calls when cleaning up thread resources.
+
+2003-06-18  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * src/pthread.cxx (pthread_self_info): Just add some comments so
+       no-one's tempted to uncomment assert.
+       (pthread_create): Verify that self is a valid POSIX thread when
+       needed.
+
+2003-03-20  Mark Salter  <msalter@redhat.com>
+
+       * include/pthread.h: Avoid conflict with recently introduced gcc
+       __thread keyword.
+
+2003-03-13  Bart Veer  <bartv@ecoscentric.com>
+
+       * include/export.h: Only export signal-related functions if
+       CYGPKG_POSIX_SIGNALS is enabled.
+
+2003-03-04  Gary Thomas  <gary@mlbassoc.com>
+
+       * include/pthread.h: Rework prototypes to minimize namespace problems.
+
+2003-03-03  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * tests/signal2.c (cause_illegal_access): PowerPC only generates
+       alignment exceptions in little-endian mode, so make that a special
+       case.
+
+       * tests/mutex3.c: Include POSIX headers before feature tests to
+       prevent spurious CYG_TEST_NA.
+
+2003-02-24  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * doc/posix.sgml: Expunge EL/IX. Dead standard.
+       * cdl/posix.cdl: Add doc link.
+
+2003-02-13  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * src/mutex.cxx: Include sched.hxx for scheduler lock/unlock primitives.
+       Reported by Jani Monoses.
+
+2003-02-10  Gary Thomas  <gary@mlbassoc.com>
+
+       * tests/signal3.c (main): Reorg code so it builds with older GCC.
+
+2003-01-31  Nick Garnett  <nickg@calivar.com>
+
+       * src/time.cxx (alarm_action): Added call to
+       cyg_posix_signal_sigwait() to wake up any sigwait()ing threads.
+
+       * src/signal.cxx (cyg_posix_signal_sigwait): Added this function
+       to export access to signal_sigwait conditional variable.
+       (sigtimedwait): Added call to cyg_posix_timer_asr() to allow timer
+       signals to be delivered here.
+
+       * src/pprivate.h: Added prototype for cyg_posix_signal_sigwait().
+
+       * cdl/posix.cdl:
+       * tests/signal3.c: Added this program to test interaction of
+       timers and signals, particularly sigwait(). Based on a test
+       program from N.Suresh <nsuresh@cdotb.ernet.in>.
+
+2003-01-20  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * src/signal.cxx (cyg_posix_deliver_signals): silence warning.
+
+       * src/time.cxx (cyg_timespec_to_ticks): Remove use of default arg in
+       definition.
+
+2003-01-18  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * src/mqueue.cxx: Fix multi-line string literal warning.
+
+2003-01-13  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * doc/posix.sgml: Document them.
+
+       * src/mqueue.cxx (mq_timedreceive): Make fully compliant by dealing
+       with bogus timeouts.
+       (mq_timedsend): Ditto.
+
+2003-01-13  Dmitriy Korovkin  <dkorovkin@rambler.ru>
+
+       * src/mqueue.cxx (mq_timedsend): New function. Implementing POSIX
+       1003.1d draft definition.
+       (mq_timedreceive): Ditto.
+
+2002-12-10  Wade Jensen  <waj4news@cox.net>
+2002-12-10  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * src/mutex.cxx (pthread_cond_timedwait): Initialize clock converters
+       only once ever.
+
+2002-11-26  Nick Garnett  <nickg@ecoscentric.com>
+
+       * src/signal.cxx: Changed the three routines added in the last
+       change so that they can be called safely from non-POSIX threads.
+
+2002-11-10  Nick Garnett  <nickg@ecoscentric.com>
+
+       * src/signal.cxx: Added three exportable routines that may be used
+       by other packages to manipulate the signal mask, test for
+       deliverable signals, and have signals delivered at controlled
+       points.
+
+       * include/export.h: Added macros to export signal mask management,
+       detection and delivery to other packages.
+
+2002-11-05  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * tests/tm_basic.cxx: Use <cyg/infra/diag.h> for diag_printf
+       prototype.
+
+2002-05-23  Jesper Skov  <jskov@redhat.com>
+
+       * cdl/posix.cdl: Don't build tests using signals when posix
+       signals are disabled.
+
+2002-05-21  Jesper Skov  <jskov@redhat.com>
+
+       * tests/mutex3.c: Added an NA check.
+
+2002-04-09  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/signal.cxx (cyg_deliver_signals): Don't assert here for an
+       unhandled signal (unless there's no _exit). Trace it though.
+
+2002-04-08  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/sem.cxx (sem_getvalue): return 0, and put value in *sval.
+
+2002-04-03  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * cdl/posix.cdl: Allow clocks to be configured again.
+
+2002-03-05  Jesper Skov  <jskov@redhat.com>
+
+       * src/pprivate.h: Correct conditional declaration of timespec
+       functions.
+
+       * src/sched.cxx (sched_rr_get_interval): Return ENOSYS when
+       CYGPKG_POSIX_CLOCKS disabled.
+
+2002-02-27  Robin Farine  <robin.farine@terminus.org>
+
+       * src/pthread.cxx (pthread_exit): While running thread static
+       storage destructors, set the thread's value associated with the
+       current key to NULL before invoking the destructor.
+
+2002-02-14  Nick Garnett  <nickg@redhat.com>
+
+       * doc/posix.sgml: Generally fixed up and reformatted to make this
+       file readable by mere humans. Some omissions and outdated
+       information fixed, but not substantially changed from the
+       original.
+
+       * cdl/posix.cdl: Changed some definitions and dependencies so that
+       disabling the timers does not disable threads too. This was
+       largely a consequence of trying to document the behaviour of these
+       options.
+       
+2002-02-14  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * doc/posix.sgml: New file, originally accompanied by this ChangeLog:
+       2001-12-22  Jonathan Larmour  <jlarmour@redhat.com>
+       
+               * ecos-elix.sgml: Do a minor cleanup of the function prototype
+               layouts.
+               Should be done better than this, but this is at least not
+               _completely_ wrong any more.
+               Also several more layout problems due to incorrect tags fixed.
+       
+       2001-12-07  Jonathan Larmour  <jlarmour@redhat.com>
+       
+               * ecos-elix.sgml: Add getcwd as supported now.
+       
+       2001-12-06  Jonathan Larmour  <jlarmour@redhat.com>
+       
+               * ecos-elix.sgml: Created from old framemaker version.
+       
+2002-01-21  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/sched.cxx (sched_get_priority_min): Don't allow idle thread
+       priority as a valid priority.
+       Case #106952.
+
+2001-12-11  Nick Garnett  <nickg@redhat.com>
+
+       * tests/mqueue2.c (cyg_user_start): Added CYG_TEST_INIT() to
+       NOTAPPLICABLE variant, otherwise the order of breakpoints are all
+       wrong and the testfarm registers a failure.
+
+2001-11-06  Gary Thomas  <gthomas@redhat.com>
+
+       * include/muttypes.h: Need <pkgconf/kernel.h> configuration info,
+       otherwise structures defined here could have the wrong size.
+
+2001-10-25  I-Jui Sung <ijsung@csie.nctu.edu.tw>
+
+       * src/mqueue.cxx (do_mq_unlink): Nullify table entries' mq as this
+       is used by mq_open to see if the entry is used.
+
+2001-10-11  Jesper Skov  <jskov@redhat.com>
+
+       * tests/mutex3.c: Fixed warning. 
+       (new_thread): Fixed allocation: increase counter
+       before starting threads which have been allocated resources.
+
+       * tests/signal2.c (cause_illegal_access): Fix warning.
+
+2001-10-10  Jesper Skov  <jskov@redhat.com>
+
+       * cdl/posix.cdl: Only build sem.cxx when the semaphores component
+       is enabled.
+
+2001-10-09  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/pprivate.h (pthread_info): Conditionalize signal specific
+       members. Conditionalize declaration of 
+       cyg_posix_pthread_release_thread().     
+
+       * cdl/posix.cdl (CYGPKG_POSIX_CLOCKS): new option to separately
+       configure posix clocks from timers.
+       (CYGPKG_POSIX_TIMERS): require clocks and signals.
+
+       * include/time.h: Make proper ISO C. Conditionalize on
+       CYGPKG_POSIX_TIMERS correctly wrt the above change.
+
+       * src/pthread.cxx (posix_asr): Call signal and timer subsystems
+       conditionally.
+
+       * src/pthread.cxx (pthread_reap): Don't destroy signal handling
+       fields if there is no signal handling subsystem.
+       (cyg_posix_pthread_release_thread): Conditionalize on signals.
+       (pthread_create): Init signal subsys conditionally.
+
+       * src/signal.cxx (sleep): Move to...
+
+       * src/time.cxx: ...here.
+       Conditionalize throughout depending on whether it's POSIX clocks
+       or more specifically POSIX timers.
+       (nanosleep): Use PTHREAD_TESTCANCEL() not pthread_testcancel().
+       Get current thread from kernel not pthreads to remove pthread
+       dependency.
+
+2001-10-09  Jesper Skov  <jskov@redhat.com>
+
+       * tests/signal2.c: Also do NA check for signals.
+
+2001-10-01  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/mqueue.cxx (mq_open): Conditionalize use of sigev correctly.
+       (mq_close): Similarly.
+
+2001-09-28  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * cdl/pthread.cdl (CYGNUM_POSIX_MAIN_DEFAULT_PRIORITY): Clarify
+       POSIX thread priority description.
+
+2001-09-28  Jesper Skov  <jskov@redhat.com>
+
+       * cdl/pthread.cdl: Changed default priority of POSIX main to
+       16. This allows service threads (such as DHCP thread) to run when
+       started from main().
+
+2001-09-10  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * include/pthread.h: Separate mutex and condvar API into separate
+       header file to fix configury problems.
+       * include/mutex.h: New file for the above.
+       * cdl/posix.cdl: provide the correct configury for the isoinfra
+       package to include the above file.
+       * cdl/pthread.cdl: Move _POSIX_PTHREAD_PRIO_INHERIT and
+       _POSIX_THREAD_PRIO_PROTECT to cdl/posix.cdl.
+       
+2001-09-07  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/sem.cxx (sem_trywait): Actually use the return value.
+
+       * src/sched.cxx (sched_get_priority_max): Use MAX not MIN
+       (sched_get_priority_min): Use MIN not MAX.
+
+2001-09-06  Jesper Skov  <jskov@redhat.com>
+
+       * cdl/posix.cdl: Moved signal implements statements to the
+       CYGPKG_POSIX_SIGNALS component.
+
+2001-08-06  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * cdl/posix.cdl: Reorganize dependencies so that signals, timers
+       and pthreads really can be disabled, and the relevant files don't
+       get built.
+       Build new mutex.cxx file.
+       Remove duplicate CYGPKG_POSIX_SCHED dependency for pthreads.
+
+       * include/limits.h: Don't include irrelevant header dependencies.
+
+       * include/muttypes.h: New type defining mutex/cond var types separately
+       from other pthread types.
+
+       * include/types.h: Remove mutex/cond var types.
+
+       * include/signal.h: Conditionalize on CYGPKG_POSIX_SIGNALS
+
+       * include/sigsetjmp.h: Don't include irrelevant header dependencies.
+       Rewrite sigsetjmp in a much more compiler friendly (and readable)
+       way with less type punning.
+
+       * src/misc.cxx: Don't include sysconf cases when pthreads or
+       CYGPKG_POSIX_TIMERS not enabled.
+
+       * src/mutex.cxx: New file, broken out of pthreads.cxx, as most
+       of it is not fixed to the pthreads implementation, and I've fixed
+       the bits that were too tied to it.
+
+       * src/pprivate.h: Conditionalize definitions that are specific
+       to CYGPKG_POSIX_PTHREAD. Ditto for prototypes for CYGPKG_POSIX_SIGNALS
+       and CYGPKG_POSIX_TIMERS. Move PTHREAD_ENTRY/RETURN etc. macros
+       here so they can be used throughout the package.
+
+       * src/pthread.cxx: Remove mutex/cond var implementation, and
+       entry/return macros, as per above.
+
+       * src/signal.cxx (cyg_sigqueue): Don't just set non-queueable signals 
+       pending - also forcibly wake up any blocked threads.
+       (siglongjmp): Use new layout of sigjmp_buf.
+
+       * tests/mutex3.c:
+       * tests/pthread1.c:
+       * tests/pthread2.c:
+       * tests/pthread3.c:
+       * tests/signal1.c:
+       * tests/sigsetjmp.c:
+       * tests/timer1.c:
+       * tests/tm_basic.cxx:
+       Correct configuration dependencies, and do NA appropriately.
+       
+2001-08-03  Nick Garnett  <nickg@cygnus.co.uk>
+
+       Imported from a development branch:
+       
+       2001-06-27  Nick Garnett  <nickg@cygnus.co.uk>
+
+               * tests/pthread3.c:
+               Modified the loop that waits for the threads to get going so that
+               it will function correctly in an SMP system, where the threads
+               will run in parallel.
+
+               * tests/mutex3.c: Disabled this test for SMP systems. It depends
+               too much on predicting the priority-driven execution order of the
+               threads. In an SMP system, some threads will run in parallel and
+               falsify the assumptions.
+
+       2001-05-25  Nick Garnett  <nickg@cygnus.co.uk>
+
+               * src/signal.cxx (siglongjmp): Minor change to satisfy latest C++
+               compiler.
+
+2001-06-14  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/pthread.cxx (pthread_attr_setstacksize): Correct stack
+       size assertion.
+
+2001-06-12  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/pthread.cxx (MAIN_DEFAULT_STACK_SIZE): Define to use at
+       least PTHREAD_STACK_MIN for main_stack.
+
+2001-05-01  Nick Garnett  <nickg@cygnus.co.uk>
+
+       [x86 branch]
+       * tests/signal2.c (cause_illegal_access): Added code for I386
+       architecture to provoke General Protection Fault. 
+
+       * src/except.cxx: Removed some extraneous diag_printf()s.
+
+2001-04-25  Bart Veer  <bartv@redhat.com>
+
+       * tests/tm_basic.cxx:
+       This test is now functional on the synthetic target.
+
+2001-04-20  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/time.cxx (cyg_ticks_to_timespec): Actually don't bother
+       with working out seconds using convertors. Instead just divide
+       down ns from a long long.
+
+2001-04-19  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/time.cxx (cyg_ticks_to_timespec): Clock convertors round off,
+       so adjust timespec accordingly.
+
+2001-02-14  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * include/pthread.h: Remove pthread_canceled() and
+       pthread_testcancel_unlock().
+       
+       * src/pthread.cxx: Ditto.
+       (pthread_join): Restructure to have function exit only at function end
+       (pthread_cond_timedwait): Check for timeouts and return ETIMEDOUT
+
+       * src/signal.cxx (sigtimedwait): Restructure cancellation testing
+
+       * src/time.cxx (nanosleep): test for cancellation at the end of the
+       function to keep Nick happy ;).
+
+2001-02-11  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * include/pthread.h: Add new pthread_testcancel_unlock and
+       pthread_canceled functions as eCos extensions.
+       Rename existing pthread_canceled variable to pthread_cancelled_dummy_var
+       
+       * src/pthread.cxx (pthread_canceled): New function to interrogate if
+       current thread has deferred cancel pending
+       (pthread_testcancel_unlock): New function. Like testcancel, but unlocks
+       a mutex before exitting the thread.
+       (checkforcancel): New internal function
+       (pthread_join): Add thread cancellation checks.
+       (pthread_cond_wait): Ditto.
+       (pthread_cond_timedwait): Ditto.
+       (pthread_testcancel): Use checkforcancel()
+       
+       * src/sem.cxx (sem_wait): Add thread cancellation checks
+       * src/signal.cxx (sigtimedwait): Ditto.
+       Also make compilation of this file conditional on CYGPKG_POSIX_SIGNALS
+       * src/time.cxx (nanosleep): Ditto.
+       Also make compilation of this file conditional on CYGPKG_POSIX_TIMERS
+
+       * cdl/posix.cdl (CYGPKG_POSIX_TIMERS): Implements POSIX timer ops.
+       Add explicit kernel and pthread dependencies.
+
+       * tests/sigsetjmp.c (pthread_entry1): Fix incorrect thread no. output
+
+       * tests/pthread3.c: Add deferred cancellation test.
+
+2001-01-11  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pthread.cxx (pthread_testcancel): Added test for self !=
+       NULL in case this gets called from a non-pthread.
+
+2000-12-22  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/pthread.cxx (pthread_measure_stack_usage): New function
+       to measure stack usage.
+
+       * include/pthread.h: Prototype it.
+
+       * cdl/pthread.cdl: remove CYGNUM_POSIX_MAIN_DEFAULT_STACK_SIZE and
+       instead implement CYGINT_LIBC_STARTUP_EXTERNAL_INVOKE_MAIN_POSSIBLE
+
+       * src/pthread.cxx: Use stack size for main from libc_startup package
+       to prevent confusion
+       (cyg_posix_pthread_start): Likewise
+
+2000-12-06  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/signal.cxx: include unistd.h for _exit
+
+2000-11-20  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/signal.cxx (cyg_deliver_signals): Added else in code to
+       handle SIG_DFL. Otherwise if the SA_SIGINFO bit is set we call the
+       signal handler twice!
+
+2000-11-07  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/signal.cxx (cyg_posix_thread_siginit): Add extra thread
+       argument so that threads can inherit parent's sigmask.
+
+       * src/pthread.cxx (pthread_create): Call with parent thread
+
+       * src/pprivate.h: Change cyg_posix_thread_siginit prototype to take
+       parent thread argument
+
+       * tests/signal1.c: Add more checking of sigwaits, and fix so that it's
+       only called when the signal is masked. Check errno values too
+       sometimes.
+
+2000-11-02  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/signal.cxx (sigtimedwait): return signal number on success,
+       not 0
+       (SIGNAL_RETURN_VALUE): New macro for returning from functions with
+       valid non-zero returns
+       (sigwaitinfo): Pass on sigtimedwait result with SIGNAL_RETURN_VALUE
+       macro as it may return the signal number.
+
+2000-11-01  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/signal.cxx (sigtimedwait): Check for SIGALRMs as a special
+       case when looping as it won't have been set pending if it was
+       masked.
+       (check_sigalarm): New function extracted from the posix signal ASR
+       (sigalrm_action): Unconditionally wake up threads waiting in sigwait
+       so that they can check for pending SIGALRMs even if they were
+       masked.
+       (cyg_deliver_signals): Handle SIG_DFL signals properly, and check
+       for bad signal handlers.
+       (cyg_posix_signal_start): Initialize default signal actions to SIG_DFL
+
+2000-10-27  Jesper Skov  <jskov@redhat.com>
+
+       * tests/signal2.c (cause_illegal_access): Don't loop forever.
+
+2000-10-16  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * include/sigsetjmp.h (sigsetjmp): Various fixes to make portable
+       across all HALs (by avoiding CYGARC_JMP_BUF_SIZE) and remove warnings.
+       * src/signal.cxx (siglongjmp): Likewise
+
+2000-10-12  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * include/sigsetjmp.h: Added this header to define
+       sigjmp_buf,sigsetjmp() and siglongjmp().
+
+       * cdl/posix.cdl:
+       Added support for providing sigsetjmp implementation and header.
+       Added sigsetjmp test.
+
+       * src/signal.cxx: Added siglongjmp().
+
+       * tests/sigsetjmp.c: Added this test for sigsetjmp(), siglongjmp()
+       functionality. This is also a test for longjmping out of signal
+       handlers.
+
+       * tests/signal2.c:
+       Ifdeffed around cause_* functions to avoid compiler warnings when
+       they are not needed.
+       Changed CYG_TEST_NA() calls to CYG_TEST_INFO() and changed
+       CYG_TEST_FINISH() to CYG_TEST_PASS_FINISH(). With the _NA's there,
+       the first unsupported exception just terminates the program, and
+       does not give any subsequent supported ones a chance to run.
+
+2000-10-12  Jesper Skov  <jskov@redhat.com>
+
+       * tests/timer1.c (main): Fix exit check.
+
+2000-10-11  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pthread.cxx: Fixed cyg_posix_pthread_release_thread() to
+       work for _DETACHED threads as well as for _RUNNING ones. Also
+       fixed a bug in test to decrement counter in this routine.
+
+       * src/pprivate.h: Added note about retaining numerical order of
+       PTHREAD_STATE_* defines.
+
+       * tests/timer1.c: Fixed some bugs of the how-did-it-ever-work
+       variety.
+
+2000-10-05  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/misc.cxx:
+       Added a set of compatibility functions to aid portability and
+       improve standards compliance.
+       Added cyg_posix_function_[start|finish] to set up and terminate
+       POSIX API functionality wrt signal and cancellation behaviour.
+       (Lots more to do here).
+
+       * include/export.h:
+       Added this file to contain definitions that can be exported from
+       the POSIX package to others.
+
+       * src/pprivate.h: Added include of export.h
+       
+2000-09-11  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * include/limits.h (OPEN_MAX): Don't define here - let FS infra do
+       that.
+       (LINK_MAX): Ditto
+       (NAME_MAX): Ditto
+       (PATH_MAX): Ditto
+
+2000-09-04  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * tests/pthread2.c: 
+       * tests/pthread3.c:
+       Fixed bug in calculation of thread stack addresses.
+
+       * src/misc.cxx (sysconf): Change zero returns to -1 when a feature
+       is not supported.
+
+2000-08-08  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * include/limits.h: Don't define SSIZE_MAX here, leave it to the
+       isoinfra default.
+
+2000-07-27  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * tests/signal2.c: NA if no setjmp/longjmp
+
+2000-07-26  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * include/pthread.h:
+       * src/pthread.cxx (pthread_testcancel): Reversed addition of cyg_
+       to this symbol.
+
+2000-07-25  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * src/pthread.cxx: Define main_stack and main_thread as static
+       Rename pthread_canceled -> cyg_pthread_canceled - pthread_ may be
+       a reserved name space but this makes explicit it is implementation-
+       and not standard-defined
+       (PTHREAD_ENTRY_VOID): Define for funcs that take no args
+       (pthread_testcancel): Call PTHREAD_ENTRY_VOID()
+
+       * include/pthread.h: Rename pthread_canceled -> cyg_pthread_canceled
+
+2000-07-20  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * src/pthread.cxx: Use isoinfra to determine presence of malloc()
+       Define pthread_malloc() and pthread_free() as inlines
+
+       * cdl/posix.cdl: Shouldn't define _POSIX_MESSAGE_PASSING at all - that
+       happens in isoinfra.
+
+2000-07-20  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * cdl/posix.cdl: Added misc.cxx to compile list. Added option to
+       define _POSIX_MESSAGE_PASSING. Added configury for utsname
+       structure.
+
+       * include/utsname.h: Added this file to define struct utsname and
+       uname() function prototype.
+
+       * include/mqueue.h: Moved definition of _POSIX_MESSAGE_PASSING to
+       CDL.
+
+       * include/limits.h: Added NGROUPS_MAX definition.
+
+       * src/pthread.cxx:
+       Added support for malloced() thread stacks.
+       Added implementations of pthread_mutex_setprioceiling() and
+       pthread_mutex_getprioceiling().
+       Changed implementations of pthread_mutex_destroy(),
+       pthread_mutex_lock() and pthread_mutex_trylock() to conform more
+       closely to the standard.
+       Changed pthread_key_create() to assign NULL to all valid thread
+       slots that correspond to a newly allocated key.
+
+       * src/pprivate.h: Added freestack and stackmem members to manage
+       malloced thread stacks.
+
+       * src/misc.cxx: Added this file to contain functions that do not
+       belong in any other files. Currently contains uname() and
+       sysconf().
+
+2000-07-19  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * src/startup.cxx: Remove unnecessary includes
+       Use dummy object constructor to do initialization
+
+       * cdl/posix.cdl: 
+       Don't need main.cxx any more
+       Build startup.cxx into extras.o (via libextras.a)
+
+       * cdl/pthread.cdl (CYGPKG_POSIX_MAIN_THREAD):
+       Integrate with CYGPKG_LIBC_STARTUP - tell CYGPKG_LIBC_STARTUP to
+       let pthreads set up main thread
+
+       * src/pthread.cxx: Integrate with CYGPKG_LIBC_STARTUP rather than
+       calling main() directly.
+       Track number of threads waiting to be joined, so we can tell in
+       pthread_exit() if this is the last thread, and therefore whether
+       to call exit()
+
+       * src/main.cxx: obsolete, removed
+
+2000-07-13  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/signal.cxx: Added ISO C compatibility functions signal() and
+       raise().
+
+2000-06-21  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pthread.cxx: Added for(;;) loop to end of pthread_exit().
+       pthread_exit() is marked with the noreturn attribute, and without
+       this some compilers generate a call to abort() here in case
+       Cyg_Thread::exit() returns. The loop avoids this.
+
+2000-06-06  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * src/mqueue.cxx (mq_receive): Fix non-portable treatment of mode flags
+       (mq_send):  Ditto
+       * tests/mqueue2.c (main): Ditto
+
+2000-05-24  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * tests/pthread2.c: Added this program to test per-thread data
+       handling.
+
+       * tests/pthread3.c: Added this program to test execution of
+       cancellation handler.
+
+       * src/pthread.cxx: Fixed some bugs revealed by new test programs.
+
+       * cdl/posix.cdl: Added two new pthread tests.
+
+2000-05-22  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * cdl/posix.cdl (CYGPKG_POSIX): Require
+       CYGIMP_KERNEL_SCHED_SORTED_QUEUES
+
+2000-05-20  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * tests/mqueue1.c (cyg_user_start): Define correctly
+       * tests/mqueue2.c (cyg_user_start): Likewise
+
+       * src/pprivate.h (cyg_sigqueue): Make struct sigevent * arg const since
+       it is, and it prevents warnings elsewhere
+       * src/signal.cxx (cyg_sigqueue): ditto
+
+       * tests/signal2.c: Use CYG_TEST_NA, not CYG_TEST_INFO (otherwise
+       the test farm may fail the tests because there are no PASSes or NAs)
+
+       * cdl/posix.cdl (CYGPKG_POSIX): We need errno and error codes, so
+       require them
+       Move some of the package implements into the components
+       Add message queue configuration, build mqueue.cxx and the mqueue1 and
+       mqueue2 tests
+       Move some calculated options into isoinfra, implemented as interfaces
+       so that unistd.h and limits.h can get the values
+
+       * include/limits.h: Move _POSIX_* macros into isoinfra limits.h
+       since they are implementation independent
+
+       * src/mqueue.cxx: Add POSIX message queue implementation
+       * tests/mqueue1.c, tests/mqueue2.c: and tests
+
+2000-05-18  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pprivate.h:
+       * src/pthread.cxx:
+       * src/signal.cxx:
+       * src/time.cxx:
+       Added prioritization of static kernel objects.
+
+2000-05-17  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pthread.cxx:
+       To reduce the static memory required by this code, the
+       pthread_info structure for a pthread is now allocated in the stack
+       memory for that thread, and not in a static table. The table is
+       now just an array of pointers. The per-thread data array is now
+       also allocated onto the stack only when first required.
+
+       * include/pthread.h: Removed some redundant code.
+
+       * include/limits.h: Added PTHREAD_STACK_OVERHEAD to record
+       management overhead imposed on POSIX threads stacks. This is added
+       to the HAL minimum requirement to generate PTHREAD_STACK_MIN.
+
+       * src/pprivate.h (pthread_info):
+       * include/types.h (pthread_attr_t): Converted a number of integer
+       state and boolean fields to bitfields.
+
+       * cdl/pthread.cdl:
+       Added requirement for CYGFUN_KERNEL_THREADS_STACK_LIMIT.
+
+2000-05-16  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * include/types.h: Added stacksize_valid to pthread_attr_t
+       structure.
+
+       * include/signal.h:
+       Added SI_EXCEPT to mark any signals that were caused by an
+       exception. Removed conditions around SIGBUS.
+
+       * src/startup.cxx (cyg_posix_start):
+       Added call to cyg_posix_exception_start(). 
+
+       * src/signal.cxx:
+       Rearranged cyg_deliver_signals() so that it is possible to
+       longjmp() out of a signal handler without leaving signal handling
+       code in an inconsistent state.
+       Added handling of SIG_IGN in sigaction().
+
+       * src/pthread.cxx: Added setting and checking of stacksize_valid.
+
+       * src/pprivate.h: Added cyg_deliver_signals() as an export of
+       signal system. Added exports from except.cxx.
+
+       * src/except.cxx: Added this file to handle delivery of exceptions
+       into the POSIX signal mechanism.
+
+       * cdl/posix.cdl: Added except.cxx to compile list, added signal2
+       to tests. Added requirement on kernel exception processing.
+
+       * tests/tm_basic.cxx: Tidied up a compilation warning.
+
+       * tests/signal2.c: Added this test for exception signal generation.
+
+       * tests/mutex3.c: Fixed stupid bug.
+       
+2000-05-10  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pprivate.h: Added cyg_posix_clock_start() prototype.
+
+       * src/startup.cxx: Added call to cyg_posix_clock_start().
+
+       * src/time.cxx: Added startup routine to initialize
+       converters. Fixed error result bug in timer_delete().
+
+       * include/signal.h: Removed some configuration tests which are now
+       done in CDL.
+
+       * cdl/posix.cdl: Added configury for the signals component. Added
+       tm_basic to tests.
+
+       * tests/tm_basic.cxx:
+       Added this POSIXized version of the tm_basic test. Note that this
+       has not been entirely converted. While the code being tested is
+       POSIX, the timing infrastructure remains a mish-mash of kernel,
+       KAPI and HAL code.
+
+2000-05-04  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/time.cxx:
+       Many changes to implement the delivery of signals on timer expiry.
+       Also added timer_delete().
+
+       * src/signal.cxx:
+       cyg_sigqueue() and cyg_deliver_signals() may now only be called
+       from within the context of a POSIX thread, either from an API call
+       or an ASR.
+       cyg_deliver_signals() can now cope with a signal that has
+       SA_SIGINFO set but no signals queued. It also determines
+       dynamically whether to lock the signal_mutex.
+       cyg_deliver_signals() is no longer called implicitly from
+       cyg_sigqueue() - so a number of expicit calls have been added.
+       
+       * src/sched.cxx:
+       Added this file to implement scheduling API.
+
+       * src/pthread.cxx:
+       Moved priority translation macros to pprivate.h.
+       Removed errno handling, now done in isoinfra package.
+       Added iterative calls to per-thread data destructors.
+
+       * src/pprivate.h:
+       Removed error field from pthread_info structure.
+       Moved priority translation macros here.
+       Removed prototype for cyg_deliver_signals().
+       Added prototype for cyg_posix_timer_asr().
+
+       * include/time.h: Added timer_delete() which was mysteriously
+       omitted.
+
+       * cdl/posix.cdl: Added sched.cxx to compile list and timer1.c to
+       tests.
+
+       * tests/signal1.c: 
+       * tests/pthread1.c:
+       Fixed bug in use of stack sizes.
+
+       * tests/timer1.c: 
+       Added test for use of timers.
+               
+2000-05-02  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * include/sched.h: No longer needed - just use the default definition
+       in isoinfra
+
+       * include/errno.h: No longer needed - errno provision now comes from
+       CYGPKG_ERROR
+       
+       * include/sys/types.h: Moved to include/types.h
+       
+       * cdl/posix.cdl, cdl/pthread.cdl: Put include files in cyg/posix, and
+       configure CYGPKG_ISOINFRA to include the appropriate headers
+       
+       * include/semaphore.h: Don't need to check kernel - including
+       pkgconf/kernel.h would already fail
+       Give SEM_FAILED a type so casting behaves in C++
+       
+       * include/signal.h: This uses pid_t etc., so include <sys/types.h>
+       Add signal() and raise() prototypes (to allow libc compilation, even
+       though they aren't implemented yet)
+       
+       * include/time.h: Remove unnecessary includes. Move clockid_t and
+       timer_t definitions here from sys/types.h since this is where the
+       standard says they must live. 
+       
+       * src/pprivate.h: Include signal.h and limits.h since their contents
+       are used later in the file.     
+
+2000-04-28  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/signal.cxx:
+       Added implementations of alarm(), pause() and sleep().
+       Modified cyg_sigqueue() so that it could be called from an ASR.
+       Added cyg_posix_signal_asr() to do signal processing in ASRs.
+       Miscellaneous bug fixes.
+
+       * src/pthread.cxx:
+       Added pthread_count to count number of threads created.
+       Added call to signal ASR function in main ASR.
+       Added cyg_posix_pthread_release_thread() to seek out and kick a
+       thread to which a given set of signals may be delivered.
+
+       * src/pprivate.h:
+       Added some more functions that are shared between POSIX
+       subsystems.
+
+       * include/signal.h:
+       Added alarm(), pause() and sleep() prototypes. 
+
+       * tests/signal1.c: Added this test for various aspects of signal
+       handling.
+
+       * cdl/posix.cdl: Added signal1 test.
+
+2000-04-20  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/signal.cxx: Added this file to contain signal handling code.
+
+       * src/time.cxx: Made tick<->timespec converters exported to
+       rest of POSIX subsystem. Enabled interface to signal mechanism for
+       notifying timer expiration.
+
+       * src/pthread.cxx:
+       Made pthread_mutex exported to rest of POSIX subsystem.
+       Exported pthread_info_id().
+       Added thread init and destroy functions for signal subsystem.
+
+       * src/startup.cxx: Added call to cyg_posix_signal_start().
+
+       * src/pprivate.h: Added signal handling fields support to
+       pthread_info structure. Added extra internal interfaces to support
+       signal handling code.
+
+       * include/signal.h: Added _how_ argument values for the sigmask
+       functions.
+
+       * cdl/posix.cdl: Added signal.cxx to compile list.
+
+2000-04-13  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * include/time.h: 
+       * src/time.cxx:
+       Added implementation of clock and timer functions. These are
+       currently untested since they need working signals.
+
+2000-04-12  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pprivate.h: Added cancellation support fields to
+       pthread_info structure. Made pthread_self_info() exported.
+
+       * include/semaphore.h: Added SEM_FAILED plus misc. tidies.
+
+       * include/pthread.h: Added PTHREAD_CANCELED.
+
+       * include/errno.h: Fixed cyg_pthread_errno_p() return type.
+
+       * src/pthread.cxx:
+       Added pthread_reap() to clean up exited threads.
+       Added support for cancellation.
+       Added cyg_posix_errno_p().
+
+       * src/time.cxx:
+       Added this file to implement time functionality. At present only
+       nanosleep() is actually implemented.
+
+       * src/sem.cxx:
+       Added this file to implement semaphore functionality.
+
+       * cdl/pthread.cdl:
+       Added some extra configuration requirements.
+
+       * cdl/posix.cdl:
+       Added some more files to compile.
+       Added semaphore configuration.
+
+       * tests/mutex3.c:
+       Added this test program. This is actually a POSIXized version of
+       Hugo's splendid kernel test of the same name. It exercises quite a
+       lot of the pthread infrastructure and is thus a good test to run.
+
+       * tests/pthread1.c:
+       Added proper comment headers and added full testing stuff.
+       
+2000-04-10  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pprivate.h: 
+       * src/pthread.cxx:
+       Added per-thread data support.
+
+2000-04-06  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * src/pthread.cxx:
+       Filled in implementations of lots of functions.
+
+       * src/main.cxx:
+       Added this file to contain a default main. This is currenly just a
+       duplicate of the same file from the C library. Work is needed to
+       combine these.
+
+       * include/sys/types.h:
+       Modified pthread_mutex_t to conform to kernel structure.
+
+       * cdl/pthread.cdl:
+       Added support for main thread.
+
+       * cdl/posix.cdl:
+       Added main.cxx to compile list.
+
+2000-03-31  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * cdl/pthread.cdl: 
+       * cdl/posix.cdl:
+       Added CDL files to configure POSIX subsystem.
+
+       * src/pprivate.h: 
+       * src/pthread.cxx: 
+       * src/startup.cxx: 
+       Added these files to begin implementation of POSIX package.
+       
+       * include/pthread.h: 
+       * include/sched.h: 
+       * include/signal.h: 
+       * include/time.h: 
+       * include/sys/types.h: 
+       Many changes needed by implementation work.
+       
+       * include/limits.h: 
+       * include/errno.h: 
+       Added these header files.
+       
+2000-03-24  Nick Garnett  <nickg@cygnus.co.uk>
+
+       * include/sys/types.h: 
+       * include/time.h: 
+       * include/sched.h: 
+       * include/pthread.h: 
+       * include/signal.h:
+       * include/semaphore.h: 
+       * include/mqueue.h: 
+       Roughed out (most of) the set of POSIX headers for the
+       functionality we are currently going to support. These files are
+       currently neither fully standard conformant nor implementation
+       ready. Much work is still needed to make them so. Watch this
+       space.
+
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
diff --git a/packages/compat/posix/v2_0/cdl/posix.cdl b/packages/compat/posix/v2_0/cdl/posix.cdl
new file mode 100644 (file)
index 0000000..86b3aa2
--- /dev/null
@@ -0,0 +1,317 @@
+# ====================================================================
+#
+#      posix.cdl
+#
+#      POSIX layer configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      nickg
+# Contributors:
+# Date:           2000-3-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_POSIX {
+    display        "POSIX compatibility layer"
+    description    "This package enables the POSIX compatibility
+                    layer that implements IEEE 1003.1."
+    doc            ref/posix-compatibility.html
+    include_dir    cyg/posix
+    
+    requires       CYGPKG_KERNEL
+    requires       CYGPKG_ISOINFRA
+    requires       CYGPKG_ERROR
+    requires       CYGINT_ISO_ERRNO
+    requires       CYGINT_ISO_ERRNO_CODES
+    requires       CYGIMP_KERNEL_SCHED_SORTED_QUEUES
+
+    implements     CYGINT_ISO_SCHED_IMPL
+    implements     CYGINT_ISO_POSIX_LIMITS
+    implements     CYGINT_ISO_PMUTEXTYPES
+    implements     CYGINT_ISO_PTHREAD_MUTEX
+    requires       { CYGBLD_ISO_POSIX_LIMITS_HEADER == \
+                         "<cyg/posix/limits.h>" }
+    requires       { CYGBLD_ISO_PMUTEXTYPES_HEADER == \
+                         "<cyg/posix/muttypes.h>" }
+    requires       { CYGBLD_ISO_PTHREAD_MUTEX_HEADER == \
+                         "<cyg/posix/mutex.h>" }
+    
+    compile        mqueue.cxx mutex.cxx misc.cxx
+    compile       -library=libextras.a startup.cxx
+
+    cdl_option _POSIX_THREAD_PRIO_INHERIT {
+        display                "POSIX mutex priority inheritance feature test macro"
+        flavor         bool
+        default_value  1
+        requires       CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
+        description    "This option defines the POSIX feature test macro
+                         for supporting priority inheritance protocol in
+                         mutexes."
+    }
+    
+    cdl_option _POSIX_THREAD_PRIO_PROTECT {
+        display                "POSIX mutex priority ceiling feature test macro"
+        flavor         bool
+        default_value  1
+        requires       CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
+        description    "This option defines the POSIX feature test macro
+                         for supporting priority ceiling protocol in mutexes."
+    }
+    
+    # ----------------------------------------------------------------
+    # Scheduling component
+    
+    cdl_component CYGPKG_POSIX_SCHED {
+       display          "POSIX scheduling configuration"
+       flavor           bool
+       default_value    1
+       description      "This component provides controls over scheduling
+                         in POSIX."
+        requires         CYGPKG_POSIX_CLOCKS
+        compile          sched.cxx
+
+       cdl_option _POSIX_PRIORITY_SCHEDULING {
+           display       "POSIX priority scheduling feature test macro"
+           flavor        bool
+           calculated    1
+           requires      CYGSEM_KERNEL_SCHED_MLQUEUE
+           description   "This option defines the POSIX feature test macro
+                          that indicates that priority scheduling is present.
+                          This should not be undefined."
+       }
+    }
+
+    # ----------------------------------------------------------------
+    # Pthreads component
+
+    cdl_component CYGPKG_POSIX_PTHREAD {
+       display          "POSIX pthread configuration"
+       flavor           bool
+       default_value    1
+       description      "This component provides configuration controls for
+                         the POSIX pthreads package."
+        compile          pthread.cxx
+       script           pthread.cdl
+    }
+
+    # ----------------------------------------------------------------
+    # Timers component
+
+    cdl_option CYGPKG_POSIX_CLOCKS {
+       display          "POSIX clocks"
+       flavor           bool
+        default_value    1
+        implements       CYGINT_ISO_POSIX_CLOCK_TYPES
+        implements       CYGINT_ISO_POSIX_CLOCKS
+        implements       CYGINT_ISO_POSIX_SLEEP
+        requires         { CYGBLD_ISO_POSIX_CLOCK_TYPES_HEADER == \
+                             "<cyg/posix/time.h>" }
+        requires         { CYGBLD_ISO_POSIX_CLOCKS_HEADER == \
+                             "<cyg/posix/time.h>" }
+        requires         CYGPKG_KERNEL
+        requires         CYGVAR_KERNEL_COUNTERS_CLOCK
+        compile          time.cxx
+       description      "This component provides configuration controls for
+                         the POSIX clocks."
+    }
+
+    # ----------------------------------------------------------------
+    # Timers component
+
+    cdl_option CYGPKG_POSIX_TIMERS {
+       display          "POSIX timers"
+       flavor           bool
+       default_value    1
+        implements       CYGINT_ISO_POSIX_TIMER_TYPES
+        implements       CYGINT_ISO_POSIX_TIMERS
+        implements       CYGINT_ISO_POSIX_TIMER_OPS
+        requires         { CYGBLD_ISO_POSIX_TIMER_TYPES_HEADER == \
+                             "<cyg/posix/time.h>" }
+        requires         { CYGBLD_ISO_POSIX_TIMERS_HEADER == \
+                             "<cyg/posix/time.h>" }
+        requires         CYGPKG_KERNEL
+        requires         CYGVAR_KERNEL_COUNTERS_CLOCK
+        requires         CYGPKG_POSIX_PTHREAD
+        requires         CYGPKG_POSIX_CLOCKS
+        requires         CYGPKG_POSIX_SIGNALS
+       description      "This component provides configuration controls for
+                         the POSIX timers."
+    }
+
+    # ----------------------------------------------------------------
+    # Semaphores component
+
+    cdl_option CYGPKG_POSIX_SEMAPHORES {
+       display          "POSIX semaphores"
+       flavor           bool
+       default_value    1
+        implements       CYGINT_ISO_SEMAPHORES
+        requires         { CYGBLD_ISO_SEMAPHORES_HEADER == \
+                             "<cyg/posix/semaphore.h>" }
+       description      "This component provides configuration controls for
+                         POSIX semaphores."
+
+        compile          sem.cxx
+    }
+
+    # ----------------------------------------------------------------
+    # Message queues component
+
+    cdl_component CYGPKG_POSIX_MQUEUES {
+       display          "POSIX message queues"
+       flavor           bool
+       default_value    1
+        implements       CYGINT_ISO_MQUEUE
+        requires         CYGPKG_KERNEL
+        requires         CYGINT_ISO_MALLOC
+        requires         CYGINT_ISO_ERRNO
+        requires         CYGINT_ISO_STRING_STRFUNCS
+       description      "This component provides configuration controls for
+                         POSIX message queues."
+
+        cdl_option CYGNUM_POSIX_MQUEUE_OPEN_MAX {
+            display          "Maximum number of message queues"
+            flavor           data
+            default_value    8
+            legal_values     1 to 999999
+        }
+
+        cdl_option CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR {
+            display          "Validate queue descriptors"
+            flavor           bool
+            default_value    1
+            description      "
+                This option turns on checking that message queue descriptors
+                (of type mqd_t) passed into mq_* functions are valid. If so,
+                the functions will fail with EBADF, as POSIX 1003.1 mandates.
+                If this option is disabled, if an invalid descriptor is used,
+                random corruption may occur, or the system may crash. If
+                you are confident invalid descriptors will not be used,
+                you may wish to be disable this to save some per-instance
+                memory and execution time."
+        }
+
+        cdl_option CYGFUN_POSIX_MQUEUE_NOTIFY {
+            display          "Allow empty queue notification"
+            flavor           bool
+            requires         CYGPKG_POSIX_SIGNALS
+            default_value    CYGPKG_POSIX_SIGNALS
+            description      "
+                Enabling this option adds the function mq_notify() to the
+                API. Without it, some code and per-message queue descriptor
+                space is saved, as well as no longer requiring POSIX realtime
+                signal support."
+        }
+    }
+
+    # ----------------------------------------------------------------
+    # Signals component
+
+    cdl_component CYGPKG_POSIX_SIGNALS {
+       display          "POSIX signals configuration"
+       flavor           bool
+       default_value    1
+       requires         CYGPKG_KERNEL_EXCEPTIONS
+        requires         CYGPKG_POSIX_PTHREAD
+        requires         CYGPKG_POSIX_TIMERS
+        implements       CYGINT_POSIX_REALTIME_SIGNALS
+        implements       CYGINT_ISO_SIGSETJMP
+        requires         { CYGBLD_ISO_SIGSETJMP_HEADER == \
+                             "<cyg/posix/sigsetjmp.h>" }
+        implements       CYGINT_ISO_SIGNAL_NUMBERS
+        implements       CYGINT_ISO_SIGNAL_IMPL
+        requires         { CYGBLD_ISO_SIGNAL_NUMBERS_HEADER == \
+                             "<cyg/posix/signal.h>" }
+        requires         { CYGBLD_ISO_SIGNAL_IMPL_HEADER == \
+                             "<cyg/posix/signal.h>" }
+       description      "This component provides configuration controls for
+                         the POSIX signals."
+        compile          signal.cxx except.cxx 
+    }
+
+    # ----------------------------------------------------------------
+    # uname structure component
+
+    cdl_component CYGPKG_POSIX_UTSNAME {
+       display           "POSIX utsname configuration"
+       flavor            bool
+       default_value     1
+       requires          { CYGBLD_ISO_UTSNAME_HEADER == \
+                            "<cyg/posix/utsname.h>" }
+       description       "This component provides configuration controls for
+                          the POSIX utsname structure and the uname() function."
+
+       cdl_option CYG_POSIX_UTSNAME_LENGTH {
+           display          "Length of name strings in utsname structure"
+           flavor           data
+           default_value    65
+           legal_values     1 to 99999999
+       }
+
+       cdl_option CYG_POSIX_UTSNAME_NODENAME_LENGTH {
+           display          "Length of nodename string in utsname structure"
+           flavor           data
+           default_value    { CYG_POSIX_UTSNAME_LENGTH }
+           legal_values     1 to 99999999          
+       }
+
+    }
+
+    # ----------------------------------------------------------------
+    # Tests
+
+        cdl_option CYGPKG_POSIX_TESTS {
+            display "POSIX tests"
+            flavor  data
+            no_define
+            calculated { 
+                "tests/pthread1 tests/pthread2 tests/pthread3 tests/mutex3 tests/mqueue2"
+                . ((CYGPKG_POSIX_SIGNALS) ? " tests/mqueue1 tests/signal1 tests/signal2 tests/signal3 tests/sigsetjmp tests/timer1 tests/tm_basic" : "")
+            }
+            description   "
+                This option specifies the set of tests for the POSIX package."
+        }
+
+}
+
+# ====================================================================
+# End of posix.cdl
+
+
diff --git a/packages/compat/posix/v2_0/cdl/pthread.cdl b/packages/compat/posix/v2_0/cdl/pthread.cdl
new file mode 100644 (file)
index 0000000..d170356
--- /dev/null
@@ -0,0 +1,197 @@
+# ====================================================================
+#
+#      pthread.cdl
+#
+#      POSIX pthread configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      nickg
+# Contributors:   jlarmour
+# Date:           2000-3-28
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGPKG_POSIX_PTHREAD_REQUIREMENTS {
+       display         "Generic requirements of pthread package"
+       flavor          bool
+       calculated      1
+        implements      CYGINT_ISO_PTHREADTYPES
+        implements      CYGINT_ISO_PTHREAD_IMPL
+       requires        CYGPKG_POSIX_SCHED
+       requires        CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE
+       requires        CYGSEM_KERNEL_SCHED_ASR_SUPPORT
+       requires        CYGSEM_KERNEL_SCHED_ASR_GLOBAL
+       requires        !CYGSEM_KERNEL_SCHED_ASR_DATA_GLOBAL
+       requires        CYGFUN_KERNEL_THREADS_STACK_LIMIT
+        requires        { CYGBLD_ISO_PTHREADTYPES_HEADER == \
+                          "<cyg/posix/types.h>" }
+        requires        { CYGBLD_ISO_PTHREAD_IMPL_HEADER == \
+                          "<cyg/posix/pthread.h>" }
+       description     "This option exists merely to carry the pthread
+                         package requirements."
+
+}
+
+# ====================================================================
+
+cdl_component CYGPKG_POSIX_PTHREAD_VALUES {
+    display          "Constant values used in pthread package"
+    flavor           bool
+    calculated              1
+    description      "These are values that are either configurable, or derived
+                     from system parameters."
+
+    cdl_option CYGNUM_POSIX_PTHREAD_DESTRUCTOR_ITERATIONS {
+       display          "Maximum number of iterations of key destructors"
+       flavor           data
+       legal_values     4 to 100
+       default_value    4
+       description      "Maximum number of iterations of key destructors allowed."
+    }
+
+    cdl_option CYGNUM_POSIX_PTHREAD_KEYS_MAX {
+       display          "Maximum number of per-thread data keys allowed"
+       flavor           data
+       legal_values     128 to 65535
+       default_value    128
+       description      "Number of per-thread data keys supported."
+    }
+
+        cdl_option CYGNUM_POSIX_PTHREAD_THREADS_MAX {
+       display          "Maximum number of threads allowed"
+       flavor           data
+       legal_values     64 to 1024
+       default_value    64
+       description      "Maximum number of threads supported."
+    }
+
+}
+
+# ====================================================================
+
+cdl_component CYGPKG_POSIX_PTHREAD_FEATURES {
+       display         "Fixed Feature test macros for POSIX"
+       flavor          bool
+       calculated      1
+       description     "These options define POSIX feature test macros that
+                        describe the eCos implementation of pthreads. These
+                        are not changeable configuration options."
+
+    cdl_option _POSIX_THREADS {
+       display         "POSIX thread support feature test macro"
+       flavor          bool
+       calculated      1
+       requires        CYGSEM_KERNEL_SCHED_TIMESLICE
+       requires        CYGVAR_KERNEL_THREADS_DATA
+       description     "This option defines the POSIX feature test macro
+                       for thread support."
+    }
+
+    cdl_option _POSIX_THREAD_PRIORITY_SCHEDULING {
+       display         "POSIX thread priority scheduling feature test macro"
+       flavor          bool
+       calculated      1
+       requires        CYGSEM_KERNEL_SCHED_MLQUEUE
+        requires      _POSIX_THREADS
+       description     "This option defines the POSIX feature test macro
+                       for thread priority scheduling support."
+    }
+
+    cdl_option _POSIX_THREAD_ATTR_STACKADDR {
+       display         "POSIX stack address attribute feature test macro"
+       flavor          bool
+       calculated      1
+       description     "This option defines the POSIX feature test macro
+                       for supporting the thread stack address in the thread
+                       attribute object."
+    }
+
+    cdl_option _POSIX_THREAD_ATTR_STACKSIZE {
+       display         "POSIX stack size attribute feature test macro"
+       flavor          bool
+       calculated      1
+       description     "This option defines the POSIX feature test macro
+                       for supporting the thread stack size in the thread
+                       attribute object."
+    }
+
+    cdl_option _POSIX_THREAD_PROCESS_SHARED {
+       display         "POSIX process shared attribute feature test macro"
+       flavor          bool
+       calculated      0
+       description     "This option defines the POSIX feature test macro
+                       for supporting process shared mutexes. Since eCos
+                       does not have processes, this attribute is undefined."
+    }
+
+}
+
+# ====================================================================
+
+cdl_component CYGPKG_POSIX_MAIN_THREAD {
+       display         "Main thread configuration"
+       flavor          bool
+       calculated      1
+       requires        { 0 != CYGPKG_LIBC_STARTUP }
+       requires        CYGSEM_LIBC_STARTUP_MAIN_OTHER
+        implements      CYGINT_LIBC_STARTUP_EXTERNAL_INVOKE_MAIN_POSSIBLE
+       description     "These options control the thread used to
+                         run the main() application entry routine."
+                        
+       cdl_option CYGNUM_POSIX_MAIN_DEFAULT_PRIORITY {
+            display        "main()'s default thread priority"
+            flavor         data
+            legal_values   0 to 31
+            default_value  16
+            description    "
+                POSIX compatibility requires that the application's
+                main() function be invoked in a thread.
+               This option controls the priority of that thread. This
+                priority is the POSIX priority and is NOT the same as
+                an eCos thread priority. With POSIX thread priorities,
+                lower numbers are lower priority, and higher numbers are
+                higher priority."
+       }
+}
+
+# ====================================================================
+# End of pthread.cdl
+
+
diff --git a/packages/compat/posix/v2_0/doc/posix.sgml b/packages/compat/posix/v2_0/doc/posix.sgml
new file mode 100644 (file)
index 0000000..3434a81
--- /dev/null
@@ -0,0 +1,1568 @@
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     posix.sgml                                                  -->
+<!--                                                                 -->
+<!--     POSIX Compatibility                                         -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.  -->
+<!-- This material may be distributed only subject to the terms      -->
+<!-- and conditions set forth in the Open Publication License, v1.0  -->
+<!-- or later (the latest version is presently available at          -->
+<!-- http://www.opencontent.org/openpub/)                            -->
+<!-- Distribution of the work or derivative of the work in any       -->
+<!-- standard (paper) book form is prohibited unless prior           -->
+<!-- permission obtained from the copyright holder                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->      
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN####                                       -->
+<!--                                                                 -->
+<!-- ####DESCRIPTIONEND####                                          -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="posix-compatibility">
+<title>eCos POSIX compatibility layer</title>
+
+<chapter id="posix-standard-support">
+<title>POSIX Standard Support</title>
+
+<!-- {{{ Intro  -->
+
+    <para>
+      eCos contains support for the POSIX Specification (ISO&sol;IEC
+      9945-1)&lsqb;POSIX&rsqb;.
+    </para>
+    <para>
+      POSIX support is divided between the POSIX and the FILEIO
+      packages. The POSIX package provides support for threads,
+      signals, synchronization, timers and message queues. The FILEIO
+      package provides support for file and device I&sol;O. The two
+      packages may be used together or separately, depending on
+      configuration.
+    </para>
+    <para>
+      This document takes a functional approach to the POSIX
+      library. Support for a function implies that the data types and
+      definitions necessary to support that function, and the objects
+      it manipulates, are also defined. Any exceptions to this are
+      noted, and unless otherwise noted, implemented functions behave
+      as specified in the POSIX standard.
+    </para>
+    <para>
+      This document only covers the differences between the eCos
+      implementation and the standard; it does not provide complete
+      documentation. For full information, see the POSIX standard
+      &lsqb;POSIX&rsqb;. Online, the Open Group Single Unix
+      Specification &lsqb;SUS2&rsqb; provides complete documentation
+      of a superset of POSIX. If you have access to a Unix system with
+      POSIX compatibility, then the manual pages for this will be of
+      use.  There are also a number of books available.
+      &lsqb;Lewine&rsqb; covers the process, signal, file and I&sol;O
+      functions, while &lsqb;Lewis1&rsqb;, &lsqb;Lewis2&rsqb;,
+      &lsqb;Nichols&rsqb; and &lsqb;Norton&rsqb; cover Pthreads and
+      related topics (see Bibliography, xref). However, many of these
+      books are oriented toward using POSIX in non-embedded systems,
+      so care should be taken in applying them to programming under
+      eCos.
+    </para>
+    <para>
+      The remainder of this chapter broadly follows the structure
+      of the POSIX Specification. References to the appropriate
+      section of the Standard are included.
+    </para>
+    <para>
+      Omitted functions marked with &ldquo;&sol;&sol; TBA&rdquo;
+      are potential candidates for later implementation.
+    </para>
+
+<!-- }}} -->
+<!-- {{{ Process Primitives -->
+
+<sect1 id="posix-process-primitives">
+<title>Process Primitives &lsqb;POSIX Section 3&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int kill(pid&lowbar;t pid, int sig); 
+int pthread&lowbar;kill(pthread&lowbar;t thread, int sig); 
+int sigaction(int sig, const struct sigaction &ast;act,
+              struct sigaction &ast;oact); 
+int sigqueue(pid&lowbar;t pid, int sig, const union sigval value); 
+int sigprocmask(int how, const sigset&lowbar;t &ast;set,
+                sigset&lowbar;t &ast;oset); 
+int pthread&lowbar;sigmask(int how, const sigset&lowbar;t &ast;set,
+                    sigset&lowbar;t &ast;oset); 
+int sigpending(sigset&lowbar;t &ast;set);
+int sigsuspend(const sigset&lowbar;t &ast;set); 
+int sigwait(const sigset&lowbar;t &ast;set, int &ast;sig); 
+int sigwaitinfo(const sigset&lowbar;t &ast;set, siginfo&lowbar;t &ast;info); 
+int sigtimedwait(const sigset&lowbar;t &ast;set, siginfo&lowbar;t &ast;info,
+                 const struct timespec &ast;timeout); 
+int sigemptyset(sigset&lowbar;t &ast;set); 
+int sigfillset(sigset&lowbar;t &ast;set); 
+int sigaddset(sigset&lowbar;t &ast;set, int signo); 
+int sigdelset(sigset&lowbar;t &ast;set, int signo); 
+int sigismember(const sigset&lowbar;t &ast;set, int signo);
+unsigned int alarm( unsigned int seconds );
+int pause( void ); 
+unsigned int sleep( unsigned int seconds );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+pid&lowbar;t fork(void); 
+int execl( const char &ast;path, const char &ast;arg, ... ); 
+int execv( const char &ast;path, char &ast;const argv&lsqb;&rsqb; ); 
+int execle( const char &ast;path, const char &ast;arg, ... ); 
+int execve( const char &ast;path, char &ast;const argv&lsqb;&rsqb;,
+            char &ast;const envp&lsqb;&rsqb; ); 
+int execlp( const char &ast;path, const char &ast;arg, ... ); 
+int execvp( const char &ast;path, char &ast;const argv&lsqb;&rsqb; ); 
+int pthread&lowbar;atfork( void(&ast;prepare)(void),
+                    void (&ast;parent)(void),
+                    void (&ast;child)() );
+pid&lowbar;t wait( int &ast;stat&lowbar;loc );             
+pid&lowbar;t waitpid( pid&lowbar;t pid, int &ast;stat&lowbar;loc,
+               int options ); 
+void &lowbar;exit( int status );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+<itemizedlist>
+  <listitem>
+    <para>
+    Signal handling may be enabled or disabled with the
+    CYGPKG&lowbar;POSIX&lowbar;SIGNALS option. Since signals are used
+    by other POSIX components, such as timers, disabling signals will
+    disable those components too.
+    </para>
+  </listitem>
+  
+  <listitem>
+    <para>
+    <emphasis>kill()</emphasis> and
+    <emphasis>sigqueue()</emphasis> may only take a 
+    <emphasis role="strong">pid</emphasis> argument of zero,
+    which maps to the current process.
+    </para>
+  </listitem>
+  
+  <listitem>
+    <para>
+    The <emphasis>SIGEV&lowbar;THREAD</emphasis> notification type is
+           not currently implemented.
+    </para>
+  </listitem>
+  
+  <listitem>
+    <para>
+    Job Control and Memory Protection signals are
+           not supported.
+    </para>
+  </listitem>
+
+  <listitem>
+    <para>
+    An extra implementation defined
+    <emphasis>si&lowbar;code</emphasis> value,
+    <emphasis>SI&lowbar;EXCEPT</emphasis>, is defined to
+    distinguish hardware generated exceptions from
+    others.
+    </para>
+  </listitem>
+
+  <listitem>
+    <para>
+    Extra signals are defined:
+    &lowbar;SIGTRAP&lowbar;,&lowbar;SIGIOT&lowbar;,
+    &lowbar;SIGEMT&lowbar;, and &lowbar;SIGSYS&lowbar;. These are
+    largely to maintain compatibility with the signal numbers used by
+    GDB.
+    </para>
+  </listitem>
+
+  <listitem>
+    <para>
+    Signal delivery may currently occur at unexpected places in some
+    API functions. Using <emphasis>longjmp()</emphasis> to transfer
+    control out of a signal handler may result in the interrupted
+    function not being able to complete properly. This may result in
+    later function calls failing or deadlocking.
+    </para>
+  </listitem>
+</itemizedlist>
+</sect2>
+
+
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Process Environment -->
+
+<sect1 id="posix-process-environment">
+<title>Process Environment &lsqb;POSIX Section 4&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int uname( struct utsname &ast;name ); 
+time&lowbar;t time( time&lowbar;t &ast;tloc ); 
+char &ast;getenv( const char &ast;name ); 
+int isatty( int fd );
+long sysconf( int name );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<screen>
+pid&lowbar;t getpid( void ); 
+pid&lowbar;t getppid( void ); 
+uid&lowbar;t getuid( void ); 
+uid&lowbar;t geteuid( void ); 
+gid&lowbar;t getgid( void ); 
+gid&lowbar;t getegid( void ); 
+int setuid( uid&lowbar;t uid ); 
+int setgid( gid&lowbar;t gid ); 
+int getgroups( int gidsetsize, gid&lowbar;t grouplist&lsqb;&rsqb; ); 
+char &ast;getlogin( void ); 
+int getlogin&lowbar;r( char &ast;name, size&lowbar;t namesize ); 
+pid&lowbar;t getpgrp( void ); 
+pid&lowbar;t setsid( void );
+int setpgid( pid&lowbar;t pid, pid&lowbar;t pgid ); 
+char &ast;ctermid( char &ast;s); 
+char &ast;ttyname( int fd );                             &sol;&sol; TBA 
+int ttyname&lowbar;r( int fd, char &ast;name, size&lowbar;t namesize); &sol;&sol; TBA 
+clock&lowbar;t times( struct tms &ast;buffer );                 &sol;&sol; TBA
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+       <itemizedlist>
+         <listitem>
+           <para>The fields of the <emphasis>utsname</emphasis>
+           structure are initialized as follows:
+            <screen>
+           sysname     &ldquo;eCos&rdquo; 
+           nodename    &ldquo;&rdquo;  (gethostname() is currently not available)
+           
+           release             Major version number of the kernel 
+           version             Minor version number of the kernel 
+           machine     &ldquo;&rdquo;  (Requires some config tool changes)
+            </screen>
+           </para>
+           <para>
+           The sizes of these strings are defined by
+           CYG&lowbar;POSIX&lowbar;UTSNAME&lowbar;LENGTH and
+           CYG&lowbar;POSIX&lowbar;UTSNAME&lowbar;NODENAME&lowbar;LENGTH. The
+           latter defaults to the value of the former, but may also
+           be set independently to accommodate a longer node name.
+           </para>
+         </listitem>
+         
+         <listitem>
+           <para>
+           The <emphasis>time()</emphasis> function is currently
+           implemented in the C library.
+           </para>
+         </listitem>
+         
+         <listitem>
+           <para>A set of environment strings may be defined at configuration
+           time with the CYGDAT&lowbar;LIBC&lowbar;DEFAULT&lowbar;ENVIRONMENT
+           option. The application may also define an environment by direct
+           assignment to the <emphasis role="strong">environ</emphasis>
+           variable.
+           </para>
+         </listitem>
+         
+         <listitem>
+           <para>
+           At present <emphasis>isatty()</emphasis> assumes that
+           any character device is a tty and that all other devices are not
+           ttys. Since the only kind of device that eCos currently supports
+           is serial character devices, this is an adequate
+           distinction.
+           </para>
+         </listitem>
+         
+         <listitem>
+           <para>
+           All system variables supported by sysconf will yield a
+           value. However, those that are irrelevant to eCos will
+           either return the default minimum defined in
+           <filename>&lt;limits.h&gt;</filename>,
+           or zero.
+           </para>
+         </listitem>
+       </itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Files and Directories -->
+
+<sect1 id="posix-files-and-directories">
+<title>Files and Directories &lsqb;POSIX Section 5&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+DIR &ast;opendir( const char &ast;dirname ); 
+struct dirent &ast;readdir( DIR &ast;dirp ); 
+int readdir&lowbar;r( DIR &ast;dirp, struct dirent &ast;entry,
+               struct dirent &ast;&ast;result ); 
+void rewinddir( DIR &ast;dirp ); 
+int closedir( DIR &ast;dirp ); 
+int chdir( const char &ast;path ); 
+char &ast;getcwd( char &ast;buf, size&lowbar;t size );
+int open( const char &ast; path , int oflag , ... ); 
+int creat( const char &ast; path, mode&lowbar;t mode ); 
+int link( const char &ast;existing, const char &ast;new ); 
+int mkdir( const char &ast;path, mode&lowbar;t mode ); 
+int unlink( const char &ast;path ); 
+int rmdir( const char &ast;path ); 
+int rename( const char &ast;old, const char &ast;new ); 
+int stat( const char &ast;path, struct stat &ast;buf ); 
+int fstat( int fd, struct stat &ast;buf ); 
+int access( const char &ast;path, int amode ); 
+long pathconf(const char &ast;path, int name); 
+long fpathconf(int fd, int name);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+mode&lowbar;t umask( mode&lowbar;t cmask ); 
+int mkfifo( const char &ast;path, mode&lowbar;t mode ); 
+int chmod( const char &ast;path, mode&lowbar;t mode );                 &sol;&sol; TBA 
+int fchmod( int fd, mode&lowbar;t mode );                              &sol;&sol; TBA 
+int chown( const char &ast;path, uid&lowbar;t owner, gid&lowbar;t group ); 
+int utime( const char &ast;path, const struct utimbuf &ast;times );    &sol;&sol; TBA 
+int ftruncate( int fd, off&lowbar;t length );                          &sol;&sol; TBA
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+       <itemizedlist>
+         <listitem>
+           <para>
+           If a call to <function>open()</function> or <function>creat()</function> supplies
+           the third &lowbar;mode&lowbar; parameter, it will
+           currently be ignored.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           Most of the functionality of these functions depends on
+           the underlying filesystem.
+           </para>
+           </listitem>
+         <listitem>
+           <para>
+           Currently<emphasis> access()</emphasis> only checks the 
+           <emphasis>F&lowbar;OK</emphasis> mode explicitly, the others are
+           all assumed to be true by default.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           The maximum number of open files allowed is supplied by
+           the CYGNUM&lowbar;FILEIO&lowbar;NFILE option. The maximum number
+           of file descriptors is supplied by the CYGNUM&lowbar;FILEIO&lowbar;NFD
+           option.  
+           </para>
+         </listitem>
+       </itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Input and Output -->
+
+<sect1 id="posix-input-and-output">
+<title>Input and Output &lsqb;POSIX Section 6&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int dup( int fd ); 
+int dup2( int fd, int fd2 ); 
+int close(int fd); 
+ssize&lowbar;t read(int fd, void &ast;buf, size&lowbar;t nbyte); 
+ssize&lowbar;t write(int fd, const void &ast;buf, size&lowbar;t nbyte); 
+int fcntl( int fd, int cmd, ... ); 
+off&lowbar;t lseek(int fd, off&lowbar;t offset, int whence); 
+int fsync( int fd );
+int fdatasync( int fd );</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<screen>
+int pipe( int fildes&lsqb;2&rsqb; ); 
+int aio&lowbar;read( struct aiocb &ast;aiocbp );                               &sol;&sol; TBA 
+int aio&lowbar;write( struct aiocb &ast;aiocbp );                              &sol;&sol; TBA 
+int lio&lowbar;listio( int mode, struct aiocb &ast;const list&lsqb;&rsqb;,
+                int nent, struct sigevent &ast;sig);           &sol;&sol; TBA 
+int aio&lowbar;error( struct aiocb &ast;aiocbp );                              &sol;&sol; TBA 
+int aio&lowbar;return( struct aiocb &ast;aiocbp );                             &sol;&sol; TBA 
+int aio&lowbar;cancel( int fd, struct aiocb &ast;aiocbp );                     &sol;&sol; TBA 
+int aio&lowbar;suspend( const struct aiocb &ast;const list&lsqb;&rsqb;,
+                 int nent, const struct timespec &ast;timeout );       &sol;&sol; TBA 
+int aio&lowbar;fsync( int op, struct aiocb &ast;aiocbp );
+&sol;&sol; TBA
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+        <itemizedlist>
+         <listitem>
+           <para>
+           Only the <emphasis>F&lowbar;DUPFD</emphasis> command
+           of <emphasis>fcntl()</emphasis> is currently implemented.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           Most of the functionality of these functions depends on
+           the underlying filesystem.
+           </para>
+         </listitem>
+       </itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Device and Class Specific Functions -->
+
+<sect1 id="posix-device-and-class-specific-functions">
+<title>Device and Class Specific Functions &lsqb;POSIX Section 7&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+<screen>
+speed&lowbar;t cfgetospeed( const struct termios &ast;termios&lowbar;p ); 
+int cfsetospeed( struct termios &ast;termios&lowbar;p, speed&lowbar;t speed ); 
+speed&lowbar;t cfgetispeed( const struct termios &ast;termios&lowbar;p ); 
+int cfsetispeed( struct termios &ast;termios&lowbar;p, speed&lowbar;t speed ); 
+int tcgetattr( int fd, struct termios &ast;termios&lowbar;p ); 
+int tcsetattr( int fd, int optional&lowbar;actions,
+              const struct termios &ast;termios&lowbar;p ); 
+int tcsendbreak( int fd, int duration ); 
+int tcdrain( int fd );
+int tcflush( int fd, int queue&lowbar;selector ); 
+int tcsendbreak( int fd, int action );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+pid&lowbar;t tcgetpgrp( int fd ); 
+int tcsetpgrp( int fd, pid&lowbar;t pgrp );</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+        <itemizedlist>
+         <listitem>
+           <para>
+           Only the functionality relevant to basic serial device
+           control is implemented. Only very limited support for
+           canonical input is provided, and then only via the
+           &ldquo;tty&rdquo; devices, not the &ldquo;serial&rdquo;
+           devices. None of the functionality relevant to job
+           control, controlling terminals and sessions is
+           implemented.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           Only <emphasis>MIN</emphasis> &equals; 0 and
+           <emphasis>TIME</emphasis> &equals; 0 functionality is
+           provided.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           Hardware flow control is supported if the underlying
+           device driver and serial port support it.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           Support for break, framing and parity errors depends on
+           the functionality of the hardware and device driver.
+           </para>
+         </listitem>
+       </itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ C Language Services -->
+
+<sect1 id="posix-C-language-services">
+<title>C Language Services &lsqb;POSIX Section 8&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+<screen>
+char &ast;setlocale( int category, const char &ast;locale ); 
+int fileno( FILE &ast;stream ); 
+FILE &ast;fdopen( int fd, const char &ast;type ); 
+int getc&lowbar;unlocked( FILE &ast;stream); 
+int getchar&lowbar;unlocked( void ); 
+int putc&lowbar;unlocked( FILE &ast;stream ); 
+int putchar&lowbar;unlocked( void ); 
+char &ast;strtok&lowbar;r( char &ast;s, const char &ast;sep, 
+                char &ast;&ast;lasts ); 
+char &ast;asctime&lowbar;r( const struct tm &ast;tm, char &ast;buf ); 
+char &ast;ctime&lowbar;r( const time&lowbar;t &ast;clock, char &ast;buf ); 
+struct tm &ast;gmtime&lowbar;r( const time&lowbar;t &ast;clock,
+                     struct tm &ast;result ); 
+struct tm &ast;localtime&lowbar;r( const time&lowbar;t &ast;clock,
+                        struct tm &ast;result ); 
+int rand&lowbar;r( unsigned int &ast;seed );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<screen>
+void flockfile( FILE &ast;file ); 
+int ftrylockfile( FILE &ast;file ); 
+void funlockfile( FILE &ast;file ); 
+int sigsetjmp( sigjmp&lowbar;buf env, int savemask );                  &sol;&sol; TBA 
+void siglongjmp( sigjmp&lowbar;buf env, int val );                     &sol;&sol; TBA 
+void tzset(void);                                                       &sol;&sol; TBA
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+       <itemizedlist>
+         <listitem>
+           <para>
+           <emphasis>setlocale()</emphasis> is implemented in the C
+           library Internationalization package.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           Functions <emphasis>fileno()</emphasis> and
+           <emphasis>fdopen()</emphasis> are implemented in the C
+           library STDIO package.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           Functions <emphasis>getc&lowbar;unlocked()</emphasis>, 
+           <emphasis>getchar&lowbar;unlocked()</emphasis>,
+           <emphasis>putc&lowbar;unlocked()</emphasis> and
+           <emphasis>putchar&lowbar;unlocked()</emphasis> are defined
+           but are currently identical to their non-unlocked
+           equivalents.
+           </para>
+         </listitem>
+         <listitem>
+           <para>
+           <emphasis>strtok&lowbar;r()</emphasis>, <emphasis>asctime&lowbar;r()</emphasis>, 
+           <emphasis>ctime&lowbar;r()</emphasis>, <emphasis>gmtime&lowbar;r()</emphasis>, 
+           <emphasis>localtime&lowbar;r()</emphasis> and
+           <emphasis>rand&lowbar;r()</emphasis> are all currently in
+           the C library, alongside their non-reentrant versions.
+           </para>
+         </listitem>
+       </itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ System Databases -->
+
+<sect1 id="posix-system-databases">
+<title>System Databases &lsqb;POSIX Section 9&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+       
+<para>
+&lt;none&gt;
+</para>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+struct group &ast;getgrgid( gid&lowbar;t gid ); 
+int getgrgid( gid&lowbar;t gid, struct group &ast;grp, char &ast;buffer, 
+             size&lowbar;t bufsize, struct group &ast;&ast;result ); 
+struct group &ast;getgrname( const char &ast;name ); 
+int getgrname&lowbar;r( const char &ast;name, struct group &ast;grp,
+                 char &ast;buffer, size&lowbar;t bufsize, struct group &ast;&ast;result ); 
+struct passwd &ast;getpwuid( uid&lowbar;t uid ); 
+int getpwuid&lowbar;r( uid&lowbar;t uid, struct passwd &ast;pwd,
+                char &ast;buffer, size&lowbar;t bufsize, struct passwd &ast;&ast;result ); 
+struct passwd &ast;getpwnam( const char &ast;name ); 
+int getpwnam&lowbar;r( const char &ast;name, struct passwd &ast;pwd,
+                char &ast;buffer, size&lowbar;t bufsize, struct passwd &ast;&ast;result );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+        <itemizedlist>
+         <listitem>
+           <para>
+           None of the functions in this section are implemented.
+           </para>
+         </listitem>
+       </itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Data Interchange Format -->
+
+<sect1 id="posix-data-interchange-format">
+<title>Data Interchange Format &lsqb;POSIX Section 10&rsqb;</title>
+      
+<para>
+This section details <emphasis>tar</emphasis> and
+<emphasis>cpio</emphasis> formats. Neither of these is supported by
+eCos.
+</para>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Synchronization -->
+
+<sect1 id="posix-synchronization">
+<title>Synchronization &lsqb;POSIX Section 11&rsqb;</title>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int sem&lowbar;init(sem&lowbar;t &ast;sem, int pshared, unsigned int value); 
+int sem&lowbar;destroy(sem&lowbar;t &ast;sem); 
+int sem&lowbar;wait(sem&lowbar;t &ast;sem); 
+int sem&lowbar;trywait(sem&lowbar;t &ast;sem); 
+int sem&lowbar;post(sem&lowbar;t &ast;sem);
+int sem&lowbar;getvalue(sem&lowbar;t &ast;sem, int &ast;sval); 
+int pthread&lowbar;mutexattr&lowbar;init( pthread&lowbar;mutexattr&lowbar;t &ast;attr); 
+int pthread&lowbar;mutexattr&lowbar;destroy( pthread&lowbar;mutexattr&lowbar;t &ast;attr); 
+int pthread&lowbar;mutex&lowbar;init(pthread&lowbar;mutex&lowbar;t &ast;mutex,
+                      const pthread&lowbar;mutexattr&lowbar;t &ast;mutex&lowbar;attr); 
+int pthread&lowbar;mutex&lowbar;destroy(pthread&lowbar;mutex&lowbar;t &ast;mutex); 
+int pthread&lowbar;mutex&lowbar;lock(pthread&lowbar;mutex&lowbar;t &ast;mutex); 
+int pthread&lowbar;mutex&lowbar;trylock(pthread&lowbar;mutex&lowbar;t &ast;mutex); 
+int pthread&lowbar;mutex&lowbar;unlock(pthread&lowbar;mutex&lowbar;t &ast;mutex); 
+int pthread&lowbar;condattr&lowbar;init(pthread&lowbar;condattr&lowbar;t &ast;attr); 
+int pthread&lowbar;condattr&lowbar;destroy(pthread&lowbar;condattr&lowbar;t &ast;attr); 
+int pthread&lowbar;cond&lowbar;init(pthread&lowbar;cond&lowbar;t &ast;cond, 
+                      const pthread&lowbar;condattr&lowbar;t &ast;attr); 
+int pthread&lowbar;cond&lowbar;destroy(pthread&lowbar;cond&lowbar;t &ast;cond); 
+int pthread&lowbar;cond&lowbar;signal(pthread&lowbar;cond&lowbar;t &ast;cond); 
+int pthread&lowbar;cond&lowbar;broadcast(pthread&lowbar;cond&lowbar;t &ast;cond); 
+int pthread&lowbar;cond&lowbar;wait(pthread&lowbar;cond&lowbar;t &ast;cond, 
+                      pthread&lowbar;mutex&lowbar;t &ast;mutex);
+int pthread&lowbar;cond&lowbar;timedwait(pthread&lowbar;cond&lowbar;t &ast;cond,
+                          pthread&lowbar;mutex&lowbar;t &ast;mutex,
+                          const struct timespec &ast;abstime);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+sem&lowbar;t &ast;sem&lowbar;open(const char &ast;name, int oflag, ...);               &sol;&sol; TBA 
+int sem&lowbar;close(sem&lowbar;t &ast;sem);                                   &sol;&sol; TBA 
+int sem&lowbar;unlink(const char &ast;name);                           &sol;&sol; TBA 
+int pthread&lowbar;mutexattr&lowbar;getpshared( const pthread&lowbar;mutexattr&lowbar;t &ast;attr,
+                                 int &ast;pshared );
+int pthread&lowbar;mutexattr&lowbar;setpshared( const pthread&lowbar;mutexattr&lowbar;t &ast;attr,
+                                 int pshared );
+int  pthread&lowbar;condattr&lowbar;getpshared( const pthread&lowbar;condattr&lowbar;t &ast;attr, 
+                                 int &ast;pshared);
+int  pthread&lowbar;condattr&lowbar;setpshared( const pthread&lowbar;condattr&lowbar;t &ast;attr,
+                                 int pshared);</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+        <itemizedlist>
+         <listitem>
+           <para>
+           The presence of semaphores is controlled by the
+           CYGPKG&lowbar;POSIX&lowbar;SEMAPHORES option. This in turn
+           causes the &lowbar;POSIX&lowbar;SEMAPHORES feature test
+           macro to be defined and the semaphore API to be made
+           available.
+           </para>
+         </listitem>
+         
+         <listitem>
+           <para>
+           The <emphasis role="strong">pshared</emphasis> argument to
+           <emphasis>sem&lowbar;init()</emphasis> is not implemented,
+           its value is ignored.
+           </para>
+         </listitem>
+         
+         <listitem>
+           <para>
+           Functions <emphasis>sem&lowbar;open()</emphasis>, 
+           <emphasis>sem&lowbar;close()</emphasis> and
+           <emphasis>sem&lowbar;unlink()</emphasis> are present but
+           always return an error (ENOSYS).
+           </para>
+         </listitem>
+
+         <listitem>
+           <para>
+           The exact priority inversion protocols supported may be
+           controlled with the
+           &lowbar;POSIX&lowbar;THREAD&lowbar;PRIO&lowbar;INHERIT and
+           &lowbar;POSIX&lowbar;THREAD&lowbar;PRIO&lowbar;PROTECT
+           configuration options.
+           </para>
+         </listitem>
+         
+         <listitem>
+           <para>
+           &lcub;&lowbar;POSIX&lowbar;THREAD&lowbar;PROCESS&lowbar;SHARED&rcub; is
+           not defined, so the 
+           <emphasis role="strong">process-shared</emphasis> mutex
+           and condition variable attributes are not supported, and
+           neither are the functions
+           <emphasis>pthread&lowbar;mutexattr&lowbar;getpshared()</emphasis>,
+           <emphasis>pthread&lowbar;mutexattr&lowbar;setpshared()</emphasis>, 
+           <emphasis>pthread&lowbar;condattr&lowbar;getpshared()</emphasis> and 
+           <emphasis>pthread&lowbar;condattr&lowbar;setpshared()</emphasis>. 
+           </para>
+         </listitem>
+         
+         <listitem>
+         <para>
+           Condition variables do not become bound to a particular
+           mutex when
+           <emphasis>pthread&lowbar;cond&lowbar;wait()</emphasis> is
+           called. Hence different threads may wait on a condition
+           variable with different mutexes. This is at variance with
+           the standard, which requires a condition variable to
+           become (dynamically) bound by the first waiter, and
+           unbound when the last finishes. However, this difference
+           is largely benign, and the cost of policing this feature
+           is non-trivial.
+         </para>
+       </listitem>
+       </itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Memory Management -->
+
+<sect1 id="posix-memory-management">
+<title>Memory Management &lsqb;POSIX Section 12&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+       
+<para>
+&lt;none&gt;
+</para>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+int mlockall( int flags ); 
+int munlockall( void ); 
+int mlock( const void &ast;addr, size&lowbar;t len ); 
+int munlock( const void &ast;addr, size&lowbar;t len ); 
+void mmap( void &ast;addr, size&lowbar;t len, int prot, int flags,      
+          int fd, off&lowbar;t off ); 
+int munmap( void &ast;addr, size&lowbar;t len ); 
+int mprotect( const void &ast;addr, size&lowbar;t len, int prot ); 
+int msync( void &ast;addr, size&lowbar;t len, int flags ); 
+int shm&lowbar;open( const char &ast;name, int oflag, mode&lowbar;t mode ); 
+int shm&lowbar;unlink( const char &ast;name );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+<para>
+None of these functions are currently provided. Some may
+be implemented in a restricted form in the future.
+</para>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Execution Scheduling -->
+
+<sect1 id="posix-execution-scheduling">
+<title>Execution Scheduling &lsqb;POSIX Section 13&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int sched&lowbar;yield(void); 
+int sched&lowbar;get&lowbar;priority&lowbar;max(int policy); 
+int sched&lowbar;get&lowbar;priority&lowbar;min(int policy); 
+int sched&lowbar;rr&lowbar;get&lowbar;interval(pid&lowbar;t pid, struct timespec &ast;t); 
+int pthread&lowbar;attr&lowbar;setscope(pthread&lowbar;attr&lowbar;t &ast;attr, int scope); 
+int pthread&lowbar;attr&lowbar;getscope(const pthread&lowbar;attr&lowbar;t &ast;attr, int &ast;scope); 
+int pthread&lowbar;attr&lowbar;setinheritsched(pthread&lowbar;attr&lowbar;t &ast;attr, int inherit); 
+int pthread&lowbar;attr&lowbar;getinheritsched(const pthread&lowbar;attr&lowbar;t &ast;attr, int &ast;inherit); 
+int pthread&lowbar;attr&lowbar;setschedpolicy(pthread&lowbar;attr&lowbar;t &ast;attr, int policy); 
+int pthread&lowbar;attr&lowbar;getschedpolicy(const pthread&lowbar;attr&lowbar;t &ast;attr, int &ast;policy);
+int pthread&lowbar;attr&lowbar;setschedparam( pthread&lowbar;attr&lowbar;t &ast;attr, const struct sched&lowbar;param &ast;param); 
+int pthread&lowbar;attr&lowbar;getschedparam( const pthread&lowbar;attr&lowbar;t &ast;attr,
+                               struct sched&lowbar;param &ast;param); 
+int pthread&lowbar;setschedparam(pthread&lowbar;t thread, int policy,
+                         const struct sched&lowbar;param &ast;param); 
+int pthread&lowbar;getschedparam(pthread&lowbar;t thread, int &ast;policy,
+                         struct sched&lowbar;param &ast;param); 
+int pthread&lowbar;mutexattr&lowbar;setprotocol( pthread&lowbar;mutexattr&lowbar;t &ast;attr,
+                                   int protocol);
+int pthread&lowbar;mutexattr&lowbar;getprotocol( pthread&lowbar;mutexattr&lowbar;t &ast;attr,
+                                   int &ast;protocol); 
+int pthread&lowbar;mutexattr&lowbar;setprioceiling( pthread&lowbar;mutexattr&lowbar;t &ast;attr,
+                                      int prioceiling); 
+int pthread&lowbar;mutexattr&lowbar;getprioceiling( pthread&lowbar;mutexattr&lowbar;t &ast;attr,
+                                     int &ast;prioceiling);
+int pthread&lowbar;mutex&lowbar;setprioceiling( pthread&lowbar;mutex&lowbar;t &ast;mutex,
+                                 int prioceiling,
+                                 int &ast;old&lowbar;ceiling); 
+int pthread&lowbar;mutex&lowbar;getprioceiling( pthread&lowbar;mutex&lowbar;t &ast;mutex,
+                                  int &ast;prioceiling);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+int sched&lowbar;setparam(pid&lowbar;t pid, const struct sched&lowbar;param &ast;param); 
+int sched&lowbar;getparam(pid&lowbar;t pid, struct sched&lowbar;param &ast;param); 
+int sched&lowbar;setscheduler(pid&lowbar;t pid, int policy,
+                      const struct sched&lowbar;param &ast;param); 
+int sched&lowbar;getscheduler(pid&lowbar;t pid);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+        <itemizedlist>
+       <listitem>
+         <para>
+         The functions <emphasis>sched&lowbar;setparam()</emphasis>, 
+         <emphasis>sched&lowbar;getparam()</emphasis>,
+         <emphasis>sched&lowbar;setscheduler()</emphasis> and
+         <emphasis>sched&lowbar;getscheduler()</emphasis> are present
+         but always return an error.
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+         The scheduler policy <emphasis>SCHED&lowbar;OTHER</emphasis> is
+         equivalent to <emphasis>SCHED&lowbar;RR</emphasis>.
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+         Only <emphasis>PTHREAD&lowbar;SCOPE&lowbar;SYSTEM</emphasis>
+         is supported as a
+         <emphasis role="strong">contentionscope</emphasis>
+         attribute.
+         </para>
+       </listitem>
+       <listitem>
+         <para>
+         The default thread scheduling attributes are:
+         <screen>
+         contentionscope          PTHREAD&lowbar;SCOPE&lowbar;SYSTEM
+         inheritsched             PTHREAD&lowbar;INHERIT&lowbar;SCHED
+         schedpolicy              SCHED&lowbar;OTHER
+         schedparam.sched         0
+         </screen>
+          </para>
+       </listitem>
+       <listitem>
+         <para>
+         Mutex priority inversion protection is controlled by a
+         number of kernel configuration options.
+         If CYGSEM&lowbar;KERNEL&lowbar;SYNCH&lowbar;MUTEX&lowbar;PRIORITY&lowbar;INVERSION&lowbar;PROTOCOL&lowbar;INHERIT
+         is defined then
+         &lcub;&lowbar;POSIX&lowbar;THREAD&lowbar;PRIO&lowbar;INHERIT&rcub;
+         will be defined and PTHREAD&lowbar;PRIO&lowbar;INHERIT may
+         be set as the protocol in a
+         <emphasis>pthread&lowbar;mutexattr&lowbar;t</emphasis>
+         object.
+         If CYGSEM&lowbar;KERNEL&lowbar;SYNCH&lowbar;MUTEX&lowbar;PRIORITY&lowbar;INVERSION&lowbar;PROTOCOL&lowbar;CEILING
+         is defined then
+         &lcub;&lowbar;POSIX&lowbar;THREAD&lowbar;PRIO&lowbar;PROTECT&rcub;
+         will be defined and PTHREAD&lowbar;PRIO&lowbar;PROTECT may
+         be set as the protocol in a
+         <emphasis>pthread&lowbar;mutexattr&lowbar;t</emphasis> object.
+          </para>
+       </listitem>
+       <listitem>
+         <para>
+         The default attribute values set by
+         <emphasis>pthread&lowbar;mutexattr&lowbar;init()</emphasis>
+         is to set the protocol attribute to
+         PTHREAD&lowbar;PRIO&lowbar;NONE and the prioceiling
+         attribute to zero.
+         </para>
+       </listitem>
+       </itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Clocks and Timers -->
+
+<sect1 id="posix-clocks-and-timers">
+<title>Clocks and Timers &lsqb;POSIX Section 14&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int clock&lowbar;settime( clockid&lowbar;t clock&lowbar;id,
+const struct timespec &ast;tp); 
+int clock&lowbar;gettime( clockid&lowbar;t clock&lowbar;id, struct timespec &ast;tp); 
+int clock&lowbar;getres( clockid&lowbar;t clock&lowbar;id, struct timespec &ast;tp); 
+int timer&lowbar;create( clockid&lowbar;t clock&lowbar;id, struct sigevent &ast;evp,
+                 timer&lowbar;t &ast;timer&lowbar;id);
+int timer&lowbar;delete( timer&lowbar;t timer&lowbar;id ); 
+int timer&lowbar;settime( timer&lowbar;t timerid, int flags,
+                  const struct itimerspec &ast;value,
+                  struct itimerspec &ast;ovalue ); 
+int timer&lowbar;gettime( timer&lowbar;t timerid, struct itimerspec &ast;value ); 
+int timer&lowbar;getoverrun( timer&lowbar;t timerid ); 
+int nanosleep( const struct timespec &ast;rqtp, struct timespec &ast;rmtp);
+</screen>
+
+</sect2>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+       
+<para>
+&lt;none&gt;
+</para>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+<itemizedlist>
+  <listitem>
+    <para>
+    Currently <emphasis>timer&lowbar;getoverrun()</emphasis> only
+    reports timer notifications that are delayed in the timer
+    subsystem.  If they are delayed in the signal subsystem, due to
+    signal masks for example, this is not counted as an overrun.
+    </para>
+  </listitem>
+
+  <listitem>
+    <para>
+    The option CYGPKG&lowbar;POSIX&lowbar;TIMERS allows the timer support to be
+    enabled or disabled, and causes &lowbar;POSIX&lowbar;TIMERS to be defined
+    appropriately. This will cause other parts of the POSIX system to
+    have limited functionality.
+    </para>
+  </listitem>
+
+</itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Message Passing -->
+
+<sect1 id="posix-message-passing">
+<title>Message Passing &lsqb;POSIX Section 15&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+mqd&lowbar;t mq&lowbar;open( const char &ast;name, int  oflag, ... ); 
+int mq&lowbar;close( mqd&lowbar;t  mqdes ); 
+int mq&lowbar;unlink( const char &ast;name );
+int mq&lowbar;send( mqd&lowbar;t mqdes, const char &ast;msg&lowbar;ptr,
+            size&lowbar;t msg&lowbar;len, unsigned int msg&lowbar;prio ); 
+ssize&lowbar;t mq&lowbar;receive( mqd&lowbar;t mqdes, char &ast;msg&lowbar;ptr,
+                   size&lowbar;t msg&lowbar;len, unsigned int &ast;msg&lowbar;prio );
+int mq&lowbar;setattr( mqd&lowbar;t mqdes, const struct mq&lowbar;attr &ast;mqstat,
+               struct mq&lowbar;attr &ast;omqstat ); 
+int mq&lowbar;getattr( mqd&lowbar;t mqdes, struct mq&lowbar;attr &ast;mqstat ); 
+int mq&lowbar;notify( mqd&lowbar;t mqdes, const struct sigevent &ast;notification );
+</screen>
+<para>From POSIX 1003.1d draft: </para>
+<screen>
+int mq&lowbar;send( mqd&lowbar;t mqdes, const char &ast;msg&lowbar;ptr,
+            size&lowbar;t msg&lowbar;len, unsigned int msg&lowbar;prio,
+             const struct timespec *abs_timeout ); 
+ssize&lowbar;t mq&lowbar;receive( mqd&lowbar;t mqdes, char &ast;msg&lowbar;ptr,
+                   size&lowbar;t msg&lowbar;len, unsigned int &ast;msg&lowbar;prio,
+             const struct timespec *abs_timeout );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+       
+<para>
+&lt;none&gt;
+</para>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+<itemizedlist>
+  <listitem>
+    <para>
+    The presence of message queues is controlled by the
+    CYGPKG&lowbar;POSIX&lowbar;MQUEUES option.  Setting this will
+    cause &lsqb;&lowbar;POSIX&lowbar;MESSAGE&lowbar;PASSING&rsqb; to
+    be defined and the message queue API to be made available.
+    </para>
+  </listitem>
+
+  <listitem>
+    <para>
+    Message queues are not currently filesystem objects. They live in
+    their own name and descriptor spaces.
+    </para>
+  </listitem>
+</itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Thread Management -->
+
+<sect1 id="posix-thread-management">
+<title>Thread Management &lsqb;POSIX Section 16&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int pthread&lowbar;attr&lowbar;init(pthread&lowbar;attr&lowbar;t &ast;attr); 
+int pthread&lowbar;attr&lowbar;destroy(pthread&lowbar;attr&lowbar;t &ast;attr); 
+int pthread&lowbar;attr&lowbar;setdetachstate(pthread&lowbar;attr&lowbar;t &ast;attr,
+                                int detachstate); 
+int pthread&lowbar;attr&lowbar;getdetachstate(const pthread&lowbar;attr&lowbar;t &ast;attr,
+                               int &ast;detachstate); 
+int pthread&lowbar;attr&lowbar;setstackaddr(pthread&lowbar;attr&lowbar;t &ast;attr,
+                              void &ast;stackaddr); 
+int pthread&lowbar;attr&lowbar;getstackaddr(const pthread&lowbar;attr&lowbar;t &ast;attr,
+                             void &ast;&ast;stackaddr); 
+int pthread&lowbar;attr&lowbar;setstacksize(pthread&lowbar;attr&lowbar;t &ast;attr,
+                              size&lowbar;t stacksize); 
+int pthread&lowbar;attr&lowbar;getstacksize(const pthread&lowbar;attr&lowbar;t &ast;attr,
+                             size&lowbar;t &ast;stacksize); 
+int pthread&lowbar;create( pthread&lowbar;t &ast;thread,
+                    const pthread&lowbar;attr&lowbar;t &ast;attr,
+                   void &ast;(&ast;start&lowbar;routine)(void &ast;),
+                   void &ast;arg);
+pthread&lowbar;t pthread&lowbar;self( void ); 
+int pthread&lowbar;equal(pthread&lowbar;t thread1, pthread&lowbar;t thread2); 
+void pthread&lowbar;exit(void &ast;retval); 
+int pthread&lowbar;join(pthread&lowbar;t thread, void &ast;&ast;thread&lowbar;return); 
+int pthread&lowbar;detach(pthread&lowbar;t thread); 
+int pthread&lowbar;once(pthread&lowbar;once&lowbar;t &ast;once&lowbar;control,
+                void (&ast;init&lowbar;routine)(void));
+</screen>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+       
+<para>
+&lt;none&gt;
+</para>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+<itemizedlist>
+  <listitem>
+    <para>
+    The presence of thread support as a whole is controlled by the the
+    CYGPKG_POSIX_PTHREAD configuration option. Note that disabling
+    this will also disable many other features of the POSIX package,
+    since these are intimately bound up with the thread mechanism.
+    </para>
+  </listitem>
+  
+  <listitem>
+    <para>
+    The default (non-scheduling) thread attributes are:
+    </para>
+    <screen>
+    detachstate            PTHREAD&lowbar;CREATE&lowbar;JOINABLE
+    stackaddr              unset
+    stacksize              unset
+    </screen>
+  </listitem>
+  
+  <listitem>
+    <para>
+      Dynamic thread stack allocation is only provided if there is an
+      implementation of
+      <emphasis>malloc()</emphasis> configured (i.e. a package
+      implements the
+      CYGINT&lowbar;MEMALLOC&lowbar;MALLOC&lowbar;ALLOCATORS
+      interface). If there is no malloc() available, then the thread
+      creator must supply a stack. If only a stack address is supplied
+      then the stack is assumed to be PTHREAD&lowbar;STACK&lowbar;MIN
+      bytes long. This size is seldom useful for any but the most
+      trivial of threads.  If a different sized stack is used, both
+      the stack address and stack size must be supplied.
+    </para>
+  </listitem>
+  
+  <listitem>
+    <para>
+      The value of PTHREAD&lowbar;THREADS&lowbar;MAX is supplied by
+      the CYGNUM&lowbar;POSIX&lowbar;PTHREAD&lowbar;THREADS&lowbar;MAX
+      option. This defines the maximum number of threads allowed. The
+      POSIX standard requires this value to be at least 64, and this
+      is the default value set.
+    </para>
+  </listitem>
+
+  <listitem>
+    <para>
+    When the POSIX package is installed, the thread that calls 
+    <emphasis>main()</emphasis> is initialized as a POSIX thread. The
+    priority of that thread is controlled by the
+    CYGNUM&lowbar;POSIX&lowbar;MAIN&lowbar;DEFAULT&lowbar;PRIORITY option.
+    </para>
+  </listitem>
+</itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Thread-Specific Data -->
+
+<sect1 id="posix-thread-specific-data">
+<title>Thread-Specific Data &lsqb;POSIX Section 17&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int pthread&lowbar;key&lowbar;create(pthread&lowbar;key&lowbar;t &ast;key,
+                      void (&ast;destructor)(void &ast;)); 
+int pthread&lowbar;setspecific(pthread&lowbar;key&lowbar;t key, const void &ast;pointer); 
+void &ast;pthread&lowbar;getspecific(pthread&lowbar;key&lowbar;t key); 
+int pthread&lowbar;key&lowbar;delete(pthread&lowbar;key&lowbar;t key);
+</screen>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<para>
+&lt;none&gt;
+</para>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+<itemizedlist>
+  <listitem>
+    <para>
+    The value of PTHREAD&lowbar;DESTRUCTOR&lowbar;ITERATIONS is
+    provided by the
+    CYGNUM&lowbar;POSIX&lowbar;PTHREAD&lowbar;DESTRUCTOR&lowbar;ITERATIONS
+    option. This controls the number of times that a key destructor
+    will be called while the data item remains non-NULL.
+    </para>
+  </listitem>
+  
+  <listitem>
+    <para>
+    The value of PTHREAD&lowbar;KEYS&lowbar;MAX is provided
+    by the CYGNUM&lowbar;POSIX&lowbar;PTHREAD&lowbar;KEYS&lowbar;MAX
+    option. This defines the maximum number of per-thread data items
+    supported. The POSIX standard calls for this to be a minimum of
+    128, which is rather large for an embedded system. The default
+    value for this option is set to 128 for compatibility but it
+    should be reduced to a more usable value.
+    </para>
+  </listitem>
+</itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Thread Cancellation -->
+
+<sect1 id="posix-thread-cancellation">
+<title>Thread Cancellation &lsqb;POSIX Section 18&rsqb;</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int pthread&lowbar;cancel(pthread&lowbar;t thread); 
+int pthread&lowbar;setcancelstate(int state, int &ast;oldstate); 
+int pthread&lowbar;setcanceltype(int type, int &ast;oldtype); 
+void pthread&lowbar;testcancel(void); 
+void pthread&lowbar;cleanup&lowbar;push( void (&ast;routine)(void &ast;),
+                           void &ast;arg); 
+void pthread&lowbar;cleanup&lowbar;pop( int execute);
+</screen>
+</sect2>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<para>
+&lt;none&gt;
+</para>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+<para>
+Asynchronous cancellation is only partially implemented.  In
+particular, cancellation may occur in unexpected places in some
+functions. It is strongly recommended that only synchronous
+cancellation be used. 
+</para>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Non-POSIX Functions -->
+
+<sect1 id="posix-non-posix-functions">
+<title>Non-POSIX Functions</title>
+       
+<para>
+In addition to the standard POSIX functions defined above, the
+following non-POSIX functions are defined in the FILEIO package.
+</para>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>General I&sol;O Functions</title>
+<screen>
+int ioctl( int fd, CYG&lowbar;ADDRWORD com, CYG&lowbar;ADDRWORD data ); 
+int select( int nfd, fd&lowbar;set &ast;in, fd&lowbar;set &ast;out, fd&lowbar;set &ast;ex, struct timeval &ast;tv);
+</screen>
+</sect2>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Socket Functions</title>
+<screen>
+int socket( int domain, int type, int protocol); 
+int bind( int s, const struct sockaddr &ast;sa, unsigned int len); 
+int listen( int s, int len); 
+int accept( int s, struct sockaddr &ast;sa, socklen&lowbar;t &ast;addrlen); 
+int connect( int s, const struct sockaddr &ast;sa, socklen&lowbar;t len); 
+int getpeername( int s, struct sockaddr &ast;sa, socklen&lowbar;t &ast;len); 
+int getsockname( int s, struct sockaddr &ast;sa, socklen&lowbar;t &ast;len); 
+int setsockopt( int s, int level, int optname, const void &ast;optval,
+               socklen&lowbar;t optlen); 
+int getsockopt( int s, int level, int optname, void &ast;optval,
+               socklen&lowbar;t &ast;optlen); 
+ssize&lowbar;t recvmsg( int s, struct msghdr &ast;msg, int flags); 
+ssize&lowbar;t recvfrom( int s, void &ast;buf, size&lowbar;t len, int flags, 
+                 struct sockaddr &ast;from, socklen&lowbar;t &ast;fromlen); 
+ssize&lowbar;t recv( int s, void &ast;buf, size&lowbar;t len, int flags); 
+ssize&lowbar;t sendmsg( int s, const struct msghdr &ast;msg, int flags); 
+ssize&lowbar;t sendto( int s, const void &ast;buf, size&lowbar;t len, int flags, 
+               const struct sockaddr &ast;to, socklen&lowbar;t tolen); 
+ssize&lowbar;t send( int s, const void &ast;buf, size&lowbar;t len, int flags); 
+int shutdown( int s, int how);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+<itemizedlist>
+  <listitem>
+   <para>
+   The precise behaviour of these functions depends mainly on the
+   functionality of the underlying filesystem or network stack to
+   which they are applied.
+   </para>
+  </listitem>
+</itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+
+</chapter>
+
+<!-- {{{ Bibliography -->
+
+<bibliography id="posix-references-and-bibliography">
+<title>References and Bibliography</title>
+
+    <bibliomixed>
+      <bibliomisc>&lsqb;Lewine&rsqb;</bibliomisc>
+      <author>
+       <firstname>Donald</firstname>
+       <othername>A.</othername>
+       <surname>Lweine</surname>
+      </author>
+      <title>Posix Programmer&rsquo;s Guide: Writing Portable Unix
+       Programs With the POSIX.1 Standard O&rsquo;Reilly &amp;
+       Associates; ISBN: 0937175730.</title></bibliomixed>
+
+    <bibliomixed>
+      <bibliomisc>&lsqb;Lewis1&rsqb;</bibliomisc>
+      <author>
+       <firstname>Bil</firstname>
+       <surname>Lewis</surname>
+      </author>
+      <author>
+       <firstname>Daniel</firstname>
+       <othername>J.</othername>
+       <surname>Berg</surname>
+      </author>
+      <title>Threads Primer: A Guide to Multithreaded Programming</title>
+      <publishername>Prentice Hall</publishername>
+      <isbn>ISBN: 013443698</isbn>
+    </bibliomixed>
+
+    <bibliomixed>
+      <bibliomisc>&lsqb;Lewis2&rsqb;</bibliomisc>
+      <author>
+       <firstname>Bil</firstname>
+       <surname>Lewis</surname>
+      </author>
+      <author>
+       <firstname>Daniel</firstname>
+       <othername>J.</othername>
+       <surname>Berg</surname>
+      </author>
+      <title>Multithreaded Programming With Pthreads</title>
+      <publisher>
+       <publishername>Prentice Hall Computer Books</publishername>
+      </publisher>
+      <isbn>ISBN: 0136807291</isbn>
+    </bibliomixed>
+
+    <bibliomixed>
+      <bibliomisc>&lsqb;Nichols&rsqb;</bibliomisc>
+      <author>
+       <firstname>Bradford</firstname>
+       <surname>Nichols</surname>
+      </author>
+      <author>
+       <firstname>Dick</firstname>
+       <surname>Buttlar</surname>
+      </author>
+      <author>
+       <firstname>Jacqueline</firstname>
+       <othername>Proulx</othername>
+       <surname>Farrell</surname>
+      </author>
+      <title>Pthreads Programming: A POSIX Standard for Better
+       Multiprocessing (O&rsquo;Reilly Nutshell)</title>
+      <publisher><publishername>O&rsquo;Reilly &amp; Associates</publishername>
+      </publisher>
+      <isbn>ISBN: 1565921151</isbn>
+    </bibliomixed>
+
+    <bibliomixed>
+      <bibliomisc>&lsqb;Norton&rsqb;</bibliomisc>
+      <author>
+       <firstname>Scott</firstname>
+       <othername>J.</othername>
+       <surname>Norton</surname>
+      </author>
+      <author>
+       <firstname>Mark</firstname>
+       <othername>D.</othername>
+       <surname>Depasquale</surname>
+      </author>
+      <title>Thread Time: The MultiThreaded Programming Guide</title>
+      <publisher><publishername>Prentice Hall</publishername>
+      </publisher>
+      <isbn>ISBN: 0131900676</isbn></bibliomixed>
+
+
+    <bibliomixed>
+      <bibliomisc>&lsqb;POSIX&rsqb;</bibliomisc>
+      <title>Portable Operating System Interface(POSIX) -
+Part 1: System Application Programming Interface (API)&lsqb;C
+Language&rsqb;</title>
+      <corpauthor>ISO&sol;IEC 9945-1:1996, IEEE</corpauthor></bibliomixed>
+
+    <bibliomixed>
+      <bibliomisc>&lsqb;SUS2&rsqb;</bibliomisc>
+      <title>Open Group; Single Unix Specification, Version 2</title>
+      <bibliomisc><ulink
+      url="http://www.opengroup.org/public/pubs/online/7908799/index.html">http://www.opengroup.org/public/pubs/online/7908799/index.html</ulink></bibliomisc>
+    </bibliomixed>
+
+  </bibliography>
+
+<!-- }}} -->
+
+</part>
diff --git a/packages/compat/posix/v2_0/include/export.h b/packages/compat/posix/v2_0/include/export.h
new file mode 100644 (file)
index 0000000..36edf0d
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef CYGONCE_POSIX_EXPORT_H
+#define CYGONCE_POSIX_EXPORT_H
+//=============================================================================
+//
+//      export.h
+//
+//      POSIX export header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Nick Garnett
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-09-18
+// Purpose:       POSIX export header
+// Description:   This header contains definitions that the POSIX package exports
+//                to other packages. These are generally interfaces that are not
+//                provided by the public API.
+//                
+//              
+// Usage:
+//              #ifdef CYGPKG_POSIX
+//              #include <export.h>
+//              #endif
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <stddef.h>             // NULL, size_t
+
+#include <limits.h>
+#include <signal.h>
+
+#include <sys/types.h>
+
+#include <sched.h>              // SCHED_*
+
+//=============================================================================
+// POSIX API function management.
+// These macros should be inserted near the start and all returns of
+// any function that is part of the POSIX API.
+
+__externC void cyg_posix_function_start();
+__externC void cyg_posix_function_finish();
+
+#define CYG_POSIX_FUNCTION_START() cyg_posix_function_start()
+
+#define CYG_POSIX_FUNCTION_FINISH() cyg_posix_function_finish()
+
+//-----------------------------------------------------------------------------
+// Signal mask management
+//
+// These are exported to allow functions in other packages to
+// manipulate the current threads signal mask. they are currently only
+// used in the implementation of cyg_pselect() in the FILEIO package.
+
+#ifdef CYGPKG_POSIX_SIGNALS
+__externC void cyg_pthread_sigmask_set (const sigset_t *set, sigset_t *oset);
+__externC cyg_bool cyg_posix_sigpending(void);
+__externC void cyg_posix_deliver_signals(const sigset_t *mask);
+
+#define CYG_PTHREAD_SIGMASK_SET cyg_pthread_sigmask_set
+
+#define CYG_POSIX_SIGPENDING() cyg_posix_sigpending()
+
+#define CYG_POSIX_DELIVER_SIGNALS cyg_posix_deliver_signals
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_POSIX_EXPORT_H
+// End of export.h
diff --git a/packages/compat/posix/v2_0/include/limits.h b/packages/compat/posix/v2_0/include/limits.h
new file mode 100644 (file)
index 0000000..2974ba1
--- /dev/null
@@ -0,0 +1,131 @@
+#ifndef CYGONCE_LIMITS_H
+#define CYGONCE_LIMITS_H
+//=============================================================================
+//
+//      limits.h
+//
+//      POSIX limits header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-03-17
+// Purpose:       POSIX limits header
+// Description:   This file contains the compile time definitions that describe
+//                the minima and current values of various values and defined
+//                in POSIX.1 section 2.8.
+//              
+// Usage:
+//              #include <limits.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/posix.h>
+
+//-----------------------------------------------------------------------------
+// Runtime invariants
+// These are all equal to or greater than the minimum values defined above.
+
+// From table 2-4
+
+#define NGROUPS_MAX             _POSIX_NGROUPS_MAX
+
+// From table 2-5
+
+#define AIO_LISTIO_MAX          _POSIX_AIO_LISTIO_MAX
+
+#define AIO_MAX                 _POSIX_AIO_MAX
+
+#define AIO_PRIO_DELTA_MAX      0
+
+#define ARG_MAX                 _POSIX_ARG_MAX
+
+#define CHILD_MAX               _POSIX_CHILD_MAX
+
+#define DELAYTIMER_MAX          _POSIX_DELAYTIMER_MAX
+
+#define LOGIN_NAME_MAX          _POSIX_LOGIN_NAME_MAX
+
+#define PAGESIZE                1
+
+#define PTHREAD_DESTRUCTOR_ITERATIONS CYGNUM_POSIX_PTHREAD_DESTRUCTOR_ITERATIONS
+
+#define PTHREAD_KEYS_MAX        CYGNUM_POSIX_PTHREAD_KEYS_MAX
+
+// Minimum size needed on a pthread stack to contain its per-thread control
+// structures and per-thread data. Since we cannot include all the headers
+// necessary to calculate this value here, the following is a generous estimate.
+#define PTHREAD_STACK_OVERHEAD  (0x180+(PTHREAD_KEYS_MAX*sizeof(void *)))
+
+#define PTHREAD_STACK_MIN       (CYGNUM_HAL_STACK_SIZE_MINIMUM+PTHREAD_STACK_OVERHEAD)
+
+#define PTHREAD_THREADS_MAX     CYGNUM_POSIX_PTHREAD_THREADS_MAX
+
+#define RTSIG_MAX               _POSIX_RTSIG_MAX
+
+#define SEM_NSEMS_MAX           _POSIX_SEM_NSEMS_MAX
+
+#define SEM_VALUE_MAX           _POSIX_SEM_VALUE_MAX
+
+#define SIGQUEUE_MAX            _POSIX_SIGQUEUE_MAX
+
+#define STREAM_MAX              _POSIX_STREAM_MAX
+
+#define TIMER_MAX               _POSIX_TIMER_MAX
+
+#define TTY_NAME_MAX            _POSIX_TTY_NAME_MAX
+
+#define TZNAME_MAX              _POSIX_TZNAME_MAX
+
+
+// From table 2-6.
+
+#define MAX_CANON               _POSIX_MAX_CANON
+
+#define MAX_INPUT               _POSIX_MAX_INPUT
+
+#define PIPE_BUF                _POSIX_PIPE_BUF
+
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_LIMITS_H
+// End of limits.h
diff --git a/packages/compat/posix/v2_0/include/mutex.h b/packages/compat/posix/v2_0/include/mutex.h
new file mode 100644 (file)
index 0000000..687479e
--- /dev/null
@@ -0,0 +1,172 @@
+#ifndef CYGONCE_POSIX_MUTEX_H
+#define CYGONCE_POSIX_MUTEX_H
+//=============================================================================
+//
+//      mutex.h
+//
+//      POSIX mutex and condition variable function definitions
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg,jlarmour
+// Contributors:  
+// Date:          2001-09-10
+// Purpose:       POSIX mutex and condition variable function definitions
+// Description:   This header contains POSIX API definitions for mutexes
+//                and cond vars.
+//              
+// Usage:         #include <pthread.h>
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/posix.h>
+
+#include <sys/types.h>   // pthread_* types
+
+//=============================================================================
+// Mutexes
+
+//-----------------------------------------------------------------------------
+// Mutex attributes manipulation functions
+
+// Initialize attribute object
+externC int pthread_mutexattr_init ( pthread_mutexattr_t *attr);
+
+// Destroy attribute object
+externC int pthread_mutexattr_destroy ( pthread_mutexattr_t *attr);
+
+#if defined(_POSIX_THREAD_PRIO_INHERIT) || defined(_POSIX_THREAD_PRIO_PROTECT)
+
+// Set priority inversion protection protocol
+externC int pthread_mutexattr_setprotocol ( pthread_mutexattr_t *attr,
+                                            int protocol);
+
+// Get priority inversion protection protocol
+externC int pthread_mutexattr_getprotocol ( pthread_mutexattr_t *attr,
+                                            int *protocol);
+
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+
+// Set priority for priority ceiling protocol
+externC int pthread_mutexattr_setprioceiling ( pthread_mutexattr_t *attr,
+                                               int prioceiling);
+
+// Get priority for priority ceiling protocol
+externC int pthread_mutexattr_getprioceiling ( pthread_mutexattr_t *attr,
+                                               int *prioceiling);
+
+// Set priority ceiling of given thread, returning old ceiling.
+externC int pthread_mutex_setprioceiling( pthread_mutex_t *mutex,
+                                          int prioceiling,
+                                          int *old_ceiling);
+
+// Get priority ceiling of given thread
+externC int pthread_mutex_getprioceiling( pthread_mutex_t *mutex,
+                                          int *prioceiling);
+#endif
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Mutex functions
+
+// Initialize mutex. If mutex_attr is NULL, use default attributes.
+externC int pthread_mutex_init (pthread_mutex_t *mutex,
+                                const pthread_mutexattr_t *mutex_attr);
+
+// Destroy mutex.
+externC int pthread_mutex_destroy (pthread_mutex_t *mutex);
+
+// Lock mutex, waiting for it if necessary.
+externC int pthread_mutex_lock (pthread_mutex_t *mutex);
+
+// Try to lock mutex.
+externC int pthread_mutex_trylock (pthread_mutex_t *mutex);
+
+
+// Unlock mutex.
+externC int pthread_mutex_unlock (pthread_mutex_t *mutex);
+
+
+
+//=============================================================================
+// Condition Variables
+
+//-----------------------------------------------------------------------------
+// Attribute manipulation functions
+// We do not actually support any attributes at present, so these do nothing.
+
+// Initialize condition variable attributes
+externC int pthread_condattr_init (pthread_condattr_t *attr);
+
+// Destroy condition variable attributes
+externC int pthread_condattr_destroy (pthread_condattr_t *attr);
+
+//-----------------------------------------------------------------------------
+// Condition variable functions
+
+// Initialize condition variable.
+externC int pthread_cond_init (pthread_cond_t *cond,
+                               const pthread_condattr_t *attr);
+
+// Destroy condition variable.
+externC int pthread_cond_destroy (pthread_cond_t *cond);
+
+// Wake up one thread waiting for condition variable
+externC int pthread_cond_signal (pthread_cond_t *cond);
+
+// Wake up all threads waiting for condition variable
+externC int pthread_cond_broadcast (pthread_cond_t *cond);
+
+// Block on condition variable until signalled. The mutex is
+// assumed to be locked before this call, will be unlocked
+// during the wait, and will be re-locked on wakeup.
+externC int pthread_cond_wait (pthread_cond_t *cond,
+                               pthread_mutex_t *mutex);
+
+// Block on condition variable until signalled, or the timeout expires.
+externC int pthread_cond_timedwait (pthread_cond_t *cond,
+                                    pthread_mutex_t *mutex,
+                                    const struct timespec *abstime);
+
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_POSIX_MUTEX_H
+// End of mutex.h
diff --git a/packages/compat/posix/v2_0/include/muttypes.h b/packages/compat/posix/v2_0/include/muttypes.h
new file mode 100644 (file)
index 0000000..91ddc86
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef CYGONCE_POSIX_MUTTYPES_H
+#define CYGONCE_POSIX_MUTTYPES_H
+//=============================================================================
+//
+//      muttypes.h
+//
+//      POSIX mutex types header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg,jlarmour
+// Date:          2000-03-17
+// Purpose:       POSIX types header
+// Description:   This header contains POSIX type definitions for mutexes
+//                and cond vars. These types are implementation defined.
+//              
+// Usage:         #include <sys/types.h>
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/posix.h>
+#include <pkgconf/kernel.h>
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Mutex object
+// This structure must exactly correspond in size and layout to the underlying
+// eCos C++ class that implements this object. Because we have to support
+// PTHREAD_MUTEX_INITIALIZER we cannot abstract this object very easily.
+
+typedef struct
+{
+    CYG_WORD32  locked;
+    CYG_ADDRESS owner;
+    CYG_ADDRESS queue;
+
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
+    CYG_WORD32  protocol;       // this mutex's protocol
+#endif    
+    
+#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
+    CYG_WORD32  ceiling;        // mutex priority ceiling
+#endif
+    
+} pthread_mutex_t;
+
+#if defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC) &&\
+    defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING)
+#define PTHREAD_MUTEX_INITIALIZER { 0, 0, 0, 0, 0 }
+#elif defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC) ||\
+    defined(CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING)
+#define PTHREAD_MUTEX_INITIALIZER { 0, 0, 0, 0 }
+#else
+#define PTHREAD_MUTEX_INITIALIZER { 0, 0, 0 }
+#endif
+
+//-----------------------------------------------------------------------------
+// Mutex attributes structure
+
+typedef struct
+{
+    int         protocol;
+#ifdef _POSIX_THREAD_PRIO_PROTECT    
+    int         prioceiling;
+#endif    
+} pthread_mutexattr_t;
+
+// Values for protocol
+#define PTHREAD_PRIO_NONE       1
+#if defined(_POSIX_THREAD_PRIO_INHERIT)
+#define PTHREAD_PRIO_INHERIT    2
+#endif
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+#define PTHREAD_PRIO_PROTECT    3
+#endif
+
+//-----------------------------------------------------------------------------
+// Condition Variable structure.
+// Like mutexes, this must match the underlying eCos implementation class.
+
+typedef struct
+{
+    CYG_ADDRESS         mutex;
+    CYG_ADDRESS         queue;    
+} pthread_cond_t;
+
+#define PTHREAD_COND_INITIALIZER { 0, 0 }
+
+//-----------------------------------------------------------------------------
+// Condition variable attributes structure
+
+typedef struct
+{
+    int         dummy;
+} pthread_condattr_t;
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_POSIX_MUTTYPES_H
+// End of muttypes.h
diff --git a/packages/compat/posix/v2_0/include/pthread.h b/packages/compat/posix/v2_0/include/pthread.h
new file mode 100644 (file)
index 0000000..a7a5c15
--- /dev/null
@@ -0,0 +1,320 @@
+#ifndef CYGONCE_PTHREAD_H
+#define CYGONCE_PTHREAD_H
+//=============================================================================
+//
+//      pthread.h
+//
+//      POSIX pthread header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-03-17
+// Purpose:       POSIX pthread header
+// Description:   This header contains all the definitions needed to support
+//                pthreads under eCos. The reader is referred to the POSIX
+//                standard or equivalent documentation for details of the
+//                functionality contained herein.
+//              
+// Usage:
+//              #include <pthread.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>   // CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+#include <stddef.h>             // NULL, size_t
+
+#include <limits.h>
+
+#include <sys/types.h>
+
+#include <sched.h>              // SCHED_*
+
+//=============================================================================
+// General thread operations
+
+//-----------------------------------------------------------------------------
+// Thread creation and management.
+
+// Create a thread.
+__externC int pthread_create (pthread_t *__pthread,
+                              const pthread_attr_t *__attr,
+                              void *(*__start_routine) (void *),
+                              void *__arg);
+
+// Get current thread id.
+__externC pthread_t pthread_self (void);
+
+// Compare two thread identifiers.
+__externC int pthread_equal (pthread_t __thread1, pthread_t __thread2);
+
+// Terminate current thread.
+__externC void pthread_exit (void *__retval) CYGBLD_ATTRIB_NORET;
+
+// Wait for the thread to terminate. If thread_return is not NULL then
+// the retval from the thread's call to pthread_exit() is stored at
+// *thread_return.
+__externC int pthread_join (pthread_t __pthread, void **__thread_return);
+
+// Set the detachstate of the thread to "detached". The thread then does not
+// need to be joined and its resources will be freed when it exits.
+__externC int pthread_detach (pthread_t __pthread);
+
+//-----------------------------------------------------------------------------
+// Thread attribute handling.
+
+// Initialize attributes object with default attributes:
+// detachstate          == PTHREAD_JOINABLE
+// scope                == PTHREAD_SCOPE_SYSTEM
+// inheritsched         == PTHREAD_EXPLICIT_SCHED
+// schedpolicy          == SCHED_OTHER
+// schedparam           == unset
+// stackaddr            == unset
+// stacksize            == 0
+// 
+__externC int pthread_attr_init (pthread_attr_t *__attr);
+
+// Destroy thread attributes object
+__externC int pthread_attr_destroy (pthread_attr_t *__attr);
+
+
+// Set the detachstate attribute
+__externC int pthread_attr_setdetachstate (pthread_attr_t *__attr,
+                                           int __detachstate);
+
+// Get the detachstate attribute
+__externC int pthread_attr_getdetachstate (const pthread_attr_t *__attr,
+                                           int *__detachstate);
+
+
+// Set scheduling contention scope
+__externC int pthread_attr_setscope (pthread_attr_t *__attr, int __scope);
+
+// Get scheduling contention scope
+__externC int pthread_attr_getscope (const pthread_attr_t *__attr, int *__scope);
+
+
+// Set scheduling inheritance attribute
+__externC int pthread_attr_setinheritsched (pthread_attr_t *__attr, int __inherit);
+
+// Get scheduling inheritance attribute
+__externC int pthread_attr_getinheritsched (const pthread_attr_t *__attr,
+                                            int *__inherit);
+
+
+// Set scheduling policy
+__externC int pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy);
+
+// Get scheduling policy
+__externC int pthread_attr_getschedpolicy (const pthread_attr_t *__attr,
+                                           int *__policy);
+
+
+// Set scheduling parameters
+__externC int pthread_attr_setschedparam (pthread_attr_t *__attr,
+                                          const struct sched_param *__param);
+
+// Get scheduling parameters
+__externC int pthread_attr_getschedparam (const pthread_attr_t *__attr,
+                                          struct sched_param *__param);
+
+
+// Set starting address of stack. Whether this is at the start or end of
+// the memory block allocated for the stack depends on whether the stack
+// grows up or down.
+__externC int pthread_attr_setstackaddr (pthread_attr_t *__attr, void *__stackaddr);
+
+// Get any previously set stack address.
+__externC int pthread_attr_getstackaddr (const pthread_attr_t *__attr,
+                                         void **__stackaddr);
+
+
+// Set minimum creation stack size.
+__externC int pthread_attr_setstacksize (pthread_attr_t *__attr,
+                                         size_t __stacksize);
+
+// Get current minimal stack size.
+__externC int pthread_attr_getstacksize (const pthread_attr_t *__attr,
+                                         size_t *__stacksize);
+
+//-----------------------------------------------------------------------------
+// Thread scheduling controls
+
+// Set scheduling policy and parameters for the thread
+__externC int pthread_setschedparam (pthread_t __pthread,
+                                     int __policy,
+                                     const struct sched_param *__param);
+
+// Get scheduling policy and parameters for the thread
+__externC int pthread_getschedparam (pthread_t __pthread,
+                                     int *__policy,
+                                     struct sched_param *__param);
+
+
+
+//=============================================================================
+// Dynamic package initialization
+
+// Initializer for pthread_once_t instances
+#define PTHREAD_ONCE_INIT       0
+
+// Call init_routine just the once per control variable.
+__externC int pthread_once (pthread_once_t *__once_control,
+                            void (*__init_routine) (void));
+
+
+
+//=============================================================================
+//Thread specific data
+
+// Create a key to identify a location in the thread specific data area.
+// Each thread has its own distinct thread-specific data area but all are
+// addressed by the same keys. The destructor function is called whenever a
+// thread exits and the value associated with the key is non-NULL.
+__externC int pthread_key_create (pthread_key_t *__key,
+                                  void (*__destructor) (void *));
+
+// Delete key.
+__externC int pthread_key_delete (pthread_key_t __key);
+
+// Store the pointer value in the thread-specific data slot addressed
+// by the key.
+__externC int pthread_setspecific (pthread_key_t __key, const void *__pointer);
+
+// Retrieve the pointer value in the thread-specific data slot addressed
+// by the key.
+__externC void *pthread_getspecific (pthread_key_t __key);
+
+
+
+//=============================================================================
+// Thread Cancellation
+
+//-----------------------------------------------------------------------------
+// Data structure used to manage cleanup functions
+
+struct pthread_cleanup_buffer
+{
+    struct pthread_cleanup_buffer *prev;        // Chain cleanup buffers
+    void (*routine) (void *);                  // Function to call
+    void *arg;                                 // Arg to pass
+};
+
+//-----------------------------------------------------------------------------
+// Thread cancelled return value.
+// This is a value returned as the retval in pthread_join() of a
+// thread that has been cancelled. By making it the address of a
+// location we define we can ensure that it differs from NULL and any
+// other valid pointer (as required by the standard).
+
+__externC int pthread_canceled_dummy_var;
+
+#define PTHREAD_CANCELED                ((void *)(&pthread_canceled_dummy_var))
+
+//-----------------------------------------------------------------------------
+// Cancelability enable and type
+
+#define PTHREAD_CANCEL_ENABLE           1
+#define PTHREAD_CANCEL_DISABLE          2
+
+#define PTHREAD_CANCEL_ASYNCHRONOUS     1
+#define PTHREAD_CANCEL_DEFERRED         2
+
+//-----------------------------------------------------------------------------
+// Functions
+
+// Set cancel state of current thread to ENABLE or DISABLE.
+// Returns old state in *oldstate.
+__externC int pthread_setcancelstate (int __state, int *__oldstate);
+
+// Set cancel type of current thread to ASYNCHRONOUS or DEFERRED.
+// Returns old type in *oldtype.
+__externC int pthread_setcanceltype (int __type, int *__oldtype);
+
+// Cancel the thread.
+__externC int pthread_cancel (pthread_t __pthread);
+
+// Test for a pending cancellation for the current thread and terminate
+// the thread if there is one.
+__externC void pthread_testcancel (void);
+
+// Install a cleanup routine.
+// Note that pthread_cleanup_push() and pthread_cleanup_pop() are macros that
+// must be used in matching pairs and at the same brace nesting level.
+#define pthread_cleanup_push(__routine, __arg)                          \
+    {                                                                   \
+        struct pthread_cleanup_buffer _buffer_;                         \
+        pthread_cleanup_push_inner (&_buffer_, (__routine), (__arg));
+
+// Remove a cleanup handler installed by the matching pthread_cleanup_push().
+// If execute is non-zero, the handler function is called.
+#define pthread_cleanup_pop(__execute)                          \
+        pthread_cleanup_pop_inner (&_buffer_, (__execute));     \
+    }
+
+
+// These two functions actually implement the cleanup push and pop functionality.
+__externC void pthread_cleanup_push_inner (struct pthread_cleanup_buffer *__buffer,
+                                           void (*__routine) (void *),
+                                           void *__arg);
+
+__externC void pthread_cleanup_pop_inner (struct pthread_cleanup_buffer *__buffer,
+                                          int __execute);
+
+
+// -------------------------------------------------------------------------
+// eCos-specific function to measure stack usage of the supplied thread
+
+#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
+__externC size_t pthread_measure_stack_usage (pthread_t __pthread);
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_PTHREAD_H
+// End of pthread.h
diff --git a/packages/compat/posix/v2_0/include/semaphore.h b/packages/compat/posix/v2_0/include/semaphore.h
new file mode 100644 (file)
index 0000000..2f88a6d
--- /dev/null
@@ -0,0 +1,127 @@
+#ifndef CYGONCE_SEMAPHORE_H
+#define CYGONCE_SEMAPHORE_H
+//=============================================================================
+//
+//      semaphore.h
+//
+//      POSIX semaphore header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-03-17
+// Purpose:       POSIX semaphore header
+// Description:   This header contains all the definitions needed to support
+//                semaphores under eCos. The reader is referred to the POSIX
+//                standard or equivalent documentation for details of the
+//                functionality contained herein.
+//              
+// Usage:
+//              #include <semaphore.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+
+#include <stddef.h>             // NULL, size_t
+
+#include <limits.h>
+
+#include <sys/types.h>
+
+//-----------------------------------------------------------------------------
+// Semaphore object definition
+
+// This structure must exactly correspond in size and layout to the underlying
+// eCos C++ class that implements this object.
+
+typedef struct
+{
+  CYG_WORD32    sem_value;
+  CYG_ADDRESS   sem_queue;
+} sem_t;
+
+//-----------------------------------------------------------------------------
+// Semaphore functions
+
+// Initialize semaphore to value.
+// pshared is not supported under eCos.
+externC int sem_init  (sem_t *sem, int pshared, unsigned int value);
+
+// Destroy the semaphore.
+externC int sem_destroy  (sem_t *sem);
+
+// Decrement value if >0 or wait for a post.
+externC int sem_wait  (sem_t *sem);
+
+// Decrement value if >0, return -1 if not.
+externC int sem_trywait  (sem_t *sem);
+
+// Increment value and wake a waiter if one is present.
+externC int sem_post  (sem_t *sem);
+
+// Get current value
+externC int sem_getvalue  (sem_t *sem, int *sval);
+
+//-----------------------------------------------------------------------------
+// Named semaphore functions
+// These are an optional feature under eCos
+
+// Open an existing named semaphore, or create it.
+externC sem_t *sem_open  (const char *name, int oflag, ...);
+
+// Close descriptor for semaphore.
+externC int sem_close  (sem_t *sem);
+
+// Remove named semaphore
+externC int sem_unlink  (const char *name);
+
+//-----------------------------------------------------------------------------
+// Special return value for sem_open()
+
+#define SEM_FAILED      ((sem_t *)NULL)
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_SEMAPHORE_H
+// End of semaphore.h
diff --git a/packages/compat/posix/v2_0/include/signal.h b/packages/compat/posix/v2_0/include/signal.h
new file mode 100644 (file)
index 0000000..2ccde69
--- /dev/null
@@ -0,0 +1,313 @@
+#ifndef CYGONCE_SIGNAL_H
+#define CYGONCE_SIGNAL_H
+//=============================================================================
+//
+//      signal.h
+//
+//      POSIX signal header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg, jlarmour
+// Contributors:  
+// Date:          2000-03-17
+// Purpose:       POSIX signal header
+// Description:   This header contains all the definitions needed to support
+//                the POSIX signal API under eCos.
+//              
+// Usage:         This file can either be included directly, or indirectly via
+//                the C library signal.h header.
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+
+#ifdef CYGPKG_POSIX_SIGNALS
+
+#include <stddef.h>             // NULL, size_t
+
+#include <limits.h>
+#include <sys/types.h>
+
+//-----------------------------------------------------------------------------
+// POSIX feature test macros
+
+// We do not support job control
+#undef _POSIX_JOB_CONTROL
+
+//-----------------------------------------------------------------------------
+// Manifest constants
+
+#ifdef _POSIX_REALTIME_SIGNALS
+// For now we define the topmost 8 signals as realtime
+#define SIGRTMIN                24
+#define SIGRTMAX                31
+#endif
+
+//-----------------------------------------------------------------------------
+// forward references
+
+struct timespec;
+
+//-----------------------------------------------------------------------------
+// Sigval structure
+
+union sigval
+{
+    int   sival_int;    // used when application-defined value is an int
+    void  *sival_ptr;   // used when application-defined value is a pointer
+};
+
+//-----------------------------------------------------------------------------
+// Siginfo structure passed to an SA_SIGINFO style handler
+
+typedef struct
+{
+    int          si_signo;      // signal number
+    int          si_code;       // cause of signal
+    union sigval si_value;      // signal value
+} siginfo_t;
+
+// Values for si_code
+# define SI_USER       1
+# define SI_QUEUE      2
+# define SI_TIMER      3
+# define SI_ASYNCIO    4
+# define SI_MESGQ      5
+# define SI_EXCEPT      6       // signal is result of an exception delivery
+
+//-----------------------------------------------------------------------------
+// Basic types
+
+// Integral type that can be accessed atomically - from ISO C 7.7
+typedef cyg_atomic sig_atomic_t;
+
+// Type of signal handler functions
+typedef void (*sa_sighandler_t)(int);
+
+// Type of signal handler used if SA_SIGINFO is set in sa_flags
+typedef void (*sa_siginfoaction_t)(int signo, siginfo_t *info,
+                                  void *context);
+
+//-----------------------------------------------------------------------------
+//Signal handlers for use with signal() and sigaction(). We avoid 0
+//because in an embedded system this may be start of ROM and thus
+//a possible function pointer for reset.
+
+#define SIG_DFL ((sa_sighandler_t) 1)      // Default action
+#define SIG_IGN ((sa_sighandler_t) 2)      // Ignore action
+#define SIG_ERR ((sa_sighandler_t)-1)      // Error return
+
+//-----------------------------------------------------------------------------
+// Signal values
+
+#define SIGNULL   0    // Reserved signal - do not use (POSIX 3.3.1.1)
+#define SIGHUP    1    // Hangup on controlling terminal (POSIX)
+#define SIGINT    2    // Interactive attention (ISO C)
+#define SIGQUIT   3    // Interactive termination (POSIX)
+#define SIGILL    4    // Illegal instruction (not reset when caught) (ISO C)
+#define SIGTRAP   5    // Trace trap (not reset when caught)
+#define SIGIOT    6    // IOT instruction
+#define SIGABRT   6    // Abnormal termination - used by abort() (ISO C)
+#define SIGEMT    7    // EMT instruction
+#define SIGFPE    8    // Floating Point Exception e.g. div by 0 (ISO C)
+#define SIGKILL   9    // Kill (cannot be caught or ignored) (POSIX)
+#define SIGBUS    10   // Bus error (POSIX)
+#define SIGSEGV   11   // Invalid memory reference (ISO C)
+#define SIGSYS    12   // Bad argument to system call (used by anything?)
+#define SIGPIPE   13   // Write on a pipe with no one to read it (POSIX)
+#define SIGALRM   14   // Alarm timeout (POSIX)
+#define SIGTERM   15   // Software termination request (ISO C)
+#define SIGUSR1   16   // Application-defined signal 1 (POSIX)
+#define SIGUSR2   17   // Application-defined signal 2 (POSIX)
+
+
+//-----------------------------------------------------------------------------
+// Signal sets.
+// At present we define a single 32 bit integer mask. We may need, at
+// some future point, to extend this to 64 bits, or a structure
+// containing an array of masks.
+
+typedef cyg_uint32 sigset_t;
+
+//-----------------------------------------------------------------------------
+// struct sigaction describes the action to be taken when we get a signal
+
+struct sigaction
+{
+    sigset_t               sa_mask;             // Additional signals to be blocked
+    int                    sa_flags;            // Special flags
+    union
+    {
+        sa_sighandler_t    sa_handler;          // signal handler
+        sa_siginfoaction_t sa_sigaction;        // Function to call instead of
+                                                // sa_handler if SA_SIGINFO is
+                                                // set in sa_flags
+    } sa_sigactionhandler;
+#define sa_handler   sa_sigactionhandler.sa_handler
+#define sa_sigaction sa_sigactionhandler.sa_sigaction
+};
+
+// sa_flag bits
+#define SA_NOCLDSTOP 1   // Don't generate SIGCHLD when children stop
+#define SA_SIGINFO   2   // Use the sa_siginfoaction_t style signal
+                         // handler, instead of the single argument handler
+
+//-----------------------------------------------------------------------------
+// Sigevent structure.
+
+struct sigevent
+{
+    int                  sigev_notify;
+    int                  sigev_signo;
+    union sigval         sigev_value;
+    void               (*sigev_notify_function) (union sigval);
+    pthread_attr_t      *sigev_notify_attributes;
+};
+
+# define SIGEV_NONE    1
+# define SIGEV_SIGNAL   2
+# define SIGEV_THREAD  3
+
+//-----------------------------------------------------------------------------
+// Functions to generate signals
+
+// Deliver sig to a process.
+// eCos only supports the value 0 for pid.
+externC int kill (pid_t pid, int sig);
+
+externC int pthread_kill (pthread_t thread, int sig);
+
+//-----------------------------------------------------------------------------
+// Functions to catch signals
+
+// Install signal handler for sig.
+externC int sigaction  (int sig, const struct sigaction *act,
+                        struct sigaction *oact);
+
+// Queue signal to process with value.
+externC int sigqueue  (pid_t pid, int sig, const union sigval value);
+
+//-----------------------------------------------------------------------------
+// Functions to deal with current blocked and pending masks
+
+// Set process blocked signal mask
+externC int sigprocmask  (int how, const sigset_t *set, sigset_t *oset);
+
+// Set calling thread's blocked signal mask
+externC int pthread_sigmask (int how, const sigset_t *set, sigset_t *oset);
+
+// Get set of pending signals for this process
+externC int sigpending  (sigset_t *set);
+
+// Values for the how arguments:
+#define SIG_BLOCK       1
+#define SIG_UNBLOCK     2
+#define SIG_SETMASK     3
+
+//-----------------------------------------------------------------------------
+// Wait for or accept signals
+
+// Block signals in set and wait for a signal
+externC int sigsuspend  (const sigset_t *set);
+
+// Wait for a signal in set to arrive
+externC int sigwait  (const sigset_t *set, int *sig);
+
+// Do the same as sigwait() except return a siginfo_t object too.
+externC int sigwaitinfo  (const sigset_t *set, siginfo_t *info);
+
+// Do the same as sigwaitinfo() but return anyway after timeout.
+externC int sigtimedwait  (const sigset_t *set, siginfo_t *info,
+                           const struct timespec *timeout);
+
+//-----------------------------------------------------------------------------
+// Signal sets
+
+// Clear all signals from set.
+externC int sigemptyset  (sigset_t *set);
+
+// Set all signals in set.
+externC int sigfillset  (sigset_t *set);
+
+// Add signo to set.
+externC int sigaddset  (sigset_t *set, int signo);
+
+// Remove signo from set.
+externC int sigdelset  (sigset_t *set, int signo);
+
+// Test whether signo is in set
+externC int sigismember  (const sigset_t *set, int signo);
+
+//-----------------------------------------------------------------------------
+// alarm, pause and sleep
+
+// Generate SIGALRM after some number of seconds
+externC unsigned int alarm( unsigned int seconds );
+
+// Wait for a signal to be delivered.
+externC int pause( void );
+
+// Wait for a signal, or the given number of seconds
+externC unsigned int sleep( unsigned int seconds );
+
+//-----------------------------------------------------------------------------
+// signal() - ISO C 7.7.1   //
+//
+// Installs a new signal handler for the specified signal, and returns
+// the old handler
+//
+
+externC sa_sighandler_t signal(int __sig, sa_sighandler_t __handler);
+
+// raise() - ISO C 7.7.2 //
+//
+// Raises the signal, which will cause the current signal handler for
+// that signal to be called
+
+externC int raise(int __sig);
+
+#endif // ifdef CYGPKG_POSIX_SIGNALS
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_SIGNAL_H
+// End of signal.h
diff --git a/packages/compat/posix/v2_0/include/sigsetjmp.h b/packages/compat/posix/v2_0/include/sigsetjmp.h
new file mode 100644 (file)
index 0000000..ff4a332
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef CYGONCE_SIGSETJMP_H
+#define CYGONCE_SIGSETJMP_H
+//=============================================================================
+//
+//      sigsetjmp.h
+//
+//      POSIX sigsetjmp header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg, jlarmour
+// Contributors:  
+// Date:          2000-03-17
+// Purpose:       POSIX sigsetjmp header
+// Description:   This header contains all the definitions needed to support
+//                the POSIX sigsetjmp/siglongjmp API under eCos.
+//              
+// Usage:         This file must be included indirectly via
+//                the C library setjmp.h header.
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <signal.h>
+#include <cyg/hal/hal_arch.h>       // hal_jmp_buf
+
+//=============================================================================
+// sigjmp_buf structure
+// The API requires this to be an array type, but this array actually
+// contains three fields:
+// 0..sizeof(hal_jmp_buf)-1               HAL jump buffer
+// sizeof(hal_jmp_buf)                    savemask value (an int)
+// sizeof(hal_jmp_buf)+sizeof(int)...     sigset_t containing saved mask
+
+typedef struct {
+    hal_jmp_buf __jmp_buf;
+    int  __savemask;
+    sigset_t __sigsavemask;
+} sigjmp_buf[1];
+
+//=============================================================================
+// sigsetjmp() macro
+
+#define sigsetjmp( _env_, _savemask_ )                                        \
+(                                                                             \
+ ((_env_)[0].__savemask = _savemask_),                                        \
+ ((_savemask_)?pthread_sigmask(SIG_BLOCK,NULL,&((_env_)[0].__sigsavemask)):0),\
+ hal_setjmp((_env_)[0].__jmp_buf)                                             \
+)
+
+//=============================================================================
+// siglongjmp function
+
+__externC void siglongjmp( sigjmp_buf env, int val );
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_SIGSETJMP_H
+// End of sigsetjmp.h
diff --git a/packages/compat/posix/v2_0/include/time.h b/packages/compat/posix/v2_0/include/time.h
new file mode 100644 (file)
index 0000000..67cdbdb
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef CYGONCE_POSIX_TIME_H
+#define CYGONCE_POSIX_TIME_H
+/*=============================================================================
+//
+//      time.h
+//
+//      POSIX time header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg, jlarmour
+// Date:          2000-03-17
+// Purpose:       POSIX time header
+// Description:   This header contains all the definitions needed to support
+//                the POSIX timer and timer API under eCos.
+//              
+// Usage:         Do not include this file directly - instead include <time.h>
+//              
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+#include <pkgconf/posix.h>
+#include <cyg/infra/cyg_type.h>
+
+/*---------------------------------------------------------------------------*/
+/* Types for timers and clocks */
+
+typedef int clockid_t;
+
+#ifdef CYGPKG_POSIX_TIMERS
+typedef int timer_t;
+
+/* forward declaration - if the app uses it it will have to include
+ * signal.h anyway
+ */
+struct sigevent;
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Structures */
+
+struct timespec
+{
+    time_t      tv_sec;
+    long        tv_nsec;
+};
+
+#ifdef CYGPKG_POSIX_TIMERS
+struct itimerspec
+{
+    struct timespec     it_interval;
+    struct timespec     it_value;
+};
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Manifest constants */
+
+#define CLOCK_REALTIME          0
+
+#ifdef CYGPKG_POSIX_TIMERS
+#define TIMER_ABSTIME           1
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Clock functions */
+
+/* Set the clocks current time */
+__externC int clock_settime( clockid_t clock_id, const struct timespec *tp);
+
+/* Get the clocks current time */
+__externC int clock_gettime( clockid_t clock_id, struct timespec *tp);
+
+/* Get the clocks resolution */
+__externC int clock_getres( clockid_t clock_id, struct timespec *tp);
+
+
+/*---------------------------------------------------------------------------*/
+/* Timer functions */
+
+#ifdef CYGPKG_POSIX_TIMERS
+
+/* Create a timer based on the given clock. */
+__externC int timer_create( clockid_t clock_id,
+                            struct sigevent *evp,
+                            timer_t *timer_id);
+
+/* Delete the timer */
+__externC int timer_delete( timer_t timer_id );
+
+/* Set the expiration time of the timer. */
+__externC int timer_settime( timer_t timerid, int flags,
+                             const struct itimerspec *value,
+                             struct itimerspec *ovalue );
+
+/* Get current timer values */
+__externC int timer_gettime( timer_t timerid, struct itimerspec *value );
+
+/* Get number of missed triggers */
+__externC int timer_getoverrun( timer_t timerid );
+
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* Nanosleep */
+
+/* Sleep for the given time. */
+__externC int nanosleep( const struct timespec *rqtp,
+                         struct timespec *rmtp);
+
+
+/*---------------------------------------------------------------------------*/
+#endif /* ifndef CYGONCE_POSIX_TIME_H */
+/* End of time.h */
diff --git a/packages/compat/posix/v2_0/include/types.h b/packages/compat/posix/v2_0/include/types.h
new file mode 100644 (file)
index 0000000..dc74e0f
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef CYGONCE_POSIX_TYPES_H
+#define CYGONCE_POSIX_TYPES_H
+//=============================================================================
+//
+//      types.h
+//
+//      POSIX types header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-03-17
+// Purpose:       POSIX types header
+// Description:   This header contains various POSIX type definitions. These types
+//                are implementation defined.
+//              
+// Usage:         #include <sys/types.h>
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+
+#include <cyg/infra/cyg_type.h>
+
+//-----------------------------------------------------------------------------
+// Basic types.
+
+typedef cyg_uint32 pthread_t;
+typedef int pthread_key_t;
+typedef int pthread_once_t;
+
+//-----------------------------------------------------------------------------
+// Scheduling parameters. At present only the priority is defined.
+// Strictly this should be in <sched.h>, but the requirement for pthread_attr_t
+// to contain a sched_param object means that it must be here.
+
+struct sched_param
+{
+    int                 sched_priority;
+};
+
+//-----------------------------------------------------------------------------
+// Thread attribute structure.
+
+typedef struct pthread_attr_t
+{
+    unsigned int        detachstate:2,
+                        scope:2,
+                        inheritsched:2,
+                        schedpolicy:2,
+                        stackaddr_valid:1,
+                        stacksize_valid:1;
+    struct sched_param  schedparam;
+    void                *stackaddr;
+    size_t              stacksize;
+} pthread_attr_t;
+
+// Values for detachstate
+#define PTHREAD_CREATE_JOINABLE                1
+#define PTHREAD_CREATE_DETACHED                2
+
+// Values for scope
+#define PTHREAD_SCOPE_SYSTEM            1
+#define PTHREAD_SCOPE_PROCESS           2
+
+// Values for inheritsched
+#define PTHREAD_INHERIT_SCHED           1
+#define PTHREAD_EXPLICIT_SCHED          2
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_POSIX_TYPES_H
+// End of types.h
diff --git a/packages/compat/posix/v2_0/include/utsname.h b/packages/compat/posix/v2_0/include/utsname.h
new file mode 100644 (file)
index 0000000..3f0b79c
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef CYGONCE_UTSNAME_H
+#define CYGONCE_UTSNAME_H
+//=============================================================================
+//
+//      utsname.h
+//
+//      POSIX utsname header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-03-17
+// Purpose:       POSIX utsname header
+// Description:   This header contains all the definitions needed to support
+//                utsnames under eCos. The reader is referred to the POSIX
+//                standard or equivalent documentation for details of the
+//                functionality contained herein.
+//              
+// Usage:
+//              #include <utsname.h>
+//              ...
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>   // CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+#include <stddef.h>             // NULL, size_t
+
+#include <limits.h>
+
+#include <sys/types.h>
+
+#include <sched.h>              // SCHED_*
+
+//=============================================================================
+// UTSName structure
+
+struct utsname
+{
+    char        sysname[CYG_POSIX_UTSNAME_LENGTH];
+    char        nodename[CYG_POSIX_UTSNAME_NODENAME_LENGTH];
+    char        release[CYG_POSIX_UTSNAME_LENGTH];
+    char        version[CYG_POSIX_UTSNAME_LENGTH];
+    char        machine[CYG_POSIX_UTSNAME_LENGTH];
+};
+
+//=============================================================================
+// uname() function
+
+__externC int uname( struct utsname *name );
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_UTSNAME_H
+// End of utsname.h
diff --git a/packages/compat/posix/v2_0/src/except.cxx b/packages/compat/posix/v2_0/src/except.cxx
new file mode 100644 (file)
index 0000000..a82913b
--- /dev/null
@@ -0,0 +1,343 @@
+//==========================================================================
+//
+//      except.cxx
+//
+//      POSIX exception translation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg
+// Date:                2000-03-27
+// Purpose:             POSIX exception translation
+// Description:         This file contains code to translate eCos hardware
+//                      exceptions into POSIX signals.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.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/infra/diag.h>
+
+#include "pprivate.h"                   // POSIX private header
+
+#include <signal.h>                     // our header
+
+#include <cyg/kernel/thread.inl>
+
+//==========================================================================
+// Translation table from eCos exceptions to POSIX signals.
+
+static const struct
+{
+    cyg_code    exception;
+    int         signal;
+} exception_signal_mapping[] =
+{
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
+    {CYGNUM_HAL_EXCEPTION_DATA_ACCESS, SIGBUS},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_WRITE
+    {CYGNUM_HAL_EXCEPTION_DATA_WRITE, SIGBUS},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_CODE_ACCESS
+    {CYGNUM_HAL_EXCEPTION_CODE_ACCESS, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_CODE_WRITE
+    {CYGNUM_HAL_EXCEPTION_CODE_WRITE, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_CODE_EXECUTE
+    {CYGNUM_HAL_EXCEPTION_CODE_EXECUTE, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_IO_ACCESS
+    {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_IO_WRITE
+    {CYGNUM_HAL_EXCEPTION_IO_ACCESS, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
+    {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE
+    {CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_WRITE, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS
+    {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_ACCESS, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE
+    {CYGNUM_HAL_EXCEPTION_CODE_TLBMISS_WRITE, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS
+    {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_ACCESS, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE
+    {CYGNUM_HAL_EXCEPTION_DATA_TLBERROR_WRITE, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS
+    {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_ACCESS, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE
+    {CYGNUM_HAL_EXCEPTION_CODE_TLBERROR_WRITE, SIGSEGV},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
+    {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE
+    {CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS
+    {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_ACCESS, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE
+    {CYGNUM_HAL_EXCEPTION_IO_UNALIGNED_WRITE, SIGBUS},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
+    {CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, SIGILL},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_INTERRUPT
+    {CYGNUM_HAL_EXCEPTION_INTERRUPT, SIGINT},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_TRAP
+    {CYGNUM_HAL_EXCEPTION_TRAP, SIGTRAP},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO
+    {CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO, SIGFPE},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_OVERFLOW
+    {CYGNUM_HAL_EXCEPTION_OVERFLOW, SIGFPE},
+#endif    
+#ifdef CYGNUM_HAL_EXCEPTION_BOUNDS
+    {CYGNUM_HAL_EXCEPTION_BOUNDS, SIGSEGV},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_SINGLE_STEP
+    {CYGNUM_HAL_EXCEPTION_SINGLE_STEP, SIGTRAP},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP
+    {CYGNUM_HAL_EXCEPTION_INSTRUCTION_BP, SIGTRAP},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP
+    {CYGNUM_HAL_EXCEPTION_PERIPHERAL_BP, SIGTRAP},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_BP
+    {CYGNUM_HAL_EXCEPTION_DATA_BP, SIGTRAP},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP
+    {CYGNUM_HAL_EXCEPTION_DEVELOPMENT_BP, SIGTRAP},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW
+    {CYGNUM_HAL_EXCEPTION_STACK_OVERFLOW, SIGSEGV},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_STACK_FAULT
+    {CYGNUM_HAL_EXCEPTION_STACK_FAULT, SIGSEGV},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_PARITY
+    {CYGNUM_HAL_EXCEPTION_PARITY, SIGBUS},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU
+    {CYGNUM_HAL_EXCEPTION_FPU, SIGFPE},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL
+    {CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL, SIGFPE},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW
+    {CYGNUM_HAL_EXCEPTION_FPU_OVERFLOW, SIGFPE},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW
+    {CYGNUM_HAL_EXCEPTION_FPU_UNDERFLOW, SIGFPE},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
+    {CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, SIGFPE},
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_SYSTEM_CALL
+    {CYGNUM_HAL_EXCEPTION_SYSTEM_CALL, SIGSYS},
+#endif
+    {0, 0} // dummy value to ensure compiler is happy
+};
+
+//==========================================================================
+// POSIX exception handler
+
+static void cyg_posix_exception_handler(
+    CYG_ADDRWORD        data,                   // user supplied data == signal number
+    cyg_code            exception_number,       // exception being raised
+    CYG_ADDRWORD        exception_info          // any exception specific info
+    )
+{
+    int signo = 0;
+
+    pthread_info *self = pthread_self_info();
+
+    if( self == NULL )
+    {
+        // Not a POSIX thread, just return
+        return;
+    }
+    
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+
+    signo = data;
+
+#else
+
+    for( int i = 0; exception_signal_mapping[i].signal != 0; i++ )    
+    {
+        if( exception_signal_mapping[i].exception == exception_number )
+        {
+            signo = exception_signal_mapping[i].signal;
+            break;
+        }
+    }
+
+#endif
+
+    if( sigismember( &self->sigmask, signo ) )
+    {
+        // The signal is masked in the current thread. POSIX says that
+        // the behaviour is undefined here. We choose to ignore it.
+
+        return;
+    }
+
+    // The kernel exception handler may have disabled interrupts, so
+    // we (re-)enable them here. From this point on we are running in
+    // a context that is effectively just pushed onto the stack of the
+    // current thread. If we return we will unwind and resume
+    // execution from the excepting code. We can also, in theory,
+    // longjump out of the signal handler, and although that is
+    // deprecated, we make sure in cyg_deliver_signals() that it is
+    // possible to do it.
+    
+    HAL_ENABLE_INTERRUPTS();
+    
+    struct sigevent sev;
+
+    sev.sigev_notify           = SIGEV_SIGNAL;
+    sev.sigev_signo            = signo;
+    sev.sigev_value.sival_ptr  = (void *)exception_info;
+
+    // Generate the signal
+    cyg_sigqueue( &sev, SI_EXCEPT );
+
+    // And try to deliver it
+    cyg_deliver_signals();
+}
+
+//==========================================================================
+// Install all the exception handlers
+
+static void install_handlers( Cyg_Thread *thread)
+{
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE
+
+    // With decoded exceptions, we must install a separate exception
+    // handler for each supported exception.
+
+    for( int i = 0; exception_signal_mapping[i].signal != 0; i++ )
+    {
+        thread->register_exception( exception_signal_mapping[i].exception,
+                                    cyg_posix_exception_handler,
+                                    exception_signal_mapping[i].signal,,
+                                    NULL,
+                                    NULL);
+    }
+    
+#else
+
+    // Otherwise there is just one exception handler for all exceptions.
+    
+    thread->register_exception( CYGNUM_HAL_EXCEPTION_MIN,
+                                cyg_posix_exception_handler,
+                                0,
+                                NULL,
+                                NULL);
+    
+#endif    
+    
+}
+
+//==========================================================================
+// Initialization
+
+externC void cyg_posix_exception_start()
+{
+#ifdef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
+
+    // With global exceptions, we only need to install a single static
+    // set of exception handlers. Note that by this point in system
+    // initialization the idle thread should be installed as the
+    // current thread, so we pass a pointer to that to
+    // install_handlers(). The identity of the thread passed is
+    // actually irrelevant in this case and is just used as a handle
+    // into the thread class.
+
+    install_handlers( Cyg_Thread::self() );
+    
+#endif    
+}
+
+//==========================================================================
+// Per thread exception initialization and destruction
+
+externC void cyg_pthread_exception_init(pthread_info *thread)
+{
+#ifndef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
+
+    // With non-global exceptions we must install a new set of handlers
+    // for each thread.
+
+    install_handlers( thread->thread );
+    
+#endif
+}
+
+externC void cyg_pthread_exception_destroy(pthread_info *thread)
+{
+    // Nothing to do at present.
+}
+
+// -------------------------------------------------------------------------
+// EOF except.cxx
diff --git a/packages/compat/posix/v2_0/src/misc.cxx b/packages/compat/posix/v2_0/src/misc.cxx
new file mode 100644 (file)
index 0000000..d56ef91
--- /dev/null
@@ -0,0 +1,386 @@
+//==========================================================================
+//
+//      misc.cxx
+//
+//      POSIX misc function implementations
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg
+// Date:                2000-07-18
+// Purpose:             POSIX misc function implementation
+// Description:         This file contains the implementation of miscellaneous POSIX
+//                      functions that do not belong elsewhere.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.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 "pprivate.h"                   // POSIX private header
+
+#include <unistd.h>
+#include <sys/utsname.h>                // My header
+#include <string.h>                     // strcpy
+#include <limits.h>
+#include <time.h>
+
+#include <cyg/kernel/sched.hxx>
+
+#include <cyg/kernel/sched.inl>
+
+// -------------------------------------------------------------------------
+// Supply some suitable values for constants that may not be present
+// in all configurations.
+
+#ifndef MQ_OPEN_MAX
+#define MQ_OPEN_MAX 0
+#endif
+#ifndef MQ_PRIO_MAX
+#define MQ_PRIO_MAX 0
+#endif
+
+// -------------------------------------------------------------------------
+
+#define __string(_x) #_x
+#define __xstring(_x) __string(_x)
+
+// -------------------------------------------------------------------------
+// uname()
+
+__externC int uname( struct utsname *name )
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    strcpy( name->sysname, "eCos" );
+    strcpy( name->nodename, "" );       // should use gethostname()
+    strcpy( name->release, __xstring( CYGNUM_KERNEL_VERSION_MAJOR ) );
+    strcpy( name->version, __xstring( CYGNUM_KERNEL_VERSION_MINOR ) );
+    strcpy( name->machine, "" );
+
+    CYG_REPORT_RETVAL(0);
+    return 0;
+}
+
+// -------------------------------------------------------------------------
+// sysconf()
+
+#define SC_CASE( _name, _val ) case _name: return _val
+
+__externC long sysconf( int name )
+{
+
+    switch( name )
+    {
+        SC_CASE( _SC_AIO_LISTIO_MAX,                    AIO_LISTIO_MAX );
+        SC_CASE( _SC_AIO_MAX,                           AIO_MAX );
+        SC_CASE( _SC_AIO_PRIO_DELTA_MAX,                AIO_PRIO_DELTA_MAX );
+        SC_CASE( _SC_ARG_MAX,                           ARG_MAX );
+        SC_CASE( _SC_CHILD_MAX,                         CHILD_MAX );
+        SC_CASE( _SC_DELAYTIMER_MAX,                    DELAYTIMER_MAX );
+        SC_CASE( _SC_GETGR_R_SIZE_MAX,                  0 );
+        SC_CASE( _SC_GETPW_R_SIZE_MAX,                  0 );
+        SC_CASE( _SC_LOGIN_NAME_MAX,                    LOGIN_NAME_MAX );
+        SC_CASE( _SC_MQ_OPEN_MAX,                       MQ_OPEN_MAX );
+        SC_CASE( _SC_MQ_PRIO_MAX,                       MQ_PRIO_MAX );
+        SC_CASE( _SC_NGROUPS_MAX,                       NGROUPS_MAX );
+        SC_CASE( _SC_OPEN_MAX,                          OPEN_MAX );
+        SC_CASE( _SC_PAGESIZE,                          PAGESIZE );
+        SC_CASE( _SC_RTSIG_MAX,                         RTSIG_MAX );
+        SC_CASE( _SC_SEM_NSEMS_MAX,                     SEM_NSEMS_MAX );
+        SC_CASE( _SC_SEM_VALUE_MAX,                     SEM_VALUE_MAX );
+        SC_CASE( _SC_SIGQUEUE_MAX,                      SIGQUEUE_MAX );
+        SC_CASE( _SC_STREAM_MAX,                        STREAM_MAX );
+#ifdef CYGPKG_POSIX_PTHREAD
+        SC_CASE( _SC_THREAD_DESTRUCTOR_ITERATIONS,      PTHREAD_DESTRUCTOR_ITERATIONS );
+        SC_CASE( _SC_THREAD_KEYS_MAX,                   PTHREAD_KEYS_MAX );
+        SC_CASE( _SC_THREAD_STACK_MIN,                  PTHREAD_STACK_MIN );
+        SC_CASE( _SC_THREAD_THREADS_MAX,                PTHREAD_THREADS_MAX );
+#endif
+        SC_CASE( _SC_TIMER_MAX,                         TIMER_MAX );
+        SC_CASE( _SC_TTY_NAME_MAX,                      TTY_NAME_MAX );
+        SC_CASE( _SC_TZNAME_MAX,                        TZNAME_MAX );
+        SC_CASE( _SC_VERSION,                           _POSIX_VERSION );
+
+#ifdef CYGPKG_POSIX_TIMERS
+    case _SC_CLK_TCK:
+    {
+        struct timespec ts;
+        ts.tv_sec = 1;
+        ts.tv_nsec = 0;
+        cyg_tick_count ticks = cyg_timespec_to_ticks( &ts );
+        return ticks;
+    }
+#endif
+
+    case _SC_ASYNCHRONOUS_IO:
+    #ifdef _POSIX_ASYNCHRONOUS_IO
+        return 1;
+    #else
+        return -1;
+    #endif
+            
+    case _SC_FSYNC:
+    #ifdef _POSIX_FSYNC
+        return 1;
+    #else
+        return -1;
+    #endif
+                
+    case _SC_JOB_CONTROL:
+    #ifdef _POSIX_JOB_CONTROL
+        return 1;
+    #else
+        return -1;
+    #endif
+                    
+    case _SC_MAPPED_FILES:
+    #ifdef _POSIX_MAPPED_FILES
+        return 1;
+    #else
+        return -1;
+    #endif
+                        
+    case _SC_MEMLOCK:
+    #ifdef _POSIX_MEMLOCK
+        return 1;
+    #else
+        return -1;
+    #endif
+                            
+    case _SC_MEMLOCK_RANGE:
+    #ifdef _POSIX_MEMLOCK_RANGE
+        return 1;
+    #else
+        return -1        ;
+    #endif      
+                                
+    case _SC_MEMORY_PROTECTION:
+    #ifdef _POSIX_MEMORY_PROTECTION
+        return 1;
+    #else
+        return -1;
+    #endif
+            
+    case _SC_MESSAGE_PASSING:
+    #ifdef _POSIX_MESSAGE_PASSING
+        return 1;
+    #else
+        return -1;
+    #endif
+                
+    case _SC_PRIORITIZED_IO:
+    #ifdef _POSIX_PRIORITIZED_IO
+        return 1;
+    #else
+        return -1;
+    #endif
+                    
+    case _SC_PRIORITY_SCHEDULING:
+    #ifdef _POSIX_PRIORITY_SCHEDULING
+        return 1;
+    #else
+        return -1;
+    #endif
+                        
+    case _SC_REALTIME_SIGNALS:
+    #ifdef _POSIX_REALTIME_SIGNALS
+        return 1;
+    #else
+        return -1;
+    #endif
+                            
+    case _SC_SAVED_IDS:
+    #ifdef _POSIX_SAVED_IDS
+        return 1;
+    #else
+        return -1;
+    #endif
+                                
+    case _SC_SEMAPHORES:
+    #ifdef _POSIX_SEMAPHORES
+        return 1;
+    #else
+        return -1;
+    #endif
+                                    
+    case _SC_SHARED_MEMORY_OBJECTS:
+    #ifdef _POSIX_SHARED_MEMORY_OBJECTS
+        return 1;
+    #else
+        return -1;
+    #endif
+                                        
+    case _SC_SYNCHRONIZED_IO:
+    #ifdef _POSIX_SYNCHRONIZED_IO
+        return 1;
+    #else
+        return -1;
+    #endif
+                                            
+    case _SC_THREADS:
+    #ifdef _POSIX_THREADS
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                
+    case _SC_THREAD_ATTR_STACKADDR:
+    #ifdef _POSIX_THREAD_ATTR_STACKADDR
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                    
+    case _SC_THREAD_ATTR_STACKSIZE:
+    #ifdef _POSIX_THREAD_ATTR_STACKSIZE
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                        
+    case _SC_THREAD_PRIO_INHERIT:
+    #ifdef _POSIX_THREAD_PRIO_INHERIT
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                            
+    case _SC_THREAD_PRIO_PROTECT:
+    #ifdef _POSIX_THREAD_PRIO_PROTECT
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                                
+    case _SC_THREAD_PRIORITY_SCHEDULING:
+    #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                                    
+    case _SC_THREAD_PROCESS_SHARED:
+    #ifdef _POSIX_THREAD_PROCESS_SHARED
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                                        
+    case _SC_THREAD_SAFE_FUNCTIONS:
+    #ifdef _POSIX_THREAD_SAFE_FUNCTIONS
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                                            
+    case _SC_TIMERS:
+    #ifdef _POSIX_TIMERS
+        return 1;
+    #else
+        return -1;
+    #endif
+                                                                                
+
+    default:
+        errno = EINVAL;
+        return -1;
+    }
+}
+
+//==========================================================================
+// Some trivial compatibility functions.
+// These are merely present to permit existing code to be ported a little
+// more easily, and to provide adequate standards compatibility.
+
+__externC pid_t getpid    ( void ) { return 42; }
+__externC pid_t getppid   ( void ) { return 41; }
+__externC uid_t getuid    ( void ) { return 666; }
+__externC uid_t geteuid   ( void ) { return 666; }
+__externC gid_t getgid    ( void ) { return 88; }
+__externC gid_t getegid   ( void ) { return 88; }
+__externC int   setuid    ( uid_t uid ) { errno = EPERM; return -1; }
+__externC int   setgid    ( uid_t gid ) { errno = EPERM; return -1; }
+__externC int   getgroups ( int gidsetsize, gid_t grouplist[] ) { return 0; };
+__externC pid_t getpgrp   ( void ) { return 42; }
+__externC pid_t setsid    ( void ) { errno = EPERM; return -1; }
+__externC int   setpgid   ( pid_t pid, pid_t pgid ) { errno = ENOSYS; return -1; }
+
+//==========================================================================
+// Exports to other packages
+
+// -------------------------------------------------------------------------
+// POSIX API function entry
+
+__externC void cyg_posix_function_start()
+{
+    Cyg_Thread *self = Cyg_Scheduler::get_current_thread();
+
+    // Inhibit ASR delivery in this function until it returns.
+    
+    self->set_asr_inhibit();
+}
+
+// -------------------------------------------------------------------------
+
+__externC void cyg_posix_function_finish()
+{
+    Cyg_Thread *self = Cyg_Scheduler::get_current_thread();
+
+    // Re-allow ASR delivery.
+    
+    self->clear_asr_inhibit();
+
+    // After clearing the inhibit flag, blip the scheduler lock
+    // to get any pending ASRs delivered.
+    Cyg_Scheduler::lock();
+    Cyg_Scheduler::unlock();
+}
+
+// -------------------------------------------------------------------------
+// EOF misc.cxx
diff --git a/packages/compat/posix/v2_0/src/mqueue.cxx b/packages/compat/posix/v2_0/src/mqueue.cxx
new file mode 100644 (file)
index 0000000..350950a
--- /dev/null
@@ -0,0 +1,1005 @@
+/*========================================================================
+//
+//      mqueue.cxx
+//
+//      Message queues tests
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     jlarmour
+// Contributors:  
+// Date:          2000-05-14
+// Purpose:       This file provides the implementation for POSIX message
+//                queues
+// Description:   It uses eCos kernel mqueues as the underlying
+//                implementation
+// Usage:         
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/posix.h>
+
+#ifdef CYGPKG_POSIX_MQUEUES
+
+#include <pkgconf/kernel.h>
+
+/* INCLUDES */
+
+#include <cyg/infra/cyg_type.h>      // common types etc.
+#include <cyg/infra/cyg_ass.h>       // Assertion support
+#include <cyg/infra/cyg_trac.h>      // Tracing support
+#include <cyg/kernel/mqueue.hxx>     // eCos Mqueue Header
+#include <cyg/kernel/sched.hxx>      // Cyg_Scheduler::lock()
+#include <cyg/kernel/sched.inl>      // inlines for above
+#include <mqueue.h>                  // Standard POSIX mqueue header
+#include <sys/types.h>               // mode_t, ssize_t
+#include <limits.h>                  // PATH_MAX
+#include <stdlib.h>                  // malloc, etc.
+#include <errno.h>                   // errno
+#include <fcntl.h>                   // O_*
+#include <stdarg.h>                  // varargs
+#include <pthread.h>                 // mutexes
+#include <string.h>                  // strncpy
+#ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+# include <signal.h>
+# include "pprivate.h"               // cyg_sigqueue()
+#endif
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+# include <time.h>
+# include "pprivate.h"               // cyg_timespec_to_ticks()
+#endif
+
+/* CONSTANTS */
+
+#define MQ_VALID_MAGIC  0x6db256c1
+
+/* TYPE DEFINITIONS */
+
+struct mqtabent;
+
+// this is a queue user - each one of these corresponds to a mqd_t
+struct mquser {
+    int flags;               // O_RDONLY, O_WRONLY, O_RDWR, O_NONBLOCK
+    struct mqtabent *tabent; // back pointer to table entry
+    struct mquser *next;
+    bool notifieruser;       // POSIX sucks so bad. It requires a mq_close
+                             // to only deregister the notification if it
+                             // was done via this descriptor. So we have to
+                             // know if it was this one
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    cyg_uint32 magic;        // magic number: MQ_VALID_MAGIC if valid
+#endif    
+};
+
+struct mqtabent {
+    char name[ PATH_MAX ]; // ascii name - set to "" when unused
+    Cyg_Mqueue *mq;        // the underlying queue object
+    long maxmsg;           // as set on creation
+    long msgsize;          // as set on creation
+    bool unlinkme;         // unlink when final user closes?
+    struct mquser *users;  // each user
+
+#ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+    const struct sigevent *sigev; // notification event
+#endif
+};
+
+/* GLOBALS */
+
+static struct mqtabent mqtab[ CYGNUM_POSIX_MQUEUE_OPEN_MAX ];
+static pthread_mutex_t mqtab_mut = PTHREAD_MUTEX_INITIALIZER;
+
+/* LOCAL FUNCTIONS */
+
+//------------------------------------------------------------------------
+
+// placement new definition
+inline void *operator new(size_t size, void *ptr) 
+{ 
+    CYG_CHECK_DATA_PTR( ptr, "Bad pointer" ); 
+    return ptr; 
+} 
+
+// Deallocation callback from Cyg_Mqueue
+static void
+my_free( void *ptr, size_t )
+{
+    free( ptr );
+}
+
+//------------------------------------------------------------------------
+
+// Do the actual "unlink" of a queue, i.e. mark it invalid in the table.
+// The table mutex is assumed to be locked
+static void
+do_mq_unlink( struct mqtabent *tabent )
+{
+    CYG_REPORT_FUNCTION();
+    CYG_CHECK_DATA_PTRC( tabent );
+
+    tabent->name[0] = '\0'; // won't match anything the user sends now
+    tabent->mq->~Cyg_Mqueue();
+    free( tabent->mq );
+    tabent->mq=NULL;
+
+    CYG_REPORT_RETURN();
+}
+
+//------------------------------------------------------------------------
+
+#ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+
+static void
+notifyme( Cyg_Mqueue &q, CYG_ADDRWORD data )
+{
+    CYG_REPORT_FUNCTION();
+    struct mquser *user = (struct mquser *)data;
+    CYG_CHECK_DATA_PTRC( user );
+    struct mqtabent *tabent = user->tabent;
+    CYG_CHECK_DATA_PTRC( tabent );
+
+    Cyg_Scheduler::lock();
+    // we may have been pre-empted before this, so check there's still a
+    // notification to do
+
+    if ( NULL == tabent->sigev ) {
+        Cyg_Scheduler::unlock();
+        CYG_REPORT_RETURN();
+        return;
+    } // if
+
+    const struct sigevent *ev = tabent->sigev;
+    
+    // first deregister
+    q.setnotify( NULL, 0 );
+    tabent->sigev = NULL;
+    user->notifieruser = false; // not any more
+    
+    // now the rest of the world can go
+    Cyg_Scheduler::unlock();
+    
+    // queue event. If it fails... nothing we can do :-( so ignore return code
+    cyg_sigqueue( ev, SI_MESGQ );
+
+    cyg_deliver_signals();
+    
+    CYG_REPORT_RETURN();
+}
+
+#endif // ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+
+//------------------------------------------------------------------------
+
+/* EXPORTED FUNCTIONS */
+
+externC mqd_t
+mq_open( const char *name, int oflag, ... )
+{
+    CYG_REPORT_FUNCTYPE( "returning %08x" );
+    CYG_REPORT_FUNCARG2( "name=%08x, oflag=%d", name, oflag );
+    CYG_CHECK_DATA_PTRC( name );
+
+    if ( ((oflag & O_RDONLY) != O_RDONLY) &&
+         ((oflag & O_WRONLY) != O_WRONLY) &&
+         ((oflag & O_RDWR) != O_RDWR)) {
+        // user didn't specify mode
+        errno = EINVAL;
+        CYG_REPORT_RETVAL( -1 );
+        return (mqd_t)-1;
+    } // if
+
+    mqd_t retval;
+    cyg_ucount32 i;
+    struct mqtabent *qtabent=NULL;
+    int interr;
+
+    interr = pthread_mutex_lock( &mqtab_mut );
+    // should never fail
+    CYG_ASSERT( interr == 0, "internal lock failed!" );
+    
+    // find if a matching entry exists first
+    // FIXME: Should check for length and return ENAMETOOLONG
+    for ( i=0; i < CYGNUM_POSIX_MQUEUE_OPEN_MAX; i++ ) {
+        if ( 0 == strncmp(name, mqtab[i].name, PATH_MAX) ) {
+            qtabent = &mqtab[i];
+            break;
+        } // if
+    } // for
+    
+    if ( (NULL != qtabent) && (O_EXCL == (oflag & O_EXCL)) ) {
+        errno = EEXIST;
+        retval = (mqd_t)-1;
+        goto exit_unlock;
+    }
+        
+    if ( (NULL == qtabent) && (O_CREAT != (oflag & O_CREAT)) ) {
+        errno = ENOENT;
+        retval = (mqd_t)-1;
+        goto exit_unlock;
+    }
+
+    // so if we didn't find something, we must be being asked to create it
+    if (NULL == qtabent) {
+        mode_t mode; // FIXME: mode ignored for now
+        const struct mq_attr *attr;
+        const struct mq_attr default_attr = { 0, MQ_OPEN_MAX, 128 };
+        va_list args;
+        
+        va_start( args, oflag );
+        mode = va_arg( args, mode_t );
+        attr = va_arg( args, struct mq_attr * );
+        va_end( args );
+
+        // find an empty table entry
+        for ( i=0; i < CYGNUM_POSIX_MQUEUE_OPEN_MAX; i++ ) {
+            if ( NULL == mqtab[i].mq )
+                break;
+        }
+
+        // if not found, table is full
+        if ( i == CYGNUM_POSIX_MQUEUE_OPEN_MAX ) {
+            errno = ENFILE;
+            retval = (mqd_t)-1;
+            goto exit_unlock;
+        }
+
+        Cyg_Mqueue::qerr_t qerr;
+
+        // user can specify NULL attr, which means arbitrary message queue
+        // size! Duh.
+        if ( NULL == attr )
+            attr = &default_attr;
+        else {
+            // if they do supply one, POSIX says we're meant to check it
+            if (attr->mq_maxmsg <= 0 || attr->mq_msgsize <= 0) {
+                errno = EINVAL;
+                retval = (mqd_t)-1;
+                goto exit_unlock;
+            }
+        } // else
+
+        // allocate the underlying queue
+        Cyg_Mqueue *mqholder = (Cyg_Mqueue *)malloc( sizeof(Cyg_Mqueue) );
+        if ( NULL == mqholder ) {
+            errno = ENOSPC;
+            retval = (mqd_t)-1;
+            goto exit_unlock;
+        }
+            
+        // construct it with placement new
+        mqtab[i].mq = new (mqholder) Cyg_Mqueue( attr->mq_maxmsg,
+                                                 attr->mq_msgsize,
+                                                 &malloc, &my_free, &qerr );
+            
+        switch (qerr) {
+        case Cyg_Mqueue::OK:
+            break;
+        case Cyg_Mqueue::NOMEM:
+            free( mqholder );
+            errno = ENOSPC;
+            retval = (mqd_t)-1;
+            goto exit_unlock;
+        default:
+            CYG_FAIL("Unhandled Cyg_Mqueue constructor return error");
+            break;
+        } // switch
+
+        mqtab[i].users = (struct mquser *) malloc( sizeof(struct mquser) );
+        if ( NULL == mqtab[i].users ) {
+            mqtab[i].mq->~Cyg_Mqueue();
+            free( mqholder );
+            errno = ENOSPC;
+            retval = (mqd_t)-1;
+            goto exit_unlock;
+        }
+
+        // initialize mqtab[i]
+        mqtab[i].maxmsg  = attr->mq_maxmsg;
+        mqtab[i].msgsize = attr->mq_msgsize;
+        mqtab[i].unlinkme = false;
+#ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+        mqtab[i].sigev = NULL;
+#endif
+        strncpy( mqtab[i].name, name, PATH_MAX );
+
+        // initialize first mqtab[i].users
+        mqtab[i].users->next = NULL;
+        // set the mode for later, but also note that O_NONBLOCK can
+        // be set in oflags *or* the attr the user passed
+        mqtab[i].users->flags = oflag | (attr->mq_flags & O_NONBLOCK);
+
+        // set back pointer so that message queue handle can find actual queue
+        mqtab[i].users->tabent = &mqtab[i]; 
+        
+        mqtab[i].users->notifieruser = false;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+        mqtab[i].users->magic = MQ_VALID_MAGIC; // now valid
+#endif
+        
+        retval=(mqd_t)mqtab[i].users;
+
+        goto exit_unlock;
+    } // if (NULL == qtabent)
+
+    // so we're not creating, and we have a valid qtabent
+
+    // But this qtabent may be being unlinked. If so, we are permitted
+    // to return an error, so we will. (see under mq_unlink() in POSIX)
+    // Which error though? EINVAL seems best, but POSIX doesn't say :-/
+
+    if (true == qtabent->unlinkme) {
+        errno = EINVAL;
+        retval = (mqd_t)-1;
+        goto exit_unlock;
+    }
+    
+    // now we have a usable qtabent
+
+    struct mquser *user;
+    user = (struct mquser *) malloc( sizeof(struct mquser) );
+    if ( NULL == user ) {
+            errno = ENOSPC;
+            retval = (mqd_t)-1;
+            goto exit_unlock;
+    }
+
+    // prepend to qtab user list
+    user->next = qtabent->users;
+    qtabent->users = user;
+
+    // set back pointer so that message queue handle can find actual queue
+    user->tabent = qtabent;
+
+    user->flags = oflag;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    user->magic = MQ_VALID_MAGIC; // now valid
+#endif
+
+    retval=(mqd_t)user;
+
+ exit_unlock:
+    interr = pthread_mutex_unlock( &mqtab_mut );
+    // should never fail
+    CYG_ASSERT( interr == 0, "internal lock failed!" );
+    CYG_REPORT_RETVAL( retval );
+    return retval;
+} // mq_open()
+
+//------------------------------------------------------------------------
+
+// NOTE: It is the *user*'s responsibility to ensure that nothing is
+// blocked in mq_send() or mq_receive() when closing the queue with
+// that descriptor. The standard does not specify the behaviour, so that's
+// what I am assuming
+
+externC int
+mq_close( mqd_t mqdes )
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+    CYG_REPORT_FUNCARG1XV( mqdes );
+    
+    struct mquser *user = (struct mquser *)mqdes;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+#endif
+    
+    int interr;
+
+    interr = pthread_mutex_lock( &mqtab_mut );
+    // should never fail
+    CYG_ASSERT( interr == 0, "internal lock failed!" );
+
+    struct mqtabent *tabent = user->tabent;
+    struct mquser *usertmp;
+    
+    // perhaps should return EBADF instead of assert?
+    CYG_ASSERT( tabent->users != NULL, "Null message queue user list" );
+
+#ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+    // deregister notification iff this was the message queue descriptor
+    // that was used to register it (POSIX says)
+    if ( true == user->notifieruser ) {
+        tabent->mq->setnotify( NULL, 0 );
+        tabent->sigev = NULL;
+        // not worth clearing notifieruser
+    }
+#endif
+
+    // find in the list for this queue and remove - sucks a bit, but seems
+    // best over all - the list shouldn't be too long
+    if ( tabent->users == user ) {
+        tabent->users = user->next;  // remove
+    } else {
+        for ( usertmp=tabent->users;
+              NULL != usertmp->next;
+              usertmp = usertmp->next ) {
+            if ( usertmp->next == user )
+                break;
+        } // for
+
+        // perhaps should return EBADF instead of assert?
+        CYG_ASSERT( usertmp->next != NULL, "Couldn't find message queue user" );
+
+        usertmp->next = user->next; // remove
+    } // else
+    
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    user->magic = 0; // invalidate
+#endif
+
+    // free it up
+    free( user );
+
+    if ( (true == tabent->unlinkme) && (NULL == tabent->users) ) {
+        do_mq_unlink( tabent );
+    } // if
+
+    interr = pthread_mutex_unlock( &mqtab_mut );
+    // should never fail
+    CYG_ASSERT( interr == 0, "internal lock failed!" );
+    CYG_REPORT_RETVAL( 0 );
+    return 0;
+} // mq_close()
+
+
+//------------------------------------------------------------------------
+
+externC int
+mq_unlink( const char *name )
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+    CYG_REPORT_FUNCARG1( "name=%s", name );
+
+    int retval, interr;
+    cyg_ucount32 i;
+    struct mqtabent *qtabent=NULL;
+
+    interr = pthread_mutex_lock( &mqtab_mut );
+    // should never fail
+    CYG_ASSERT( interr == 0, "internal lock failed!" );
+
+    // find the entry first
+    // FIXME: Should check for length and return ENAMETOOLONG
+    for ( i=0; i < CYGNUM_POSIX_MQUEUE_OPEN_MAX; i++ ) {
+        if ( 0 == strncmp(name, mqtab[i].name, PATH_MAX) ) {
+            qtabent = &mqtab[i];
+            break;
+        } // if
+    } // for
+
+    if ( NULL == qtabent ) { // not found
+        errno = ENOENT;
+        retval = -1;
+        goto exit_unlock;
+    }
+
+    if ( NULL != qtabent->users ) {   // still in use
+        qtabent->unlinkme = true;     // so mark it as pending deletion
+    } else {
+        do_mq_unlink( qtabent );
+    } // else
+
+    retval = 0;
+
+ exit_unlock:
+    interr = pthread_mutex_unlock( &mqtab_mut );
+    // should never fail
+    CYG_ASSERT( interr == 0, "internal lock failed!" );
+    CYG_REPORT_RETVAL( retval );
+    return retval;
+} // mq_unlink()
+
+//------------------------------------------------------------------------
+
+externC int
+mq_send( mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+         unsigned int msg_prio )
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+    CYG_REPORT_FUNCARG4( "mqdes=%08x, msg_ptr=%08x, msg_len=%u, msg_prio=%u",
+                         mqdes, msg_ptr, msg_len, msg_prio );
+    CYG_CHECK_DATA_PTRC( msg_ptr );
+    
+    struct mquser *user = (struct mquser *)mqdes;
+    struct mqtabent *tabent = user->tabent;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+#endif
+    
+    if ( msg_len > (size_t)tabent->msgsize ) {
+        errno = EMSGSIZE;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    if ( msg_prio > MQ_PRIO_MAX ) {
+        errno = EINVAL;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    if ( (O_WRONLY != (user->flags & O_WRONLY)) && 
+         (O_RDWR != (user->flags & O_RDWR)) ) {
+        errno = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    // go for it
+    Cyg_Mqueue::qerr_t err;
+    err = tabent->mq->put( msg_ptr, msg_len, msg_prio,
+                           ((user->flags & O_NONBLOCK) != O_NONBLOCK) );
+    switch (err) {
+
+    case Cyg_Mqueue::INTR:
+        errno = EINTR;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+
+    case Cyg_Mqueue::WOULDBLOCK:
+        CYG_ASSERT( (user->flags & O_NONBLOCK) == O_NONBLOCK,
+                    "Message queue assumed non-blocking when blocking requested"
+            );
+        errno = EAGAIN;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+        
+    case Cyg_Mqueue::OK:
+        CYG_REPORT_RETVAL( 0 );
+        return 0;
+
+    default:
+        CYG_FAIL( "unhandled message queue return code" );
+        return -1; // keep compiler happy
+    } // switch
+} // mq_send()
+
+//------------------------------------------------------------------------
+
+
+externC ssize_t
+mq_receive( mqd_t mqdes, char *msg_ptr, size_t msg_len,
+            unsigned int *msg_prio )
+{
+    CYG_REPORT_FUNCTYPE( "returning %ld" );
+    CYG_REPORT_FUNCARG4( "mqdes=%08x, msg_ptr=%08x, msg_len=%u, msg_prio=%08x",
+                         mqdes, msg_ptr, msg_len, msg_prio );
+    CYG_CHECK_DATA_PTRC( msg_ptr );
+    CYG_CHECK_DATA_PTRC( msg_ptr+msg_len-1 );
+    if ( NULL != msg_prio )
+        CYG_CHECK_DATA_PTRC( msg_prio );
+    
+    
+    struct mquser *user = (struct mquser *)mqdes;
+    struct mqtabent *tabent = user->tabent;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+    }
+#endif
+    
+    if ( (O_RDONLY != (user->flags & O_RDONLY)) && 
+         (O_RDWR != (user->flags & O_RDWR)) ) {
+        errno = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+    }
+
+    if ( msg_len < (size_t)tabent->msgsize ) {
+        errno = EMSGSIZE;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+    }
+
+    // go for it
+    Cyg_Mqueue::qerr_t err;
+    err = tabent->mq->get( msg_ptr, &msg_len, msg_prio,
+                           ((user->flags & O_NONBLOCK) != O_NONBLOCK) );
+    switch (err) {
+
+    case Cyg_Mqueue::INTR:
+        errno = EINTR;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+
+    case Cyg_Mqueue::WOULDBLOCK:
+        CYG_ASSERT( (user->flags & O_NONBLOCK) == O_NONBLOCK,
+                    "Message queue assumed non-blocking when blocking requested"
+            );
+        errno = EAGAIN;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+        
+    case Cyg_Mqueue::OK:
+        CYG_ASSERT( msg_len <= (size_t)tabent->msgsize,
+                    "returned message too long" );
+        if ( NULL != msg_prio )
+            CYG_ASSERT( *msg_prio <= MQ_PRIO_MAX,
+                        "returned message has invalid priority" );
+        CYG_REPORT_RETVAL( msg_len );
+        return (ssize_t)msg_len;
+
+    default:
+        CYG_FAIL( "unhandled message queue return code" );
+        return (ssize_t)-1; // keep compiler happy
+    } // switch
+    
+} // mq_receive()
+
+
+//------------------------------------------------------------------------
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+externC int
+mq_timedsend( mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+              unsigned int msg_prio, const struct timespec *abs_timeout)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+    CYG_REPORT_FUNCARG6( "mqdes=%08x, msg_ptr=%08x, msg_len=%u, msg_prio=%u, "
+                         "abs_timeout = %lu, %ld",
+                         mqdes, msg_ptr, msg_len, msg_prio, 
+                         abs_timeout->tv_sec, abs_timeout->tv_nsec);
+    CYG_CHECK_DATA_PTRC( msg_ptr );
+    
+    struct mquser *user = (struct mquser *)mqdes;
+    struct mqtabent *tabent = user->tabent;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+#endif
+    
+    if ( msg_len > (size_t)tabent->msgsize ) {
+        errno = EMSGSIZE;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    if ( msg_prio > MQ_PRIO_MAX ) {
+        errno = EINVAL;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    if ( (O_WRONLY != (user->flags & O_WRONLY)) && 
+         (O_RDWR != (user->flags & O_RDWR)) ) {
+        errno = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    // go for it
+    Cyg_Mqueue::qerr_t err;
+    bool nonblocking = ((user->flags & O_NONBLOCK) == O_NONBLOCK);
+    bool badtimespec = (abs_timeout->tv_nsec < 0) ||
+        (abs_timeout->tv_nsec > 999999999l);
+    cyg_tick_count abs_ticks = cyg_timespec_to_ticks(abs_timeout);
+
+    // We should never time out if there is room in the queue.  Simplest
+    // way to ensure this is to try the non-blocking put() first.
+    err = tabent->mq->put( msg_ptr, msg_len, msg_prio, false, abs_ticks );
+
+    // If the blocking variant would have blocked and that is what's wanted
+    if ( Cyg_Mqueue::WOULDBLOCK == err && !nonblocking && !badtimespec ) {
+        err = tabent->mq->put( msg_ptr, msg_len, msg_prio, true, 
+                               abs_ticks );
+    }
+
+    switch (err) {
+
+    case Cyg_Mqueue::INTR:
+        errno = EINTR;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+
+    case Cyg_Mqueue::WOULDBLOCK:
+        if (badtimespec) {
+            errno = EINVAL;
+            CYG_REPORT_RETVAL( -1 );
+            return -1;
+        }
+        CYG_ASSERT( (user->flags & O_NONBLOCK) == O_NONBLOCK,
+                    "Message queue assumed non-blocking when blocking requested"
+            );
+        errno = EAGAIN;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+
+    case Cyg_Mqueue::TIMEOUT:
+        errno = ETIMEDOUT;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+        
+    case Cyg_Mqueue::OK:
+        CYG_REPORT_RETVAL( 0 );
+        return 0;
+
+    default:
+        CYG_FAIL( "unhandled message queue return code" );
+        return -1; // keep compiler happy
+    } // switch
+} // mq_timedsend()
+
+//------------------------------------------------------------------------
+
+
+externC ssize_t
+mq_timedreceive( mqd_t mqdes, char *msg_ptr, size_t msg_len,
+            unsigned int *msg_prio, const struct timespec *abs_timeout)
+{
+    CYG_REPORT_FUNCTYPE( "returning %ld" );
+    CYG_REPORT_FUNCARG6( "mqdes=%08x, msg_ptr=%08x, msg_len=%u, msg_prio=%08x, "
+                        "abs_timeout = %lu, %ld",
+                         mqdes, msg_ptr, msg_len, msg_prio,
+                         abs_timeout->tv_sec, abs_timeout->tv_nsec );
+    CYG_CHECK_DATA_PTRC( msg_ptr );
+    CYG_CHECK_DATA_PTRC( msg_ptr+msg_len-1 );
+    if ( NULL != msg_prio )
+        CYG_CHECK_DATA_PTRC( msg_prio );
+    
+    
+    struct mquser *user = (struct mquser *)mqdes;
+    struct mqtabent *tabent = user->tabent;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+    }
+#endif
+    
+    if ( (O_RDONLY != (user->flags & O_RDONLY)) && 
+         (O_RDWR != (user->flags & O_RDWR)) ) {
+        errno = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+    }
+
+    if ( msg_len < (size_t)tabent->msgsize ) {
+        errno = EMSGSIZE;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+    }
+
+    // go for it
+    Cyg_Mqueue::qerr_t err;
+    bool nonblocking = ((user->flags & O_NONBLOCK) == O_NONBLOCK);
+    bool badtimespec = (abs_timeout->tv_nsec < 0) ||
+        (abs_timeout->tv_nsec > 999999999l);
+    cyg_tick_count abs_ticks = cyg_timespec_to_ticks(abs_timeout);
+
+    // We should never time out if there is something to read.  Simplest
+    // way to ensure this is to try the non-blocking get() first.
+    err = tabent->mq->get( msg_ptr, &msg_len, msg_prio, false, abs_ticks );
+
+    // If the blocking variant would have blocked and that is what's wanted
+    if ( Cyg_Mqueue::WOULDBLOCK == err && !nonblocking && !badtimespec ) {
+        err = tabent->mq->get( msg_ptr, &msg_len, msg_prio, true, abs_ticks );
+    }
+
+    switch (err) {
+
+    case Cyg_Mqueue::INTR:
+        errno = EINTR;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+
+    case Cyg_Mqueue::WOULDBLOCK:
+        if (badtimespec) {
+            errno = EINVAL;
+            CYG_REPORT_RETVAL( -1 );
+            return -1;
+        }
+        CYG_ASSERT( (user->flags & O_NONBLOCK) == O_NONBLOCK,
+                    "Message queue assumed non-blocking when blocking requested"
+            );
+        errno = EAGAIN;
+        CYG_REPORT_RETVAL( -1 );
+        return (ssize_t)-1;
+
+    case Cyg_Mqueue::TIMEOUT:
+        errno = ETIMEDOUT;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+        
+    case Cyg_Mqueue::OK:
+        CYG_ASSERT( msg_len <= (size_t)tabent->msgsize,
+                    "returned message too long" );
+        if ( NULL != msg_prio )
+            CYG_ASSERT( *msg_prio <= MQ_PRIO_MAX,
+                        "returned message has invalid priority" );
+        CYG_REPORT_RETVAL( msg_len );
+        return (ssize_t)msg_len;
+
+    default:
+        CYG_FAIL( "unhandled message queue return code" );
+        return (ssize_t)-1; // keep compiler happy
+    } // switch
+    
+} // mq_timedreceive()
+
+//------------------------------------------------------------------------
+#endif
+
+#ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+
+externC int
+mq_notify( mqd_t mqdes, const struct sigevent *notification )
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+    CYG_REPORT_FUNCARG2( "mqdes=%08x, notification=%08x", mqdes, notification );
+    if ( NULL != notification )
+        CYG_CHECK_DATA_PTRC( notification );
+    
+    struct mquser *user = (struct mquser *)mqdes;
+    struct mqtabent *tabent = user->tabent;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+#endif
+    
+    // lock scheduler since we test and set non-atomically
+    Cyg_Scheduler::lock();
+    
+    // we are being told to clear the notification function
+    if ( NULL == notification ) {
+        tabent->mq->setnotify( NULL, 0 );
+        tabent->sigev = NULL;
+        Cyg_Scheduler::unlock();
+        CYG_REPORT_RETVAL( 0 );
+        return 0;
+    } // if
+    
+    if ( NULL != tabent->sigev ) {  // already registered
+        Cyg_Scheduler::unlock();
+        errno = EBUSY;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    } // if
+
+    tabent->sigev = notification;
+    user->notifieruser = true; // Used for deciding about whether to
+                               // deregister in mq_close()
+    tabent->mq->setnotify( &notifyme, (CYG_ADDRWORD) user );
+    Cyg_Scheduler::unlock();
+    
+    CYG_REPORT_RETVAL( 0 );
+    return 0;
+} // mq_notify()
+
+#endif // ifdef CYGFUN_POSIX_MQUEUE_NOTIFY
+
+//------------------------------------------------------------------------
+
+externC int
+mq_setattr( mqd_t mqdes, const struct mq_attr *mqstat,
+            struct mq_attr *omqstat )
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+    CYG_REPORT_FUNCARG3( "mqdes=%08x, mqstat=%08x, omqstat=%08x",
+                         mqdes, mqstat, omqstat );
+    CYG_CHECK_DATA_PTRC( mqstat );
+
+    struct mquser *user = (struct mquser *)mqdes;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+#endif
+    
+    if ( NULL != omqstat ) {
+        CYG_CHECK_DATA_PTRC( omqstat );
+        mq_getattr( mqdes, omqstat );
+    } // if
+
+    // Two-stage update, so lock sched since it's quick
+    Cyg_Scheduler::lock();
+    user->flags &= ~O_NONBLOCK;  // clear
+    if ( (mqstat->mq_flags & O_NONBLOCK) == O_NONBLOCK ) {
+        user->flags |= O_NONBLOCK;
+    } // if
+    Cyg_Scheduler::unlock();
+
+    CYG_REPORT_RETVAL( 0 );
+    return 0;
+} // mq_setattr()
+
+//------------------------------------------------------------------------
+
+externC int
+mq_getattr( mqd_t mqdes, struct mq_attr *mqstat )
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+    CYG_REPORT_FUNCARG2( "mqdes=%08x, mqstat=%08x", mqdes, mqstat );
+    CYG_CHECK_DATA_PTRC( mqstat );
+
+    struct mquser *user = (struct mquser *)mqdes;
+    struct mqtabent *tabent = user->tabent;
+
+#ifdef CYGIMP_POSIX_MQUEUE_VALIDATE_DESCRIPTOR
+    if ( user->magic != MQ_VALID_MAGIC ) {
+        errno  = EBADF;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+#endif
+    
+    mqstat->mq_flags   = user->flags;
+    mqstat->mq_maxmsg  = tabent->maxmsg;
+    mqstat->mq_msgsize = tabent->msgsize;
+    mqstat->mq_curmsgs = tabent->mq->count();    
+    
+    CYG_REPORT_RETVAL( 0 );
+    return 0;
+} // mq_getattr()
+
+
+//------------------------------------------------------------------------
+
+#endif // ifdef CYGPKG_POSIX_MQUEUES
+
+/* EOF mqueue.cxx */
diff --git a/packages/compat/posix/v2_0/src/mutex.cxx b/packages/compat/posix/v2_0/src/mutex.cxx
new file mode 100644 (file)
index 0000000..66dbf45
--- /dev/null
@@ -0,0 +1,551 @@
+//==========================================================================
+//
+//      pthread.cxx
+//
+//      POSIX pthreads implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg, jlarmour, Wade Jensen
+// Date:                2000-03-27
+// Purpose:             POSIX pthread implementation
+// Description:         This file contains the implementation of the POSIX pthread
+//                      functions.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/posix.h>
+
+#include <cyg/infra/cyg_trac.h>        // tracing macros
+#include <cyg/infra/cyg_ass.h>         // assertion macros
+
+#include "pprivate.h"                  // POSIX private header
+
+#include <cyg/kernel/thread.hxx>       // thread definitions
+#include <cyg/kernel/mutex.hxx>        // mutex definitions
+#include <cyg/kernel/clock.hxx>        // clock definitions
+#include <cyg/kernel/sched.hxx>        // scheduler primitives
+#include <pthread.h>
+
+#include <cyg/kernel/thread.inl>       // thread inlines
+#include <cyg/kernel/sched.inl>        // scheduler inlines
+
+//-----------------------------------------------------------------------------
+// new operator to allow us to construct mutex objects
+
+inline void *operator new(size_t size,  cyg_uint8 *ptr) { return (void *)ptr; };
+
+//=============================================================================
+// Mutexes
+
+//-----------------------------------------------------------------------------
+// Mutex attributes manipulation functions
+
+//-----------------------------------------------------------------------------
+// Initialize attribute object
+
+externC int pthread_mutexattr_init ( pthread_mutexattr_t *attr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    attr->protocol      = PTHREAD_PRIO_NONE;
+#ifdef _POSIX_THREAD_PRIO_PROTECT    
+    attr->prioceiling   = 0;
+#endif
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Destroy attribute object
+
+externC int pthread_mutexattr_destroy ( pthread_mutexattr_t *attr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    // Nothing to do here...
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Optional functions depending on priority inversion protection options.
+
+#if defined(_POSIX_THREAD_PRIO_INHERIT) || defined(_POSIX_THREAD_PRIO_PROTECT)
+
+// Set priority inversion protection protocol
+externC int pthread_mutexattr_setprotocol ( pthread_mutexattr_t *attr,
+                                            int protocol)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    switch( protocol )
+    {
+    case PTHREAD_PRIO_NONE:
+#if defined(_POSIX_THREAD_PRIO_INHERIT)        
+    case PTHREAD_PRIO_INHERIT:
+#endif
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+    case PTHREAD_PRIO_PROTECT:
+#endif        
+        attr->protocol = protocol;
+        PTHREAD_RETURN(0);
+
+    default:
+        PTHREAD_RETURN(EINVAL);
+    }
+    
+    PTHREAD_RETURN(0);
+}
+
+// Get priority inversion protection protocol
+externC int pthread_mutexattr_getprotocol ( pthread_mutexattr_t *attr,
+                                            int *protocol)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( protocol != NULL )
+        *protocol = attr->protocol;
+    
+    PTHREAD_RETURN(0);
+}
+
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+
+// Set priority for priority ceiling protocol
+externC int pthread_mutexattr_setprioceiling ( pthread_mutexattr_t *attr,
+                                               int prioceiling)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    
+    attr->prioceiling = prioceiling;
+    
+    PTHREAD_RETURN(0);
+}
+
+// Get priority for priority ceiling protocol
+externC int pthread_mutexattr_getprioceiling ( pthread_mutexattr_t *attr,
+                                               int *prioceiling)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( prioceiling != NULL )
+        *prioceiling = attr->prioceiling;
+    
+    PTHREAD_RETURN(0);
+}
+
+// Set priority ceiling of given mutex, returning old ceiling.
+externC int pthread_mutex_setprioceiling( pthread_mutex_t *mutex,
+                                          int prioceiling,
+                                          int *old_ceiling)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(mutex);
+
+    pthread_mutex_lock( mutex );
+
+    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;
+
+    if( old_ceiling != NULL )
+        *old_ceiling = mx->get_ceiling();
+    
+    mx->set_ceiling( prioceiling );
+    
+    pthread_mutex_unlock( mutex );
+
+    PTHREAD_RETURN(0);
+}
+
+// Get priority ceiling of given mutex
+externC int pthread_mutex_getprioceiling( pthread_mutex_t *mutex,
+                                          int *prioceiling)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(mutex);
+
+    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;
+
+    if( prioceiling != NULL )
+        *prioceiling = mx->get_ceiling();
+        
+    PTHREAD_RETURN(0);
+}
+
+#endif // defined(_POSIX_THREAD_PRIO_PROTECT)
+
+#endif // defined(_POSIX_THREAD_PRIO_INHERIT) || defined(_POSIX_THREAD_PRIO_PROTECT)
+
+//-----------------------------------------------------------------------------
+// Mutex functions
+
+//-----------------------------------------------------------------------------
+// Initialize mutex. If mutex_attr is NULL, use default attributes.
+
+externC int pthread_mutex_init (pthread_mutex_t *mutex,
+                                const pthread_mutexattr_t *mutex_attr)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( mutex );
+    
+    pthread_mutexattr_t use_attr;
+
+    // Set up the attributes we are going to use
+    if( mutex_attr == NULL )
+        pthread_mutexattr_init( &use_attr );
+    else use_attr = *mutex_attr;
+
+    // Now translate the POSIX protocol identifier into the eCos one.
+    Cyg_Mutex::cyg_protcol protocol;
+    
+    switch( use_attr.protocol )
+    {
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+    case PTHREAD_PRIO_PROTECT:
+        protocol = Cyg_Mutex::CEILING;
+        break;
+#endif
+#if defined(_POSIX_THREAD_PRIO_INHERIT)
+    case PTHREAD_PRIO_INHERIT:
+        protocol = Cyg_Mutex::INHERIT;
+        break;
+#endif        
+    case PTHREAD_PRIO_NONE:
+        protocol = Cyg_Mutex::NONE;
+        break;
+
+    default:
+        PTHREAD_RETURN(EINVAL);
+    }
+
+    Cyg_Mutex *mx = new((cyg_uint8 *)mutex) Cyg_Mutex(  protocol );
+
+    mx = mx; // silence compiler warning
+#if defined(_POSIX_THREAD_PRIO_PROTECT)
+    if ( protocol == Cyg_Mutex::CEILING )
+        mx->set_ceiling( use_attr.prioceiling );
+#endif
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Destroy mutex.
+
+externC int pthread_mutex_destroy (pthread_mutex_t *mutex)
+{
+    PTHREAD_ENTRY();
+
+    int err = ENOERR;
+    
+    PTHREAD_CHECK( mutex );
+
+    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;
+    
+    if( mx->get_owner() != NULL )
+        err = EBUSY;
+    else mx->~Cyg_Mutex();
+    
+    PTHREAD_RETURN(err);
+}
+
+//-----------------------------------------------------------------------------
+// Lock mutex, waiting for it if necessary.
+
+externC int pthread_mutex_lock (pthread_mutex_t *mutex)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( mutex );
+
+    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;
+
+    if( mx->get_owner() == Cyg_Thread::self() )
+        PTHREAD_RETURN(EDEADLK);
+    
+    // Loop here until we acquire the mutex. Even if we are kicked out
+    // of the wait by a signal or release we must retry.
+    while( !mx->lock() )
+        continue;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Try to lock mutex.
+
+externC int pthread_mutex_trylock (pthread_mutex_t *mutex)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( mutex );
+    
+    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;
+
+    if( mx->get_owner() == Cyg_Thread::self() )
+        PTHREAD_RETURN(EDEADLK);
+    
+    if( mx->trylock() )
+        PTHREAD_RETURN(0);
+
+    PTHREAD_RETURN(EBUSY);
+}
+
+
+//-----------------------------------------------------------------------------
+// Unlock mutex.
+
+externC int pthread_mutex_unlock (pthread_mutex_t *mutex)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( mutex );
+    
+    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;
+
+    mx->unlock();
+    
+    PTHREAD_RETURN(0);
+}
+
+
+//=============================================================================
+// Condition Variables
+
+//-----------------------------------------------------------------------------
+// Attribute manipulation functions
+// We do not actually support any attributes at present, so these do nothing.
+
+//-----------------------------------------------------------------------------
+// Initialize condition variable attributes
+
+externC int pthread_condattr_init (pthread_condattr_t *attr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    // There are no condition variable attributes at present
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Destroy condition variable attributes
+
+externC int pthread_condattr_destroy (pthread_condattr_t *attr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    // nothing to do here...
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Condition variable functions
+
+//-----------------------------------------------------------------------------
+// Initialize condition variable.
+
+externC int pthread_cond_init (pthread_cond_t *cond,
+                               const pthread_condattr_t *attr)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( cond );
+
+    Cyg_Condition_Variable *cv =
+        new((cyg_uint8 *)cond) Cyg_Condition_Variable();
+
+    cv = cv;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Destroy condition variable.
+
+externC int pthread_cond_destroy (pthread_cond_t *cond)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( cond );
+
+    ((Cyg_Condition_Variable *)cond)->~Cyg_Condition_Variable();
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Wake up one thread waiting for condition variable
+
+externC int pthread_cond_signal (pthread_cond_t *cond)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( cond );
+
+    ((Cyg_Condition_Variable *)cond)->signal();
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Wake up all threads waiting for condition variable
+
+externC int pthread_cond_broadcast (pthread_cond_t *cond)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( cond );
+
+    ((Cyg_Condition_Variable *)cond)->broadcast();
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Block on condition variable until signalled. The mutex is
+// assumed to be locked before this call, will be unlocked
+// during the wait, and will be re-locked on wakeup.
+
+externC int pthread_cond_wait (pthread_cond_t *cond,
+                               pthread_mutex_t *mutex)
+{
+    PTHREAD_ENTRY();
+
+    // check for cancellation first.
+    PTHREAD_TESTCANCEL();
+
+    PTHREAD_CHECK( cond );
+    PTHREAD_CHECK( mutex );    
+
+    ((Cyg_Condition_Variable *)cond)->wait( *(Cyg_Mutex *)mutex );
+    
+    // check if we were woken because we were being cancelled
+    PTHREAD_TESTCANCEL();
+
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Block on condition variable until signalled, or the timeout expires.
+
+externC int pthread_cond_timedwait (pthread_cond_t *cond,
+                                    pthread_mutex_t *mutex,
+                                    const struct timespec *abstime)
+{
+    PTHREAD_ENTRY();
+
+    // check for cancellation first.
+    PTHREAD_TESTCANCEL();
+
+    PTHREAD_CHECK( cond );
+    PTHREAD_CHECK( mutex );    
+    PTHREAD_CHECK( abstime );    
+
+    // Only initialize the converters once or they will consume a huge
+    // amount or runtime.
+
+    static struct Cyg_Clock::converter ns_converter;
+    static struct Cyg_Clock::converter sec_converter;
+    static volatile cyg_atomic conv_init;
+    if (!conv_init)
+    {
+
+        // Try to avoid unnecessarily locking the scheduler when we are not
+        // initializing the converters.  Check the conv_init flag again to
+        // avoid race conditions.
+
+        struct Cyg_Clock::converter temp_ns_converter, temp_sec_converter;
+    
+        Cyg_Clock::real_time_clock
+            ->get_other_to_clock_converter( 1, &temp_ns_converter );
+        Cyg_Clock::real_time_clock
+            ->get_other_to_clock_converter( 1000000000, &temp_sec_converter );
+
+        Cyg_Scheduler::lock();
+        if (!conv_init)
+        {
+            ns_converter = temp_ns_converter;
+            sec_converter = temp_sec_converter;
+            conv_init=1;
+        }
+        Cyg_Scheduler::unlock();
+    }
+
+    cyg_tick_count ticks;
+    ticks = Cyg_Clock::convert( abstime->tv_sec, &sec_converter );
+    ticks += Cyg_Clock::convert( abstime->tv_nsec, &ns_converter );
+    
+    ((Cyg_Condition_Variable *)cond)->wait( *(Cyg_Mutex *)mutex, ticks );
+    
+    // check if we were woken because we were being cancelled
+    PTHREAD_TESTCANCEL();
+
+    if ( Cyg_Thread::self()->get_wake_reason() == Cyg_Thread::TIMEOUT )
+        PTHREAD_RETURN(ETIMEDOUT);
+    else
+        PTHREAD_RETURN(0);
+}
+
+// -------------------------------------------------------------------------
+// EOF mutex.cxx
diff --git a/packages/compat/posix/v2_0/src/pprivate.h b/packages/compat/posix/v2_0/src/pprivate.h
new file mode 100644 (file)
index 0000000..e76cdb0
--- /dev/null
@@ -0,0 +1,271 @@
+#ifndef CYGONCE_PPRIVATE_H
+#define CYGONCE_PPRIVATE_H
+//=============================================================================
+//
+//      pprivate.h
+//
+//      POSIX types header
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-03-17
+// Purpose:       POSIX private header
+// Description:   This header contains various POSIX type definitions that are
+//                shared between the various parts of the POSIX package.
+//              
+// Usage:         #include <pprivate.h>
+//              
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+
+#include <stddef.h>                     // NULL, size_t
+
+#include <sys/types.h>
+#include <sched.h>
+#include <pthread.h>
+#include <errno.h>                      // error codes
+#include <signal.h>                     // sigset_t
+#include <limits.h>                     // PTHREAD_KEYS_MAX
+
+#include <cyg/posix/export.h>           // POSIX exports header
+
+#include <cyg/kernel/thread.hxx>        // thread definitions
+#include <cyg/kernel/mutex.hxx>         // mutex definitions
+
+//=============================================================================
+// Constructor prioritization
+
+// Prioritization for POSIX library support objects
+#define CYGBLD_POSIX_INIT CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_COMPAT)
+
+// Prioritization for POSIX library startup initialization. This must
+// come after CYGBLD_POSIX_INIT constructors.
+#define CYGBLD_POSIX_START CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_COMPAT+5)
+
+//=============================================================================
+// Thread control data structure
+
+// Per-thread information needed by POSIX
+// This is pointed to by the CYGNUM_KERNEL_THREADS_DATA_POSIX entry of the
+// per-thread data.
+
+#ifdef CYGPKG_POSIX_PTHREAD
+typedef struct
+{
+    unsigned int        state:4,                // Thread state
+                        cancelstate:2,          // Cancel state of thread
+                        canceltype:2,           // Cancel type of thread
+                        cancelpending:1,        // pending cancel flag
+                        freestack:1;            // stack malloced, must be freed
+
+    pthread_t           id;                     // My thread ID
+    Cyg_Thread          *thread;                // pointer to eCos thread object
+    pthread_attr_t      attr;                   // Current thread attributes
+    void                *retval;                // return value
+    void                *(*start_routine)(void *); // start routine
+    void                *start_arg;             // argument to start routine
+    char                name[20];               // name string for debugging
+    Cyg_Condition_Variable *joiner;             // joining threads wait here
+    CYG_ADDRWORD        stackmem;               // base of stack memory area
+                                                // only valid if freestack == true
+
+    struct pthread_cleanup_buffer *cancelbuffer; // stack of cleanup buffers
+
+#ifdef CYGPKG_POSIX_SIGNALS
+    sigset_t            sigpending;     // Set of pending signals
+    sigset_t            sigmask;        // Thread's signal mask
+#endif
+    
+    // The following is space for the eCos thread object that underlies
+    // this POSIX thread. It is allocated like this to avoid constructing
+    // it on startup.
+    cyg_uint8           thread_obj[sizeof(Cyg_Thread)];
+
+    // And the same for the joiner condition variable.
+    cyg_uint8           joiner_obj[sizeof(Cyg_Condition_Variable)];
+
+    // Per-thread data table pointer
+    void                **thread_data;
+    
+} pthread_info;
+
+
+// Values for the state field. These are solely concerned with the
+// states visible to POSIX. The thread's run state is stored in the
+// eCos thread object.
+// Note: numerical order here is important, do not rearrange.
+
+#define PTHREAD_STATE_FREE      0       // This structure is free for reuse
+#define PTHREAD_STATE_DETACHED  1       // The thread is running but detached
+#define PTHREAD_STATE_RUNNING   2       // The thread is running and will wait
+                                        // to join when it exits
+#define PTHREAD_STATE_JOIN      3       // The thread has exited and is waiting
+                                        // to be joined
+#define PTHREAD_STATE_EXITED    4       // The thread has exited and is ready to
+                                        // be reaped
+#endif // ifdef CYGPKG_POSIX_PTHREAD
+//-----------------------------------------------------------------------------
+// Internal definitions
+
+// Handle entry to a pthread package function. 
+#define PTHREAD_ENTRY() CYG_REPORT_FUNCTYPE( "returning %d" )
+
+// Handle entry to a pthread package function with no args. 
+#define PTHREAD_ENTRY_VOID() CYG_REPORT_FUNCTION()
+
+// Do a pthread package defined return. This requires the error code to be
+// returned as the result of the function. This also gives us a place to
+// put any generic tidyup handling needed for things like signal delivery
+// and cancellation.
+#define PTHREAD_RETURN(err)                     \
+CYG_MACRO_START                                 \
+    CYG_REPORT_RETVAL( err );                   \
+    return err;                                 \
+CYG_MACRO_END
+
+// A void variant of the above.
+#define PTHREAD_RETURN_VOID                     \
+CYG_MACRO_START                                 \
+    CYG_REPORT_RETURN();                        \
+    return;                                     \
+CYG_MACRO_END
+
+// Check that a pointer passed in as an argument is valid and return
+// EINVAL if it is not. This should be used to check pointers that are
+// required to be valid. Pointers that may optionally be NULL should
+// be checked within the function.
+#define PTHREAD_CHECK(ptr) if( (ptr) == NULL ) PTHREAD_RETURN(EINVAL);
+
+#ifdef CYGPKG_POSIX_PTHREAD
+# define PTHREAD_TESTCANCEL() pthread_testcancel()
+#else
+# define PTHREAD_TESTCANCEL()
+#endif
+
+//-----------------------------------------------------------------------------
+// Priority translation.
+// eCos priorities run from 0 as the highest to 31 as the lowest. POSIX priorities
+// run in the opposite direction. The following macros translate between the two
+// priority ranges.
+
+#define PTHREAD_ECOS_PRIORITY(pri) (CYG_THREAD_MIN_PRIORITY-(pri))
+
+#define PTHREAD_POSIX_PRIORITY(pri) (CYG_THREAD_MIN_PRIORITY-(pri))
+
+//-----------------------------------------------------------------------------
+// Global data structures
+
+// Mutex for locking access to pthread_info structures
+extern Cyg_Mutex pthread_mutex;
+
+//-----------------------------------------------------------------------------
+// Functions exported by pthread.cxx to the other parts of the POSIX subsystem.
+
+#ifdef CYGPKG_POSIX_PTHREAD
+externC void cyg_posix_pthread_start( void );
+
+externC pthread_info *pthread_self_info(void);
+
+externC pthread_info *pthread_info_id( pthread_t id );
+
+# ifdef CYGPKG_POSIX_SIGNALS
+externC void cyg_posix_pthread_release_thread( sigset_t *mask );
+# endif
+#endif
+
+//-----------------------------------------------------------------------------
+// Functions exported by signal.cxx to the other parts of the POSIX subsystem.
+
+#ifdef CYGPKG_POSIX_SIGNALS
+externC void cyg_posix_signal_start();
+
+externC void cyg_posix_signal_asr(pthread_info *self);
+
+externC cyg_bool cyg_sigqueue( const struct sigevent *sev, int code,
+                               pthread_info *thread = NULL );
+
+externC cyg_bool cyg_deliver_signals();
+
+externC void cyg_posix_signal_sigwait();
+
+externC void cyg_posix_thread_siginit( pthread_info *thread,
+                                       pthread_info *parentthread );
+
+externC void cyg_posix_thread_sigdestroy( pthread_info *thread );
+#endif
+
+//-----------------------------------------------------------------------------
+// Functions exported by time.cxx to other parts of the POSIX subsystem.
+
+#ifdef CYGPKG_POSIX_CLOCKS
+externC void cyg_posix_clock_start();
+
+externC cyg_tick_count cyg_timespec_to_ticks( const struct timespec *tp,
+                                         cyg_bool roundup = false);
+
+externC void cyg_ticks_to_timespec( cyg_tick_count ticks, struct timespec *tp );
+
+#endif
+
+#ifdef CYGPKG_POSIX_TIMERS
+
+externC void cyg_posix_timer_asr( pthread_info *self );
+
+#endif
+
+//-----------------------------------------------------------------------------
+// Functions exported by except.cxx
+
+#ifdef CYGPKG_POSIX_SIGNALS
+externC void cyg_posix_exception_start();
+
+externC void cyg_pthread_exception_init(pthread_info *thread);
+
+externC void cyg_pthread_exception_destroy(pthread_info *thread);
+#endif
+
+//-----------------------------------------------------------------------------
+#endif // ifndef CYGONCE_PPRIVATE_H
+// End of pprivate.h
diff --git a/packages/compat/posix/v2_0/src/pthread.cxx b/packages/compat/posix/v2_0/src/pthread.cxx
new file mode 100644 (file)
index 0000000..068cdf0
--- /dev/null
@@ -0,0 +1,1679 @@
+//==========================================================================
+//
+//      pthread.cxx
+//
+//      POSIX pthreads implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg, jlarmour
+// Date:                2000-03-27
+// Purpose:             POSIX pthread implementation
+// Description:         This file contains the implementation of the POSIX pthread
+//                      functions.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.h>
+#include <pkgconf/isoinfra.h>
+#include <pkgconf/libc_startup.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 "pprivate.h"                   // POSIX private header
+
+#include <stdlib.h>                     // malloc(), free()
+
+#include <cyg/kernel/sched.hxx>        // scheduler definitions
+#include <cyg/kernel/thread.hxx>       // thread definitions
+#include <cyg/kernel/clock.hxx>        // clock definitions
+
+#include <cyg/kernel/sched.inl>        // scheduler inlines
+
+//-----------------------------------------------------------------------------
+// First check that the configuration contains the elements we need
+
+#ifndef CYGPKG_KERNEL
+#error POSIX pthread need eCos kernel
+#endif
+
+#ifndef CYGSEM_KERNEL_SCHED_MLQUEUE
+#error POSIX pthreads need MLQ scheduler
+#endif
+
+#ifndef CYGSEM_KERNEL_SCHED_TIMESLICE
+#error POSIX pthreads need timeslicing
+#endif
+
+#ifndef CYGVAR_KERNEL_THREADS_DATA
+#error POSIX pthreads need per-thread data
+#endif
+
+//=============================================================================
+// Internal data structures
+
+// Mutex for controlling access to shared data structures
+Cyg_Mutex pthread_mutex CYGBLD_POSIX_INIT;
+
+// Array of pthread control structures. A pthread_t object is
+// "just" an index into this array.
+static pthread_info *thread_table[CYGNUM_POSIX_PTHREAD_THREADS_MAX];
+
+// Count of number of threads in table.
+static int pthread_count = 0;
+
+// Count of number of threads that have exited and not been reaped.
+static int pthreads_exited;
+
+// Count of number of threads that are waiting to be joined
+static int pthreads_tobejoined;
+
+// Per-thread key allocation. This key map has a 1 bit set for each
+// key that is free, zero if it is allocated.
+#define KEY_MAP_TYPE cyg_uint32
+#define KEY_MAP_TYPE_SIZE (sizeof(KEY_MAP_TYPE)*8) // in BITS!
+static KEY_MAP_TYPE thread_key[PTHREAD_KEYS_MAX/KEY_MAP_TYPE_SIZE];
+static void (*key_destructor[PTHREAD_KEYS_MAX]) (void *);
+    
+// Index of next pthread_info to allocate from thread_table array.
+static int thread_info_next = 0;
+
+// This is used to make pthread_t values unique even when reusing
+// a table slot. This allows CYGNUM_POSIX_PTHREAD_THREADS_MAX to range
+// up to 1024.
+#define THREAD_ID_COOKIE_INC 0x00000400
+#define THREAD_ID_COOKIE_MASK (THREAD_ID_COOKIE_INC-1)
+static pthread_t thread_id_cookie = THREAD_ID_COOKIE_INC;
+
+//-----------------------------------------------------------------------------
+// Main thread.
+
+#define MAIN_DEFAULT_STACK_SIZE \
+  (CYGNUM_LIBC_MAIN_DEFAULT_STACK_SIZE < PTHREAD_STACK_MIN \
+              ? PTHREAD_STACK_MIN : CYGNUM_LIBC_MAIN_DEFAULT_STACK_SIZE)
+
+static char main_stack[MAIN_DEFAULT_STACK_SIZE];
+
+// Thread ID of main thread.
+static pthread_t main_thread;
+
+//=============================================================================
+// Exported variables
+
+int pthread_canceled_dummy_var;           // pointed to by PTHREAD_CANCELED
+
+//=============================================================================
+// Internal functions
+
+//-----------------------------------------------------------------------------
+// Private version of pthread_self() that returns a pointer to our internal
+// control structure.
+
+pthread_info *pthread_self_info(void)
+{
+    Cyg_Thread *thread = Cyg_Thread::self();
+
+    CYG_CHECK_DATA_PTR(thread, "Illegal current thread");
+    
+    pthread_info *info = (pthread_info *)thread->get_data(CYGNUM_KERNEL_THREADS_DATA_POSIX);
+
+    // This assertion mustn't be enabled because sometimes we can legitimately
+    // carefully call this as long as we realise the value can be NULL.
+    // e.g. consider the use of this when inheriting sigmasks when in the
+    // context of creating the main() thread.
+//    CYG_CHECK_DATA_PTR(info, "Not a POSIX thread!!!");
+
+    return info;
+}
+
+externC pthread_info *pthread_info_id( pthread_t id )
+{
+    pthread_t index = id & THREAD_ID_COOKIE_MASK;
+
+    pthread_info *info = thread_table[index];
+
+    // Check for a valid entry
+    if( info == NULL )
+        return NULL;
+    
+    // Check that this is a valid entry
+    if ( info->state == PTHREAD_STATE_FREE ||
+         info->state == PTHREAD_STATE_EXITED )
+        return NULL;
+
+    // Check that the entry matches the id
+    if( info->id != id ) return NULL;
+
+    // Return the pointer
+    return info;
+}
+
+//-----------------------------------------------------------------------------
+// new operator to allow us to invoke the Cyg_Thread constructor on the
+// pthread_info.thread_obj array.
+
+inline void *operator new(size_t size,  cyg_uint8 *ptr) { return (void *)ptr; };
+
+//-----------------------------------------------------------------------------
+// Optional memory allocation functions for pthread stacks.
+// If there is an implementation of malloc() available, define pthread_malloc()
+// and pthread_free() to use it. Otherwise define them to do nothing.
+// In the future we may want to add configuration here to permit thread stacks
+// to be allocated in a nominated memory pool separate from the standard malloc()
+// pool. Hence the (currently redundant) encapsulation of these functions.
+
+#if CYGINT_ISO_MALLOC
+
+static __inline__ CYG_ADDRWORD pthread_malloc( CYG_ADDRWORD size )
+{
+    return (CYG_ADDRWORD)malloc( size );
+}
+
+static __inline__ void pthread_free( CYG_ADDRWORD m )
+{
+    free( (void *)m );
+}
+
+#define PTHREAD_MALLOC
+
+#else
+
+#define pthread_malloc(_x_) (0)
+
+#define pthread_free(_x_)
+
+#endif
+
+//-----------------------------------------------------------------------------
+// pthread entry function.
+// does some housekeeping and then calls the user's start routine.
+
+static void pthread_entry(CYG_ADDRWORD data)
+{
+    pthread_info *self = (pthread_info *)data;
+
+    void *retval = self->start_routine(self->start_arg);
+
+    pthread_exit( retval );
+}
+
+//-----------------------------------------------------------------------------
+// Main entry function.
+// This is set as the start_routine of the main thread. It invokes main()
+// and if it returns, shuts down the system.
+
+externC void cyg_libc_invoke_main( void );
+
+static void *call_main( void * )
+{
+    cyg_libc_invoke_main();
+    return NULL; // placate compiler
+}
+
+//-----------------------------------------------------------------------------
+// Check whether there is a cancel pending and if so, whether
+// cancellations are enabled. We do it in this order to reduce the
+// number of tests in the common case - when no cancellations are
+// pending.
+// We make this inline so it can be called directly below for speed
+
+static __inline__ int
+checkforcancel( void )
+{
+     pthread_info *self = pthread_self_info();
+
+    if( self != NULL &&
+        self->cancelpending &&
+        self->cancelstate == PTHREAD_CANCEL_ENABLE )
+        return 1;
+    else
+        return 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// POSIX ASR
+// This is installed as the ASR for all POSIX threads.
+
+static void posix_asr( CYG_ADDRWORD data )
+{
+    pthread_info *self = (pthread_info *)data;
+
+#ifdef CYGPKG_POSIX_TIMERS
+    // Call into timer subsystem to deliver any pending
+    // timer expirations.
+    cyg_posix_timer_asr(self);
+#endif
+    
+#ifdef CYGPKG_POSIX_SIGNALS
+    // Call signal subsystem to deliver any signals
+    cyg_posix_signal_asr(self);
+#endif
+    
+    // Check for cancellation
+    if( self->cancelpending &&
+        self->cancelstate == PTHREAD_CANCEL_ENABLE &&
+        self->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS )
+    {
+        // If we have a pending cancellation, cancellations are
+        // enabled and we are in asynchronous mode, then we can do the
+        // cancellation processing.  Since pthread_exit() does
+        // everything we need to do, we just call that here.
+        
+        pthread_exit(PTHREAD_CANCELED);
+    }
+}
+
+//-----------------------------------------------------------------------------
+// The (Grim) Reaper.
+// This function is called to tidy up and dispose of any threads that have
+// exited. This work must be done from a thread other than the one exiting.
+// Note: this function _must_ be called with pthread_mutex locked.
+
+static void pthread_reap()
+{
+    int i;
+
+    // Loop over the thread table looking for exited threads. The
+    // pthreads_exited counter springs us out of this once we have
+    // found them all (and keeps us out if there are none to do).
+   
+    for( i = 0; pthreads_exited && i < CYGNUM_POSIX_PTHREAD_THREADS_MAX ; i++ )
+    {
+        pthread_info *thread = thread_table[i];
+
+        if( thread != NULL && thread->state == PTHREAD_STATE_EXITED )
+        {
+            // The thread has exited, so it is a candidate for being
+            // reaped. We have to make sure that the eCos thread has
+            // also reached EXITED state before we can tidy it up.
+
+            while( thread->thread->get_state() != Cyg_Thread::EXITED )
+            {
+                // The eCos thread has not yet exited. This is
+                // probably because its priority is too low to allow
+                // it to complete.  We fix this here by raising its
+                // priority to equal ours and then yielding. This
+                // should eventually get it into exited state.
+
+                Cyg_Thread *self = Cyg_Thread::self();
+
+                // Set thread's priority to our current dispatching priority.
+                thread->thread->set_priority( self->get_current_priority() );
+
+                // Yield, yield
+                self->yield();
+    
+                // and keep looping until he exits.
+            }
+
+            // At this point we have a thread that we can reap.
+
+            // destroy the eCos thread
+            thread->thread->~Cyg_Thread();
+
+            // destroy the joiner condvar
+            thread->joiner->~Cyg_Condition_Variable();
+
+#ifdef CYGPKG_POSIX_SIGNALS
+            // Destroy signal handling fields
+            cyg_posix_thread_sigdestroy( thread );
+#endif
+            
+            // Free the stack if we allocated it
+            if( thread->freestack )
+                pthread_free( thread->stackmem );
+
+            // Finally, set the thread table entry to NULL so that it
+            // may be reused.
+            thread_table[i] = NULL;
+
+            pthread_count--;
+            pthreads_exited--;
+        }
+    }
+}
+
+//=============================================================================
+// Functions exported to rest of POSIX subsystem.
+
+//-----------------------------------------------------------------------------
+// Create the main() thread.
+
+externC void cyg_posix_pthread_start( void )
+{
+
+    // Initialize the per-thread data key map.
+
+    for( cyg_ucount32 i = 0; i < (PTHREAD_KEYS_MAX/KEY_MAP_TYPE_SIZE); i++ )
+    {
+        thread_key[i] = ~0;
+    }
+    
+    // Create the main thread
+    pthread_attr_t attr;
+    struct sched_param schedparam;
+
+    schedparam.sched_priority = CYGNUM_POSIX_MAIN_DEFAULT_PRIORITY;
+
+    pthread_attr_init( &attr );
+    pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+    pthread_attr_setstackaddr( &attr, &main_stack[sizeof(main_stack)] );
+    pthread_attr_setstacksize( &attr, sizeof(main_stack) );
+    pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    pthread_create( &main_thread, &attr, call_main, NULL );    
+}
+
+#ifdef CYGPKG_POSIX_SIGNALS
+//-----------------------------------------------------------------------------
+// Look for a thread that can accept delivery of any of the signals in
+// the mask and release it from any wait it is in.  Since this may be
+// called from a DSR, it cannot use any locks internally - any locking
+// should be done before the call.
+
+externC void cyg_posix_pthread_release_thread( sigset_t *mask )
+{
+    int i;
+    int count = pthread_count;
+    
+    // Loop over the thread table looking for a thread that has a
+    // signal mask that does not mask all the signals in mask.
+    // FIXME: find a more efficient way of doing this.
+    
+    for( i = 0; count > 0 && i < CYGNUM_POSIX_PTHREAD_THREADS_MAX ; i++ )
+    {
+        pthread_info *thread = thread_table[i];
+
+        if( (thread != NULL) &&
+            (thread->state <= PTHREAD_STATE_RUNNING) &&
+            ((*mask & ~thread->sigmask) != 0) )
+        {
+            // This thread can service at least one of the signals in
+            // *mask. Knock it out of its wait and make its ASR pending.
+
+            thread->thread->set_asr_pending();
+            thread->thread->release();
+            break;
+        }
+
+        // Decrement count for each valid thread we find.
+        if( thread != NULL && thread->state != PTHREAD_STATE_FREE )
+            count--;
+    }
+}
+#endif
+
+//=============================================================================
+// General thread operations
+
+//-----------------------------------------------------------------------------
+// Thread creation and management.
+
+// Create a thread.
+externC int pthread_create ( pthread_t *thread,
+                             const pthread_attr_t *attr,
+                             void *(*start_routine) (void *),
+                             void *arg)
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK(thread);
+    PTHREAD_CHECK(start_routine);
+
+    pthread_info *self = pthread_self_info();
+    
+    pthread_attr_t use_attr;
+
+    // Set use_attr to the set of attributes we are going to
+    // actually use. Either those passed in, or the default set.
+   
+    if( attr == NULL )
+        pthread_attr_init( &use_attr );
+    else use_attr = *attr;
+
+    // Adjust the attributes to cope with the setting of inheritsched.
+
+    if( use_attr.inheritsched == PTHREAD_INHERIT_SCHED )
+    {
+        CYG_ASSERT( NULL != self,
+                    "Attempt to inherit sched policy from non-POSIX thread" );
+#ifdef CYGDBG_USE_ASSERTS
+        // paranoia check
+        int i;
+        for (i=(sizeof(thread_table)/sizeof(*thread_table))-1; i>=0; i--) {
+            if (thread_table[i] == self)
+                break;
+        }
+        CYG_ASSERT( i>=0, "Current pthread not found in table" );
+#endif
+        use_attr.schedpolicy = self->attr.schedpolicy;
+        use_attr.schedparam  = self->attr.schedparam;
+    }
+
+    CYG_ADDRWORD stackbase, stacksize;
+    cyg_bool freestack = false;
+    CYG_ADDRWORD stackmem = 0;
+    
+    // If the stack size is not valid, we can assume that it is at
+    // least PTHREAD_STACK_MIN bytes.
+        
+    if( use_attr.stacksize_valid )
+        stacksize = use_attr.stacksize;
+    else stacksize = PTHREAD_STACK_MIN;
+
+    if( use_attr.stackaddr_valid )
+    {
+        // Set up stack base and size from supplied arguments.
+
+        // Calculate stack base from address and size.
+        // FIXME: Falling stack assumed in pthread_create().
+        stackmem = stackbase = (CYG_ADDRWORD)use_attr.stackaddr-stacksize;
+    }
+    else
+    {
+#ifdef PTHREAD_MALLOC
+
+        stackmem = stackbase = pthread_malloc( stacksize );
+
+        if( stackmem == 0 )
+            PTHREAD_RETURN( EAGAIN );
+
+        freestack = true;
+#else        
+        PTHREAD_RETURN(EINVAL);
+#endif        
+        
+    }
+
+    // Get sole access to data structures
+    
+    pthread_mutex.lock();
+    
+    // Dispose of any dead threads
+    pthread_reap();
+    
+    // Find a free slot in the thread table
+    
+    pthread_info *nthread;
+    int thread_next = thread_info_next;
+    
+    while( thread_table[thread_next] != NULL )
+    {
+        thread_next++;
+        if( thread_next >= CYGNUM_POSIX_PTHREAD_THREADS_MAX )
+            thread_next = 0;
+
+        // check for wrap, and return error if no slots left
+        if( thread_next == thread_info_next )
+        {
+            pthread_mutex.unlock();
+            if( freestack )
+                pthread_free( stackmem );
+            PTHREAD_RETURN(ENOMEM);
+        }
+    }
+
+    nthread = (pthread_info *)stackbase;
+
+    stackbase += sizeof(pthread_info);
+    stacksize -= sizeof(pthread_info);
+    
+    thread_table[thread_next] = nthread;
+
+    // Set new next index
+    thread_info_next = thread_next;
+    
+    // step the cookie
+    thread_id_cookie += THREAD_ID_COOKIE_INC;
+
+    // Initialize the table entry
+    nthread->state              = use_attr.detachstate == PTHREAD_CREATE_JOINABLE ?
+                                  PTHREAD_STATE_RUNNING : PTHREAD_STATE_DETACHED;
+    nthread->id                 = thread_next+thread_id_cookie;
+    nthread->attr               = use_attr;
+    nthread->retval             = 0;
+    nthread->start_routine      = start_routine;
+    nthread->start_arg          = arg;
+
+    nthread->freestack          = freestack;
+    nthread->stackmem           = stackmem;
+    
+    nthread->cancelstate        = PTHREAD_CANCEL_ENABLE;
+    nthread->canceltype         = PTHREAD_CANCEL_DEFERRED;
+    nthread->cancelbuffer       = NULL;
+    nthread->cancelpending      = false;
+
+    nthread->thread_data        = NULL;
+    
+#ifdef CYGVAR_KERNEL_THREADS_NAME    
+    // generate a name for this thread
+
+    char *name = nthread->name;
+    static char *name_template = "pthread.00000000";
+    pthread_t id = nthread->id;
+    
+    for( int i = 0; name_template[i]; i++ ) name[i] = name_template[i];
+
+    // dump the id, in hex into the name.
+    for( int i = 15; i >= 8; i-- )
+    {
+        name[i] = "0123456789ABCDEF"[id&0xF];
+        id >>= 4;
+    }
+
+#endif
+
+    // Initialize the joiner condition variable
+
+    nthread->joiner = new(nthread->joiner_obj) Cyg_Condition_Variable( pthread_mutex );
+
+#ifdef CYGPKG_POSIX_SIGNALS
+    // Initialize signal specific fields.
+    if (NULL != self) {
+        CYG_CHECK_DATA_PTR( self,
+                            "Attempt to inherit signal mask from bogus pthread" );
+#ifdef CYGDBG_USE_ASSERTS
+        // paranoia check
+        int i;
+        for (i=(sizeof(thread_table)/sizeof(*thread_table))-1; i>=0; i--) {
+            if (thread_table[i] == self)
+                break;
+        }
+        CYG_ASSERT( i>=0, "Current pthread not found in table" );
+#endif
+    }
+    cyg_posix_thread_siginit( nthread, self );
+#endif
+
+    // create the underlying eCos thread
+
+    nthread->thread = new(&nthread->thread_obj[0])
+        Cyg_Thread ( PTHREAD_ECOS_PRIORITY(use_attr.schedparam.sched_priority),
+                     pthread_entry,
+                     (CYG_ADDRWORD)nthread,
+                     name,
+                     stackbase,
+                     stacksize);
+
+    // Put pointer to pthread_info into eCos thread's per-thread data.
+    nthread->thread->set_data( CYGNUM_KERNEL_THREADS_DATA_POSIX, (CYG_ADDRWORD)nthread );
+
+    // Set timeslice enable according to scheduling policy.
+    if( use_attr.schedpolicy == SCHED_FIFO )
+         nthread->thread->timeslice_disable();
+    else nthread->thread->timeslice_enable();
+
+    // set up ASR and data
+    nthread->thread->set_asr( posix_asr, (CYG_ADDRWORD)nthread, NULL, NULL );    
+    
+    // return thread ID
+    *thread = nthread->id;
+
+    pthread_count++;
+                
+    pthread_mutex.unlock();
+
+    // finally, set the thread going
+    nthread->thread->resume();
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Get current thread id.
+
+externC pthread_t pthread_self ( void )
+{
+    PTHREAD_ENTRY();
+    
+    pthread_info *info = pthread_self_info();
+
+    CYG_CHECK_DATA_PTR(info, "Not a POSIX thread!!!");
+    
+    return info->id;
+}
+
+//-----------------------------------------------------------------------------
+// Compare two thread identifiers.
+
+externC int pthread_equal (pthread_t thread1, pthread_t thread2)
+{
+    PTHREAD_ENTRY();
+    
+    return thread1 == thread2;
+}
+
+//-----------------------------------------------------------------------------
+// Terminate current thread.
+
+externC void exit(int) CYGBLD_ATTRIB_NORET;
+
+externC void pthread_exit (void *retval)
+{
+    PTHREAD_ENTRY();
+    
+    pthread_info *self = pthread_self_info();
+
+    // Disable cancellation requests for this thread.  If cleanup
+    // handlers exist, they will generally be issuing system calls
+    // to clean up resources.  We want these system calls to run
+    // without cancelling, and we also want to prevent being
+    // re-cancelled.
+    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+    // Call cancellation handlers. We eat up the buffers as we go in
+    // case any of the routines calls pthread_exit() itself.
+    while( self->cancelbuffer != NULL )
+    {
+        struct pthread_cleanup_buffer *buffer = self->cancelbuffer;
+
+        self->cancelbuffer = buffer->prev;
+
+        buffer->routine(buffer->arg);
+    }
+
+    if( self->thread_data != NULL )
+    {
+        // Call per-thread key destructors.
+        // The specification of this is that we must continue to call the
+        // destructor functions until all the per-thread data values are NULL or
+        // we have done it PTHREAD_DESTRUCTOR_ITERATIONS times.
+    
+        cyg_bool destructors_called;
+        int destructor_iterations = 0;
+
+        do
+        {
+            destructors_called = false;
+        
+            for( cyg_ucount32 key = 0; key < PTHREAD_KEYS_MAX; key++ )
+            {
+                // Skip unallocated keys
+                if( thread_key[key/KEY_MAP_TYPE_SIZE] & 1<<(key%KEY_MAP_TYPE_SIZE) )
+                    continue;
+
+                // Skip NULL destructors
+                if( key_destructor[key] == NULL ) continue;
+
+                // Skip NULL data values
+                if( self->thread_data[key] == NULL ) continue;
+
+                // If it passes all that, call the destructor.
+               // Note that NULLing the data value here is new
+               // behaviour in the 2001 POSIX standard.
+                {
+                    void* value = self->thread_data[key];
+                    self->thread_data[key] = NULL;
+                    key_destructor[key](value);
+                }
+
+                // Record that we called a destructor
+                destructors_called = true;
+            }
+
+            // Count the iteration
+            destructor_iterations++;
+        
+        } while( destructors_called &&
+                 (destructor_iterations <= PTHREAD_DESTRUCTOR_ITERATIONS));
+
+    }
+    
+    pthread_mutex.lock();
+
+    // Set the retval for any joiner
+    self->retval = retval;
+
+    // If we are already detached, go to EXITED state, otherwise
+    // go into JOIN state.
+    
+    if ( PTHREAD_STATE_DETACHED == self->state ) {
+        self->state = PTHREAD_STATE_EXITED;
+        pthreads_exited++;
+    } else {
+        self->state = PTHREAD_STATE_JOIN;
+        pthreads_tobejoined++;
+    }
+
+    // Kick any waiting joiners
+    self->joiner->broadcast();
+
+    cyg_bool call_exit=false;
+
+    // if this is the last thread (other than threads waiting to be joined)
+    // then we need to call exit() later
+    if ( pthreads_exited + pthreads_tobejoined == pthread_count )
+        call_exit=true;
+
+    pthread_mutex.unlock();
+    
+    // Finally, call the exit function; this will not return.
+    if ( call_exit )
+        ::exit(0);
+    else
+        self->thread->exit();
+
+    // This loop keeps some compilers happy. pthread_exit() is marked
+    // with the noreturn attribute, and without this they generate a
+    // call to abort() here in case Cyg_Thread::exit() returns. 
+    
+    for(;;) continue;
+}
+
+//-----------------------------------------------------------------------------
+// Wait for the thread to terminate. If thread_return is not NULL then
+// the retval from the thread's call to pthread_exit() is stored at
+// *thread_return.
+
+externC int pthread_join (pthread_t thread, void **thread_return)
+{
+    int err = 0;
+
+    PTHREAD_ENTRY();
+    
+    // check for cancellation first.
+    pthread_testcancel();
+
+    pthread_mutex.lock();
+    
+    // Dispose of any dead threads
+    pthread_reap();
+    
+    pthread_info *self = pthread_self_info();
+    pthread_info *joinee = pthread_info_id( thread );
+
+    if( joinee == NULL )
+    {
+        err = ESRCH;
+    }
+
+    if( !err && joinee == self )
+    {
+        err = EDEADLK;
+    }
+
+    if ( !err ) {
+        switch ( joinee->state )
+        {
+        case PTHREAD_STATE_RUNNING:
+            // The thread is still running, we must wait for it.
+        while( joinee->state == PTHREAD_STATE_RUNNING ) {
+            if ( !joinee->joiner->wait() )
+                // check if we were woken because we were being cancelled
+                if ( checkforcancel() ) {
+                    err = EAGAIN;  // value unimportant, just some error
+                    break;
+                }
+        }
+
+        // check that the thread is still joinable
+        if( joinee->state == PTHREAD_STATE_JOIN )
+            break;
+
+        // The thread has become unjoinable while we waited, so we
+        // fall through to complain.
+        
+        case PTHREAD_STATE_FREE:
+        case PTHREAD_STATE_DETACHED:
+        case PTHREAD_STATE_EXITED:
+        // None of these may be joined.
+            err = EINVAL;
+            break;
+            
+        case PTHREAD_STATE_JOIN:
+            break;
+        }
+    }
+
+    if ( !err ) {
+    
+        // here, we know that joinee is a thread that has exited and is
+        // ready to be joined.
+
+        // Get the retval
+        if( thread_return != NULL )
+            *thread_return = joinee->retval;
+        
+        // set state to exited.
+        joinee->state = PTHREAD_STATE_EXITED;
+        pthreads_exited++;
+        pthreads_tobejoined--;
+    
+        // Dispose of any dead threads
+        pthread_reap();
+    }
+
+    pthread_mutex.unlock();
+    
+    // check for cancellation before returning
+    pthread_testcancel();
+
+    PTHREAD_RETURN(err);
+}
+
+//-----------------------------------------------------------------------------
+// Set the detachstate of the thread to "detached". The thread then does not
+// need to be joined and its resources will be freed when it exits.
+
+externC int pthread_detach (pthread_t thread)
+{
+    PTHREAD_ENTRY();
+    
+    int ret = 0;
+    
+    pthread_mutex.lock();
+
+    pthread_info *detachee = pthread_info_id( thread );
+    
+    if( detachee == NULL )
+        ret = ESRCH;                    // No such thread
+    else if( detachee->state == PTHREAD_STATE_DETACHED )
+        ret = EINVAL;                   // Already detached!
+    else
+    {
+        // Set state to detached and kick any joinees to
+        // make them return.
+        detachee->state = PTHREAD_STATE_DETACHED;
+        detachee->joiner->broadcast();
+    }
+    
+    // Dispose of any dead threads
+    pthread_reap();
+    
+    pthread_mutex.unlock();
+
+    PTHREAD_RETURN(ret);
+}
+
+
+//-----------------------------------------------------------------------------
+// Thread attribute handling.
+
+//-----------------------------------------------------------------------------
+// Initialize attributes object with default attributes:
+// detachstate          == PTHREAD_CREATE_JOINABLE
+// scope                == PTHREAD_SCOPE_SYSTEM
+// inheritsched         == PTHREAD_INHERIT_SCHED
+// schedpolicy          == SCHED_OTHER
+// schedparam           == unset
+// stackaddr            == unset
+// stacksize            == 0
+// 
+
+externC int pthread_attr_init (pthread_attr_t *attr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+    
+    attr->detachstate                 = PTHREAD_CREATE_JOINABLE;
+    attr->scope                       = PTHREAD_SCOPE_SYSTEM;
+    attr->inheritsched                = PTHREAD_INHERIT_SCHED;
+    attr->schedpolicy                 = SCHED_OTHER;
+    attr->schedparam.sched_priority   = 0;
+    attr->stackaddr_valid             = 0;    
+    attr->stackaddr                   = NULL;
+    attr->stacksize_valid             = 0;    
+    attr->stacksize                   = 0;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Destroy thread attributes object
+
+externC int pthread_attr_destroy (pthread_attr_t *attr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    // Nothing to do here...
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Set the detachstate attribute
+
+externC int pthread_attr_setdetachstate (pthread_attr_t *attr,
+                                         int detachstate)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( detachstate == PTHREAD_CREATE_JOINABLE ||
+        detachstate == PTHREAD_CREATE_DETACHED )
+    {
+        attr->detachstate = detachstate;
+        PTHREAD_RETURN(0);
+    }
+    
+    PTHREAD_RETURN(EINVAL);
+}
+
+//-----------------------------------------------------------------------------
+// Get the detachstate attribute
+externC int pthread_attr_getdetachstate (const pthread_attr_t *attr,
+                                         int *detachstate)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( detachstate != NULL )
+        *detachstate = attr->detachstate;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Set scheduling contention scope
+
+externC int pthread_attr_setscope (pthread_attr_t *attr, int scope)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( scope == PTHREAD_SCOPE_SYSTEM ||
+        scope == PTHREAD_SCOPE_PROCESS )
+    {
+        if( scope == PTHREAD_SCOPE_PROCESS )
+            PTHREAD_RETURN(ENOTSUP);
+
+        attr->scope = scope;
+
+        PTHREAD_RETURN(0);
+    }
+    
+    PTHREAD_RETURN(EINVAL);
+}
+
+//-----------------------------------------------------------------------------
+// Get scheduling contention scope
+
+externC int pthread_attr_getscope (const pthread_attr_t *attr, int *scope)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( scope != NULL )
+        *scope = attr->scope;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Set scheduling inheritance attribute
+
+externC int pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( inherit == PTHREAD_INHERIT_SCHED ||
+        inherit == PTHREAD_EXPLICIT_SCHED )
+    {
+        attr->inheritsched = inherit;
+
+        PTHREAD_RETURN(0);
+    }
+
+    PTHREAD_RETURN(EINVAL);
+}
+
+//-----------------------------------------------------------------------------
+// Get scheduling inheritance attribute
+
+externC int pthread_attr_getinheritsched (const pthread_attr_t *attr,
+                                          int *inherit)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( inherit != NULL )
+        *inherit = attr->inheritsched;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Set scheduling policy
+
+externC int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( policy == SCHED_OTHER ||
+        policy == SCHED_FIFO ||
+        policy == SCHED_RR )
+    {
+        attr->schedpolicy = policy;
+
+        PTHREAD_RETURN(0);
+    }
+    
+    PTHREAD_RETURN(EINVAL);
+}
+
+//-----------------------------------------------------------------------------
+// Get scheduling policy
+
+externC int pthread_attr_getschedpolicy (const pthread_attr_t *attr,
+                                         int *policy)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( policy != NULL )
+        *policy = attr->schedpolicy;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Set scheduling parameters
+externC int pthread_attr_setschedparam (pthread_attr_t *attr,
+                                       const struct sched_param *param)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+    PTHREAD_CHECK(param);
+
+    attr->schedparam = *param;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Get scheduling parameters
+
+externC int pthread_attr_getschedparam (const pthread_attr_t *attr,
+                                        struct sched_param *param)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( param != NULL )
+        *param = attr->schedparam;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Set starting address of stack. Whether this is at the start or end of
+// the memory block allocated for the stack depends on whether the stack
+// grows up or down.
+
+externC int pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    attr->stackaddr       = stackaddr;
+    attr->stackaddr_valid = 1;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Get any previously set stack address.
+
+externC int pthread_attr_getstackaddr (const pthread_attr_t *attr,
+                                       void **stackaddr)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    if( stackaddr != NULL )
+    {
+        if( attr->stackaddr_valid )
+        {
+            *stackaddr = attr->stackaddr;
+            PTHREAD_RETURN(0);
+        }
+        // Stack address not set, return EINVAL.
+        else PTHREAD_RETURN(EINVAL);
+    }
+
+    PTHREAD_RETURN(0);
+}
+
+
+//-----------------------------------------------------------------------------
+// Set minimum creation stack size.
+
+externC int pthread_attr_setstacksize (pthread_attr_t *attr,
+                                       size_t stacksize)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    CYG_ASSERT( stacksize >= PTHREAD_STACK_MIN, "Inadequate stack size supplied");
+    
+    // Reject inadequate stack sizes
+    if( stacksize < PTHREAD_STACK_MIN )
+        PTHREAD_RETURN(EINVAL);
+        
+    attr->stacksize_valid = 1;    
+    attr->stacksize = stacksize;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Get current minimal stack size.
+
+externC int pthread_attr_getstacksize (const pthread_attr_t *attr,
+                                       size_t *stacksize)
+{
+    PTHREAD_ENTRY();
+    
+    PTHREAD_CHECK(attr);
+
+    // Reject attempts to get a stack size when one has not been set.
+    if( !attr->stacksize_valid )
+        PTHREAD_RETURN(EINVAL);
+    
+    if( stacksize != NULL )
+        *stacksize = attr->stacksize;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Thread scheduling controls
+
+//-----------------------------------------------------------------------------
+// Set scheduling policy and parameters for the thread
+
+externC int pthread_setschedparam (pthread_t thread_id,
+                                   int policy,
+                                   const struct sched_param *param)
+{
+    PTHREAD_ENTRY();
+
+    if( policy != SCHED_OTHER &&
+        policy != SCHED_FIFO &&
+        policy != SCHED_RR )
+        PTHREAD_RETURN(EINVAL);
+
+    PTHREAD_CHECK(param);
+
+    // The parameters seem OK, change the thread...
+    
+    pthread_mutex.lock();
+
+    pthread_info *thread = pthread_info_id( thread_id );
+
+    if( thread == NULL )
+    {
+        pthread_mutex.unlock();
+        PTHREAD_RETURN(ESRCH);
+    }
+    
+    thread->attr.schedpolicy = policy;
+    thread->attr.schedparam = *param;
+
+    if ( policy == SCHED_FIFO )
+         thread->thread->timeslice_disable();
+    else thread->thread->timeslice_enable();
+
+    thread->thread->set_priority( PTHREAD_ECOS_PRIORITY( param->sched_priority ));
+
+    pthread_mutex.unlock();
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Get scheduling policy and parameters for the thread
+
+externC int pthread_getschedparam (pthread_t thread_id,
+                                   int *policy,
+                                   struct sched_param *param)
+{
+    PTHREAD_ENTRY();
+
+    pthread_mutex.lock();
+
+    pthread_info *thread = pthread_info_id( thread_id );
+
+    if( thread == NULL )
+    {
+        pthread_mutex.unlock();
+        PTHREAD_RETURN(ESRCH);
+    }
+
+    if( policy != NULL )
+        *policy = thread->attr.schedpolicy;
+
+    if( param != NULL )
+        *param = thread->attr.schedparam;
+    
+    pthread_mutex.unlock();
+    
+    PTHREAD_RETURN(0);
+}
+
+
+//=============================================================================
+// Dynamic package initialization
+// Call init_routine just the once per control variable.
+
+externC int pthread_once (pthread_once_t *once_control,
+                          void (*init_routine) (void))
+{
+    PTHREAD_ENTRY();
+
+    PTHREAD_CHECK( once_control );
+    PTHREAD_CHECK( init_routine );
+
+    pthread_once_t old;
+
+    // Do a test and set on the once_control object.
+    pthread_mutex.lock();
+
+    old = *once_control;
+    *once_control = 1;
+
+    pthread_mutex.unlock();
+
+    // If the once_control was zero, call the init_routine().
+    if( !old ) init_routine();
+    
+    PTHREAD_RETURN(0);
+}
+
+
+//=============================================================================
+//Thread specific data
+
+//-----------------------------------------------------------------------------
+// Create a key to identify a location in the thread specific data area.
+// Each thread has its own distinct thread-specific data area but all are
+// addressed by the same keys. The destructor function is called whenever a
+// thread exits and the value associated with the key is non-NULL.
+
+externC int pthread_key_create (pthread_key_t *key,
+                                void (*destructor) (void *))
+{
+    PTHREAD_ENTRY();
+
+    pthread_key_t k = -1;
+    
+    pthread_mutex.lock();
+
+    // Find a key to allocate
+    for( cyg_ucount32 i = 0; i < (PTHREAD_KEYS_MAX/KEY_MAP_TYPE_SIZE); i++ )
+    {
+        if( thread_key[i] != 0 )
+        {
+            // We have a table slot with space available
+
+            // Get index of ls set bit.
+            HAL_LSBIT_INDEX( k, thread_key[i] );
+
+            // clear it
+            thread_key[i] &= ~(1<<k);
+
+            // Add index of word
+            k += i * KEY_MAP_TYPE_SIZE;
+
+            // Install destructor
+            key_destructor[k] = destructor;
+            
+            // break out with key found
+            break;
+        }
+    }
+
+    if( k != -1 )
+    {
+        // plant a NULL in all the valid thread data slots for this
+        // key in case we are reusing a key we used before.
+        
+        for( cyg_ucount32 i = 0; i < CYGNUM_POSIX_PTHREAD_THREADS_MAX ; i++ )
+        {
+            pthread_info *thread = thread_table[i];
+
+            if( thread != NULL && thread->thread_data != NULL )
+                thread->thread_data[k] = NULL;
+        }
+    }
+    
+    pthread_mutex.unlock();    
+
+    if( k == -1 ) PTHREAD_RETURN(EAGAIN);
+
+    *key = k;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Delete key.
+
+externC int pthread_key_delete (pthread_key_t key)
+{
+    PTHREAD_ENTRY();
+
+    pthread_mutex.lock();
+
+    // Set the key bit to 1 to indicate it is free.
+    thread_key[key/KEY_MAP_TYPE_SIZE] |= 1<<(key%(KEY_MAP_TYPE_SIZE));
+
+    pthread_mutex.unlock();        
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Store the pointer value in the thread-specific data slot addressed
+// by the key.
+
+externC int pthread_setspecific (pthread_key_t key, const void *pointer)
+{
+    PTHREAD_ENTRY();
+
+    if( thread_key[key/KEY_MAP_TYPE_SIZE] & 1<<(key%KEY_MAP_TYPE_SIZE) )
+        PTHREAD_RETURN(EINVAL);
+
+    pthread_info *self = pthread_self_info();
+
+    if( self->thread_data == NULL )
+    {
+        // Allocate the per-thread data table
+        self->thread_data =
+            (void **)self->thread->increment_stack_limit(
+                PTHREAD_KEYS_MAX * sizeof(void *) );
+
+        // Clear out all entries
+        for( int i  = 0; i < PTHREAD_KEYS_MAX; i++ )
+            self->thread_data[i] = NULL;
+    }
+    
+    self->thread_data[key] = (void *)pointer;
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Retrieve the pointer value in the thread-specific data slot addressed
+// by the key.
+
+externC void *pthread_getspecific (pthread_key_t key)
+{
+    void *val;
+    PTHREAD_ENTRY();
+
+    if( thread_key[key/KEY_MAP_TYPE_SIZE] & 1<<(key%KEY_MAP_TYPE_SIZE) )
+        PTHREAD_RETURN(NULL);
+
+    pthread_info *self = pthread_self_info();
+
+    if( self->thread_data == NULL )
+        val = NULL;
+    else val = self->thread_data[key];
+
+    PTHREAD_RETURN(val);
+}
+
+//=============================================================================
+// Thread Cancellation Functions
+
+//-----------------------------------------------------------------------------
+// Set cancel state of current thread to ENABLE or DISABLE.
+// Returns old state in *oldstate.
+
+externC int pthread_setcancelstate (int state, int *oldstate)
+{
+    PTHREAD_ENTRY();
+
+    if( state != PTHREAD_CANCEL_ENABLE &&
+        state != PTHREAD_CANCEL_DISABLE )
+        PTHREAD_RETURN(EINVAL);
+    
+    pthread_mutex.lock();
+
+    pthread_info *self = pthread_self_info();
+
+    if( oldstate != NULL ) *oldstate = self->cancelstate;
+    
+    self->cancelstate = state;
+    
+    pthread_mutex.unlock();
+    
+    // Note: This function may have made it possible for a pending
+    // cancellation to now be delivered. However the standard does not
+    // list this function as a cancellation point, so for now we do
+    // nothing. In future we might call pthread_testcancel() here.
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Set cancel type of current thread to ASYNCHRONOUS or DEFERRED.
+// Returns old type in *oldtype.
+
+externC int pthread_setcanceltype (int type, int *oldtype)
+{
+    PTHREAD_ENTRY();
+
+    if( type != PTHREAD_CANCEL_ASYNCHRONOUS &&
+        type != PTHREAD_CANCEL_DEFERRED )
+        PTHREAD_RETURN(EINVAL);
+    
+    pthread_mutex.lock();
+
+    pthread_info *self = pthread_self_info();
+        
+    if( oldtype != NULL ) *oldtype = self->canceltype;
+
+    self->canceltype = type;
+    
+    pthread_mutex.unlock();   
+
+    // Note: This function may have made it possible for a pending
+    // cancellation to now be delivered. However the standard does not
+    // list this function as a cancellation point, so for now we do
+    // nothing. In future we might call pthread_testcancel() here.
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Cancel the thread.
+
+externC int pthread_cancel (pthread_t thread)
+{
+    PTHREAD_ENTRY();
+
+    pthread_mutex.lock();
+
+    pthread_info *th = pthread_info_id(thread);
+
+    if( th == NULL )
+    {
+        pthread_mutex.unlock();
+        PTHREAD_RETURN(ESRCH);
+    }
+
+    th->cancelpending = true;
+
+    if ( th->cancelstate == PTHREAD_CANCEL_ENABLE )
+    {
+        if ( th->canceltype == PTHREAD_CANCEL_ASYNCHRONOUS )
+        {
+            // If the thread has cancellation enabled, and it is in
+            // asynchronous mode, set the eCos thread's ASR pending to
+            // deal with it when the thread wakes up. We also release the
+            // thread out of any current wait to make it wake up.
+        
+            th->thread->set_asr_pending();
+            th->thread->release();
+        }
+        else if ( th->canceltype == PTHREAD_CANCEL_DEFERRED )
+        {
+            // If the thread has cancellation enabled, and it is in 
+            // deferred mode, wake the thread up so that cancellation
+            // points can test for cancellation.
+            th->thread->release();
+        }
+        else
+            CYG_FAIL("Unknown cancellation type");
+    }
+
+    // Otherwise the thread has cancellation disabled, in which case
+    // it is up to the thread to enable cancellation
+    
+    pthread_mutex.unlock();   
+   
+    
+    PTHREAD_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Test for a pending cancellation for the current thread and terminate
+// the thread if there is one.
+
+externC void pthread_testcancel (void)
+{
+    PTHREAD_ENTRY_VOID();
+
+    if( checkforcancel() )
+    {
+        // If we have cancellation enabled, and there is a cancellation
+        // pending, then go ahead and do the deed. 
+        
+        // Exit now with special retval. pthread_exit() calls the
+        // cancellation handlers implicitly.
+        pthread_exit(PTHREAD_CANCELED);
+    }
+        
+    PTHREAD_RETURN_VOID;
+}
+
+//-----------------------------------------------------------------------------
+// These two functions actually implement the cleanup push and pop functionality.
+
+externC void pthread_cleanup_push_inner (struct pthread_cleanup_buffer *buffer,
+                                         void (*routine) (void *),
+                                         void *arg)
+{
+    PTHREAD_ENTRY();
+
+    pthread_info *self = pthread_self_info();
+
+    buffer->routine     = routine;
+    buffer->arg         = arg;
+    
+    buffer->prev        = self->cancelbuffer;
+
+    self->cancelbuffer  = buffer;
+
+    return;
+}
+
+externC void pthread_cleanup_pop_inner (struct pthread_cleanup_buffer *buffer,
+                                        int execute)
+{
+    PTHREAD_ENTRY();
+
+    pthread_info *self = pthread_self_info();
+    
+    CYG_ASSERT( self->cancelbuffer == buffer, "Stacking error in cleanup buffers");
+    
+    if( self->cancelbuffer == buffer )
+    {
+        // Remove the buffer from the stack
+        self->cancelbuffer = buffer->prev;
+    }
+    else
+    {
+        // If the top of the stack is not the buffer we expect, do not
+        // execute it.
+        execute = 0;
+    }
+
+    if( execute ) buffer->routine(buffer->arg);
+    
+    return;
+}
+
+
+// -------------------------------------------------------------------------
+// eCos-specific function to measure stack usage of the supplied thread
+
+#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
+externC size_t pthread_measure_stack_usage (pthread_t thread)
+{
+    pthread_info *th = pthread_info_id(thread);
+
+    if ( NULL == th )
+      return (size_t)-1;
+
+    return (size_t)th->thread->measure_stack_usage();
+}
+#endif
+
+// -------------------------------------------------------------------------
+// EOF pthread.cxx
diff --git a/packages/compat/posix/v2_0/src/sched.cxx b/packages/compat/posix/v2_0/src/sched.cxx
new file mode 100644 (file)
index 0000000..6ca47a3
--- /dev/null
@@ -0,0 +1,242 @@
+//==========================================================================
+//
+//      sched.cxx
+//
+//      POSIX scheduler API implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg
+// Date:                2000-03-27
+// Purpose:             POSIX scheduler API implementation
+// Description:         This file contains the implementation of the POSIX scheduler
+//                      functions.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.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 "pprivate.h"                   // POSIX private header
+
+#include <cyg/kernel/sched.hxx>        // scheduler definitions
+#include <cyg/kernel/thread.hxx>       // thread definitions
+
+#include <cyg/kernel/sched.inl>        // scheduler inlines
+#include <cyg/kernel/thread.inl>       // thread inlines
+
+//==========================================================================
+// Process scheduling functions.
+
+//--------------------------------------------------------------------------
+// Set scheduling parameters for given process.
+
+int sched_setparam (pid_t pid, const struct sched_param *param)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    if( pid != 0 )
+    {
+        errno = ESRCH;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    errno = ENOSYS;
+    CYG_REPORT_RETVAL( -1 );
+    return -1;
+}
+
+//--------------------------------------------------------------------------
+// Get scheduling parameters for given process.
+
+int sched_getparam (pid_t pid, struct sched_param *param)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    if( pid != 0 )
+    {
+        errno = ESRCH;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+    
+    errno = ENOSYS;
+    CYG_REPORT_RETVAL( -1 );
+    return -1;
+}
+
+//--------------------------------------------------------------------------
+// Set scheduling policy and/or parameters for given process.
+int sched_setscheduler (pid_t pid,
+                        int policy,
+                        const struct sched_param *param)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    if( pid != 0 )
+    {
+        errno = ESRCH;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    errno = ENOSYS;
+    CYG_REPORT_RETVAL( -1 );
+    return -1;
+}
+    
+
+//--------------------------------------------------------------------------
+// Get scheduling policy for given process.
+
+int sched_getscheduler (pid_t pid)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    if( pid != 0 )
+    {
+        errno = ESRCH;
+        CYG_REPORT_RETVAL( 0 );
+        return -1;
+    }
+    
+    errno = ENOSYS;
+    CYG_REPORT_RETVAL( -1 );
+    return -1;
+}    
+
+//--------------------------------------------------------------------------
+// Force current thread to relinquish the processor.
+
+int sched_yield (void)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    Cyg_Thread::yield();
+    
+    CYG_REPORT_RETVAL( 0 );
+    return 0;
+}
+   
+
+//==========================================================================
+// Scheduler parameter limits.
+
+//--------------------------------------------------------------------------
+// Get maximum priority value for a policy.
+
+int sched_get_priority_max (int policy)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    if( policy != SCHED_FIFO &&
+        policy != SCHED_RR &&
+        policy != SCHED_OTHER )
+    {
+        errno = EINVAL;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+    
+    int pri = PTHREAD_POSIX_PRIORITY( CYG_THREAD_MAX_PRIORITY );
+    
+    CYG_REPORT_RETVAL( pri );
+    return pri;
+}    
+
+//--------------------------------------------------------------------------
+// Get minimum priority value for a policy.
+
+int sched_get_priority_min (int policy)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+    if( policy != SCHED_FIFO &&
+        policy != SCHED_RR &&
+        policy != SCHED_OTHER )
+    {
+        errno = EINVAL;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+
+    // idle thread priority isn't valid for general use, so subtract 1
+    int pri = PTHREAD_POSIX_PRIORITY( CYG_THREAD_MIN_PRIORITY-1 );
+    
+    CYG_REPORT_RETVAL( pri );
+    return pri;
+}    
+
+//--------------------------------------------------------------------------
+// Get the SCHED_RR interval for the given process.
+
+int sched_rr_get_interval (pid_t pid, struct timespec *t)
+{
+    CYG_REPORT_FUNCTYPE( "returning %d" );
+
+#ifdef CYGPKG_POSIX_CLOCKS
+    if( pid != 0 )
+    {
+        errno = ESRCH;
+        CYG_REPORT_RETVAL( -1 );
+        return -1;
+    }
+    
+    cyg_ticks_to_timespec( CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS, t );
+    
+    CYG_REPORT_RETVAL( 0 );
+    return 0;
+#else
+    errno = ENOSYS;
+    CYG_REPORT_RETVAL( -1 );
+    return -1;
+#endif
+} 
+
+// -------------------------------------------------------------------------
+// EOF sched.cxx
diff --git a/packages/compat/posix/v2_0/src/sem.cxx b/packages/compat/posix/v2_0/src/sem.cxx
new file mode 100644 (file)
index 0000000..298dc66
--- /dev/null
@@ -0,0 +1,244 @@
+//==========================================================================
+//
+//      sem.cxx
+//
+//      POSIX semaphore implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg
+// Date:                2000-03-27
+// Purpose:             POSIX semaphore implementation
+// Description:         This file contains the implementation of the POSIX semaphore
+//                      functions.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/posix.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 <semaphore.h>                  // our header
+
+#include "pprivate.h"                   // POSIX private header
+
+#include <cyg/kernel/thread.hxx>        // Kernel threads
+
+#include <cyg/kernel/thread.inl>        // Cyg_ThreadQueue::empty()
+
+#include <cyg/kernel/sema.hxx>          // Kernel semaphores
+
+// -------------------------------------------------------------------------
+// Internal definitions
+
+// Handle entry to a pthread package function. 
+#define SEMA_ENTRY() CYG_REPORT_FUNCTYPE( "returning %d" );
+
+// Do a semaphore package defined return. This requires the error code
+// to be placed in errno, and if it is non-zero, -1 returned as the
+// result of the function. This also gives us a place to put any
+// generic tidyup handling needed for things like signal delivery and
+// cancellation.
+#define SEMA_RETURN(err)                        \
+CYG_MACRO_START                                 \
+    int __retval = 0;                           \
+    if( err != 0 ) __retval = -1, errno = err;  \
+    CYG_REPORT_RETVAL( __retval );              \
+    return __retval;                            \
+CYG_MACRO_END
+
+//-----------------------------------------------------------------------------
+// new operator to allow us to invoke the Cyg_Thread constructor on the
+// user's semaphore object.
+
+inline void *operator new(size_t size,  void *ptr) { return (void *)ptr; };
+
+// -------------------------------------------------------------------------
+// Initialize semaphore to value.
+// pshared is not supported under eCos.
+
+externC int sem_init  (sem_t *sem, int pshared, unsigned int value)
+{
+    SEMA_ENTRY();
+
+    if( value > SEM_VALUE_MAX )
+        SEMA_RETURN(EINVAL);
+
+    Cyg_Counting_Semaphore *sema;
+
+    sema = new((void *)sem) Cyg_Counting_Semaphore(value);
+
+    sema=sema;
+    
+    SEMA_RETURN(0);
+}
+
+// -------------------------------------------------------------------------
+// Destroy the semaphore.
+
+externC int sem_destroy  (sem_t *sem)
+{
+    SEMA_ENTRY();
+
+    Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
+
+    // Check that the semaphore has no waiters
+    if( sema->waiting() )
+        SEMA_RETURN(EBUSY);
+
+    // Call the destructor
+    sema->~Cyg_Counting_Semaphore();
+    
+    SEMA_RETURN(0);
+}
+
+// -------------------------------------------------------------------------
+// Decrement value if >0 or wait for a post.
+
+externC int sem_wait  (sem_t *sem)
+{
+    int retval = 0;
+    
+    SEMA_ENTRY();
+
+#ifdef CYGPKG_POSIX_PTHREAD
+    // check for cancellation first.
+    pthread_testcancel();
+#endif
+
+    Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
+
+    if( !sema->wait() ) retval = EINTR;
+    
+#ifdef CYGPKG_POSIX_PTHREAD
+    // check if we were woken because we were being cancelled
+    pthread_testcancel();
+#endif
+
+    SEMA_RETURN(retval);
+}
+
+// -------------------------------------------------------------------------
+// Decrement value if >0, return -1 if not.
+
+externC int sem_trywait  (sem_t *sem)
+{
+    int retval = 0;
+    
+    SEMA_ENTRY();
+
+    Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
+
+    if( !sema->trywait() ) retval = EAGAIN;
+    
+    SEMA_RETURN(retval);
+}
+
+// -------------------------------------------------------------------------
+// Increment value and wake a waiter if one is present.
+
+externC int sem_post  (sem_t *sem)
+{
+    SEMA_ENTRY();
+
+    Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
+
+    sema->post();
+    
+    SEMA_RETURN(0);
+}
+    
+
+// -------------------------------------------------------------------------
+// Get current value
+
+externC int sem_getvalue  (sem_t *sem, int *sval)
+{
+    SEMA_ENTRY();
+
+    Cyg_Counting_Semaphore *sema = (Cyg_Counting_Semaphore *)sem;
+
+    *sval = sema->peek();
+
+    CYG_REPORT_RETVAL( 0 );
+    return 0;
+}
+
+// -------------------------------------------------------------------------
+// Open an existing named semaphore, or create it.
+
+externC sem_t *sem_open  (const char *name, int oflag, ...)
+{
+    SEMA_ENTRY();
+
+    errno = ENOSYS;
+
+    CYG_REPORT_RETVAL( SEM_FAILED );
+    return SEM_FAILED;
+}
+
+// -------------------------------------------------------------------------
+// Close descriptor for semaphore.
+
+externC int sem_close  (sem_t *sem)
+{
+    SEMA_ENTRY();
+
+    SEMA_RETURN(ENOSYS);
+}   
+
+// -------------------------------------------------------------------------
+// Remove named semaphore
+
+externC int sem_unlink  (const char *name)
+{
+    SEMA_ENTRY();
+
+    SEMA_RETURN(ENOSYS);
+}    
+
+// -------------------------------------------------------------------------
+// EOF sem.cxx
diff --git a/packages/compat/posix/v2_0/src/signal.cxx b/packages/compat/posix/v2_0/src/signal.cxx
new file mode 100644 (file)
index 0000000..80bc9c3
--- /dev/null
@@ -0,0 +1,1236 @@
+//==========================================================================
+//
+//      signal.cxx
+//
+//      POSIX signal functions implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Nick Garnett
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg
+// Date:                2000-03-27
+// Purpose:             POSIX signal functions implementation
+// Description:         This file contains the implementation of the POSIX signal
+//                      functions.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/posix.h>
+
+#ifdef CYGPKG_POSIX_SIGNALS
+
+#include <pkgconf/hal.h>
+#include <pkgconf/kernel.h>
+#include <pkgconf/isoinfra.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 "pprivate.h"                   // POSIX private header
+
+#include <signal.h>                     // our header
+#include <setjmp.h>
+#include <unistd.h>                     // _exit
+
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/clock.inl>
+#include <cyg/kernel/thread.inl>
+
+// -------------------------------------------------------------------------
+// Internal definitions
+
+// Handle entry to a signal package function. 
+#define SIGNAL_ENTRY() CYG_REPORT_FUNCTYPE( "returning %d" );
+
+// Do a signal package defined return. This requires the error code
+// to be placed in errno, and if it is non-zero, -1 returned as the
+// result of the function. This also gives us a place to put any
+// generic tidyup handling needed for things like signal delivery and
+// cancellation.
+#define SIGNAL_RETURN(err)                      \
+CYG_MACRO_START                                 \
+    int __retval = 0;                           \
+    if( err != 0 ) __retval = -1, errno = err;  \
+    CYG_REPORT_RETVAL( __retval );              \
+    return __retval;                            \
+CYG_MACRO_END
+
+// Similarly for functions that have valid non-zero returns
+#define SIGNAL_RETURN_VALUE(val)                \
+CYG_MACRO_START                                 \
+    CYG_REPORT_RETVAL( val );                   \
+    return val;                                 \
+CYG_MACRO_END
+
+// Range check on a signal value.
+#define SIGNAL_VALID(_sig_) (((_sig_) > 0) && ((_sig_) < ((int)sizeof(sigset_t)*8)))
+
+//==========================================================================
+// Signal management structures
+
+typedef struct signal_info
+{
+    struct signal_info          *next;  // link in list of pending signals
+    siginfo_t                   si;     // siginfo to pass to handler
+} signal_info;
+
+typedef struct
+{
+    struct sigaction            sa;     // Sigaction defining what to do
+    signal_info                 *pending; // List of pending signals - this is
+                                          // a circular list with pending pointing
+                                          // to the tail element (or NULL if empty).
+} signal_state;
+
+//==========================================================================
+// Signal management variables
+
+// Lock used to protect signal management structures
+Cyg_Mutex signal_mutex CYGBLD_POSIX_INIT;
+
+// Condition variable for all threads in sigsuspend() and sigwait()
+// to wait on.
+Cyg_Condition_Variable CYGBLD_POSIX_INIT signal_sigwait( signal_mutex ) ;
+
+// Global pending signal set
+sigset_t sig_pending;
+
+// Array controlling signal states
+static signal_state sigstate[sizeof(sigset_t)*8];
+
+// Array of available signal_info objects for queueing signals
+static signal_info siginfo[SIGQUEUE_MAX];
+
+// List of free signal_info objects
+static signal_info *siginfo_next = NULL;
+
+//==========================================================================
+// Variables used to support alarm()
+
+// Forward def of action function
+static void sigalrm_action( Cyg_Alarm *alarm, CYG_ADDRWORD data );
+
+// Kernel alarm object
+static Cyg_Alarm CYGBLD_POSIX_INIT sigalrm_alarm( Cyg_Clock::real_time_clock, sigalrm_action, 0 ) ;
+
+// Set true when alarm is armed
+volatile cyg_bool sigalrm_armed = false;
+
+// Set true when alarm has fired and is waiting to be delivered
+volatile cyg_bool sigalrm_pending = false;
+
+//==========================================================================
+// Implementation functions.
+// These are where the real work of the signal mechanism gets done.
+
+externC void cyg_posix_signal_start()
+{
+    // Chain all free signal_info objects together
+    for( int i = 0; i < SIGQUEUE_MAX; i++ )
+    {
+        siginfo[i].next = siginfo_next;
+        siginfo_next = &siginfo[i];
+    }
+    
+    // initialize all signal actions to SIG_DFL
+    for ( unsigned int i=0; i<(sizeof(sigstate)/sizeof(signal_state)); i++ )
+    {
+        sigstate[i].sa.sa_handler = SIG_DFL;
+    }
+
+    // Clear the pending signal set
+    sigemptyset( &sig_pending );
+}
+
+// -------------------------------------------------------------------------
+// Generate a signal
+
+cyg_bool cyg_sigqueue( const struct sigevent *sev, int code,
+                       pthread_info *thread )
+{
+    if( sev->sigev_notify == SIGEV_NONE )
+    {
+        // Do nothing
+        return true;
+    }
+
+    if( sev->sigev_notify == SIGEV_THREAD )
+    {
+        // create a thread to run the notification
+        // function.
+        // FIXME: implement SIGEV_THREAD
+        return true;
+    }
+
+    // Otherwise we must have a SIGEV_SIGNAL notification
+
+    // Find out whether the current thread already has the mutex
+    // locked. This is a distinct possibility if this function is
+    // called from the ASR while exiting the signal_sigwait condvar in
+    // pause() and sigtimedwait().
+    
+    pthread_info *self = pthread_self_info();
+    cyg_bool locked = (self != NULL) && (signal_mutex.get_owner() == self->thread);
+    
+    // Lock the mutex only if we do not already own it
+    if( !locked ) signal_mutex.lock();
+    
+    int signo = sev->sigev_signo;
+    signal_state *ss = &sigstate[signo];
+
+    if( ss->sa.sa_flags & SA_SIGINFO )
+    {
+        // We have a queuable signal, allocate a signal_info
+        // object and add it to the queue.
+
+        if( siginfo_next == NULL )
+        {
+            if( !locked ) signal_mutex.unlock();
+            return false;
+        }
+
+        signal_info *si = siginfo_next;
+        siginfo_next = si->next;
+
+        si->si.si_signo = signo;
+        si->si.si_code = code;
+        si->si.si_value = sev->sigev_value;
+
+        if( ss->pending == NULL )
+        {
+            si->next = si;
+        }
+        else
+        {
+            si->next = ss->pending->next;
+            ss->pending->next = si;
+        }
+            
+        ss->pending = si;
+    }
+    // else A non-queuable signal, just set it pending
+
+    if( thread != NULL )
+    {
+        sigaddset( &thread->sigpending, signo );
+        // just wake the thread up now if it's blocked somewhere
+        if ((thread->sigpending & ~thread->sigmask) != 0)
+        {
+            thread->thread->set_asr_pending();
+            thread->thread->release();
+        }
+    }
+    else
+    {
+        sigaddset( &sig_pending, signo );
+        // Wake up any threads in sigsuspend() and sigwait().
+        if (!signal_sigwait.get_queue()->empty())
+        {
+            signal_sigwait.broadcast();
+        } 
+        else
+        {
+            cyg_posix_pthread_release_thread( &sig_pending );
+        }
+    }
+
+    if( !locked ) signal_mutex.unlock();
+    
+    return true;
+}
+
+// -------------------------------------------------------------------------
+// Deliver any pending unblocked signals to the current thread
+// Returns true if a signal handler was called.
+
+cyg_bool cyg_deliver_signals()
+{
+    cyg_bool res = false;
+    
+    pthread_info *self = pthread_self_info();
+
+    // If there is no pthread_info pointer for this thread then
+    // it is not a POSIX thread and cannot have signals delivered
+    // to it.
+    
+    if( self == NULL ) return false;
+    
+    // If there are no pending signals our work is done
+    if( sig_pending == 0 && self->sigpending == 0 )
+        return false;
+
+    // If there are no unmasked pending signals our
+    // work is also done
+    if( ((sig_pending | self->sigpending) & ~self->sigmask) == 0 )
+        return false;
+
+    // As with cyg_sigqueue(), this function can get called from an
+    // ASR where the signal_mutex is already locked. Check here to
+    // avoid relocking...
+    
+    cyg_bool locked = signal_mutex.get_owner() == self->thread;
+    
+    if( !locked ) signal_mutex.lock();
+        
+    sigset_t todo;
+
+    // Since a signal handler may raise another signal, or unmask an existing
+    // signal, we loop here while there are no more unblocked signals pending.
+    while( (todo = ((sig_pending | self->sigpending) & ~self->sigmask)) != 0 )
+    {
+        // Here todo is a mask of the signals available for delivery
+        
+        int signo = 0;
+
+        // This prioritizes low numbered signals
+        HAL_LSBIT_INDEX( signo, todo );
+
+        signal_state *ss = &sigstate[signo];
+        sigset_t sigbit = 1L<<signo;
+
+        if( ss->sa.sa_handler != SIG_IGN )
+        {
+            sigset_t oldmask = self->sigmask;
+            siginfo_t lsi;
+
+            if(ss->pending != NULL)
+            {
+                // There is a queued signal. Dequeue it and copy the
+                // siginfo object to a local copy.
+                
+                signal_info *si = ss->pending->next;
+                    
+                // Make a local copy of the siginfo object
+                lsi = si->si;
+                    
+                // Remove the head signal_info object from the
+                // circular list. 
+                if( ss->pending == si )
+                    ss->pending = NULL;
+                else
+                    ss->pending->next = si->next;
+
+                // Return it to the free list
+                si->next = siginfo_next;
+                siginfo_next = si;
+            }
+            else
+            {
+                // There are no signals queued. Set up the local siginfo_t
+                // object with default values. 
+
+                lsi.si_signo = signo;
+                lsi.si_code = SI_USER;
+                lsi.si_value.sival_int = 0;
+            }
+            
+            // Clear the bit from the pending masks. If the pending
+            // queue is not empty, leave the bits set, otherwise clear
+            // them. Do this now so that if the signal handler longjumps
+            // out, the signal subsystem is clean.
+        
+            if( ss->pending == NULL )
+            {
+                // Clear the bit in both masks regardless of which
+                // one it actually came from. This is cheaper than
+                // trying to find out.
+                sig_pending &= ~sigbit;
+                self->sigpending &= ~sigbit;
+            }
+
+            // Add the mask set and the signal itself to the
+            // mask while we call the signal handler
+            self->sigmask = oldmask | ss->sa.sa_mask | sigbit;
+            
+            // Unlock now so that a longjmp out of the handler
+            // does the right thing. We do this even if we did not
+            // lock the mutex since it will only recently have been
+            // relocked and thus all data is still consistent.
+                
+            signal_mutex.unlock();
+            
+            if( ss->sa.sa_flags & SA_SIGINFO )
+            {
+                // A sigaction delivery
+                CYG_CHECK_FUNC_PTR( ss->sa.sa_sigaction,
+                                    "Bad sa_sigaction signal handler" );
+                ss->sa.sa_sigaction( signo, &lsi, NULL );
+            }
+            else if ( ss->sa.sa_handler == SIG_DFL )
+            {
+                CYG_TRACE2( true,
+                            "Unhandled POSIX signal: sig=%d, mask=%08x",
+                            signo, oldmask );
+
+                // FIXME: should do something better here
+#if CYGINT_ISO_EXIT
+                _exit( -signo );
+#endif
+                CYG_FAIL("Unhandled POSIX signal");
+            }            
+            else
+            {
+                // This is a standard signal delivery.
+                CYG_CHECK_FUNC_PTR( ss->sa.sa_handler,
+                                    "Bad sa_handler signal handler" );
+
+                ss->sa.sa_handler( signo );
+            }
+
+            // Relock the mutex 
+            signal_mutex.lock();                
+
+            // Restore original signal mask
+            self->sigmask = oldmask;
+
+            // return that we have handled a signal
+            res = true;
+        }
+    }
+
+    if( !locked ) signal_mutex.unlock();
+    
+    return res;
+}
+
+// -------------------------------------------------------------------------
+// Utility routine to signal any threads waiting in sigwait*().
+
+void cyg_posix_signal_sigwait()
+{
+    signal_sigwait.broadcast();
+}       
+
+// -------------------------------------------------------------------------
+// Action routine called from kernel alarm to deliver the SIGALRM signal.
+// We cannot call any signal delivery functions directly here, so we simply
+// set a flag and schedule an ASR to be called.
+
+static void sigalrm_action( Cyg_Alarm *alarm, CYG_ADDRWORD data )
+{
+    sigset_t mask;
+    sigalrm_armed = false;
+    sigalrm_pending = true;
+    sigemptyset( &mask );
+    sigaddset( &mask, SIGALRM );
+    // Wake up any threads in sigsuspend() and sigwait() in case they
+    // are waiting for an alarm, and would have SIGALRM masked
+    signal_sigwait.broadcast();
+    
+    cyg_posix_pthread_release_thread( &mask );
+}
+
+// -------------------------------------------------------------------------
+// Check for SIGALRMs. This is called from the ASR and sigtimedwait()
+// as alarms need to be handled as a special case.
+
+static __inline__ void check_sigalarm(void)
+{
+    // If there is a pending SIGALRM, generate it
+    if( sigalrm_pending )
+    {
+        sigalrm_pending = false;
+        
+        struct sigevent sev;
+
+        sev.sigev_notify           = SIGEV_SIGNAL;
+        sev.sigev_signo            = SIGALRM;
+        sev.sigev_value.sival_int  = 0;
+
+        // generate the signal
+        cyg_sigqueue( &sev, SI_USER );
+    }
+}
+
+// -------------------------------------------------------------------------
+// signal ASR function. This is called from the general POSIX ASR to
+// deal with any signal related issues.
+
+externC void cyg_posix_signal_asr(pthread_info *self)
+{
+    check_sigalarm();
+
+    // Now call cyg_deliver_signals() to see if we can
+    // handle any signals now.
+    
+    cyg_deliver_signals();
+}
+
+//==========================================================================
+// Per-thread initialization and destruction
+
+externC void cyg_posix_thread_siginit( pthread_info *thread,
+                                       pthread_info *parentthread )
+{
+    // Clear out signal masks
+    sigemptyset( &thread->sigpending );
+    // but threads inherit signal masks
+    if ( NULL == parentthread )
+        sigemptyset( &thread->sigmask );
+    else
+        thread->sigmask = parentthread->sigmask;
+    
+    cyg_pthread_exception_init( thread );
+}
+
+externC void cyg_posix_thread_sigdestroy( pthread_info *thread )
+{
+    cyg_pthread_exception_destroy( thread );
+}
+
+//==========================================================================
+// Functions to generate signals
+
+// -------------------------------------------------------------------------
+// Deliver sig to a process.
+// eCos only supports the value 0 for pid.
+
+externC int kill (pid_t pid, int sig)
+{
+    SIGNAL_ENTRY();
+
+    if( !SIGNAL_VALID(sig) )
+        SIGNAL_RETURN(EINVAL);
+    
+    if( pid != 0 )
+        SIGNAL_RETURN(ESRCH);
+
+    struct sigevent sev;
+
+    sev.sigev_notify           = SIGEV_SIGNAL;
+    sev.sigev_signo            = sig;
+    sev.sigev_value.sival_int  = 0;
+    
+    cyg_sigqueue( &sev, SI_USER );
+
+    cyg_deliver_signals();
+    
+    SIGNAL_RETURN(0);
+}
+
+// -------------------------------------------------------------------------
+
+externC int pthread_kill (pthread_t threadid, int sig)
+{
+    SIGNAL_ENTRY();
+
+    if( !SIGNAL_VALID(sig) )
+        SIGNAL_RETURN(EINVAL);
+    
+    struct sigevent sev;
+
+    pthread_info *thread = pthread_info_id(threadid);
+
+    if( thread == NULL )
+        SIGNAL_RETURN(ESRCH);
+    
+    sev.sigev_notify           = SIGEV_SIGNAL;
+    sev.sigev_signo            = sig;
+    sev.sigev_value.sival_int  = 0;
+    
+    cyg_sigqueue( &sev, SI_USER, thread );
+
+    cyg_deliver_signals();
+    
+    SIGNAL_RETURN(0);
+}
+
+//==========================================================================
+// Functions to catch signals
+
+// -------------------------------------------------------------------------
+// Install signal handler for sig.
+
+externC int sigaction  (int sig, const struct sigaction *act,
+                        struct sigaction *oact)
+{
+    SIGNAL_ENTRY();
+
+    if( !SIGNAL_VALID(sig) )
+        SIGNAL_RETURN(EINVAL);
+    
+    signal_state *ss = &sigstate[sig];
+    
+    signal_mutex.lock();
+
+    if( oact != NULL )
+        *oact = ss->sa;
+
+    ss->sa = *act;
+
+    if( ss->sa.sa_handler == SIG_IGN )
+    {
+        // Setting the handler to SIG_IGN causes any pending
+        // signals to be discarded and any queued values to also
+        // be removed.
+
+        pthread_info *self = pthread_self_info();
+        sigset_t sigbit = 1<<sig;
+
+        if( (sig_pending | self->sigpending) & sigbit )
+        {
+            // This signal is pending, clear it
+
+            sig_pending &= ~sigbit;
+            self->sigpending &= ~sigbit;
+
+            // Clean out any queued signal_info objects
+            while( ss->pending != NULL )
+            {
+                signal_info *si = ss->pending->next;
+                
+                // Remove the head signal_info object from the
+                // circular list. 
+                if( ss->pending == si )
+                    ss->pending = NULL;
+                else
+                    ss->pending->next = si->next;
+
+                // Return it to the free list
+                si->next = siginfo_next;
+                siginfo_next = si;
+            }
+        }
+    }
+    
+    cyg_deliver_signals();
+    
+    signal_mutex.unlock();
+    
+    SIGNAL_RETURN(0);
+}
+    
+
+// -------------------------------------------------------------------------
+// Queue signal to process with value.
+
+externC int sigqueue (pid_t pid, int sig, const union sigval value)
+{
+    SIGNAL_ENTRY();
+
+    if( !SIGNAL_VALID(sig) )
+        SIGNAL_RETURN(EINVAL);
+    
+    struct sigevent sev;
+
+    sev.sigev_notify   = SIGEV_SIGNAL;
+    sev.sigev_signo    = sig;
+    sev.sigev_value    = value;
+    
+    cyg_sigqueue( &sev, SI_QUEUE );
+
+    cyg_deliver_signals();
+    
+    SIGNAL_RETURN(0);
+}
+    
+//==========================================================================
+// Functions to deal with current blocked and pending masks
+
+// -------------------------------------------------------------------------
+// Set process blocked signal mask
+// Map this onto pthread_sigmask().
+
+externC int sigprocmask  (int how, const sigset_t *set, sigset_t *oset)
+{
+    return pthread_sigmask( how, set, oset);
+}
+    
+
+// -------------------------------------------------------------------------
+// Set calling thread's blocked signal mask
+
+externC int pthread_sigmask (int how, const sigset_t *set, sigset_t *oset)
+{
+    int err = 0;
+    
+    SIGNAL_ENTRY();
+
+    pthread_info *self = pthread_self_info();
+    // Save old set
+    if( oset != NULL )
+        *oset = self->sigmask;
+
+    if( set != NULL )
+    {
+        switch( how )
+        {
+        case SIG_BLOCK:
+            self->sigmask |= *set;
+            break;
+        
+        case SIG_UNBLOCK:
+            self->sigmask &= ~*set;
+            break;
+            
+        case SIG_SETMASK:
+            self->sigmask = *set;
+            break;
+
+        default:
+            err = EINVAL;
+            break;
+        }
+    }
+
+    // Deliver any newly unblocked signals
+    cyg_deliver_signals();
+    
+    SIGNAL_RETURN(err);
+}
+
+// -------------------------------------------------------------------------
+// Exported routine to set calling thread's blocked signal mask
+//
+// Optionally set and return the current thread's signal mask. This is
+// exported to other packages so that they can manipulate the signal
+// mask without necessarily having them delivered (as calling
+// pthread_sigmask() would). Signals can be delivered by calling
+// cyg_posix_deliver_signals().
+
+externC void cyg_pthread_sigmask_set (const sigset_t *set, sigset_t *oset)
+{
+    pthread_info *self = pthread_self_info();
+
+    if( self != NULL )
+    {
+        if( oset != NULL )
+            *oset = self->sigmask;
+
+        if( set != NULL )
+            self->sigmask = *set;
+    }
+}
+
+// -------------------------------------------------------------------------
+// Exported routine to test for any pending signals.
+//
+// This routine tests for any pending undelivered, unmasked
+// signals. If there are any it returns true.  This is exported to
+// other packages, such as FILEIO, so that they can detect whether to
+// abort a current API call with an EINTR result.
+
+externC cyg_bool cyg_posix_sigpending(void)
+{
+    pthread_info *self = pthread_self_info();
+
+    if( self == NULL )
+        return false;
+    
+    return ( ((sig_pending | self->sigpending) & ~self->sigmask) != 0 );
+}
+
+// -------------------------------------------------------------------------
+// Exported routine to deliver selected signals
+//
+// This routine optionally sets the given mask and then tries to
+// deliver any pending signals that have been unmasked. This is
+// exported to other packages so that they can cause signals to be
+// delivered at controlled points during execution.
+
+externC void cyg_posix_deliver_signals( const sigset_t *mask )
+{
+    sigset_t oldmask;
+    pthread_info *self = pthread_self_info();
+
+    if( self != NULL )
+    {
+        if( mask != NULL )
+        {
+            oldmask = self->sigmask;
+            self->sigmask = *mask;
+        }
+        else
+            oldmask = 0;   // silence warning
+
+        cyg_deliver_signals();
+
+        if( mask != NULL )        
+            self->sigmask = oldmask;
+    }
+}
+
+// -------------------------------------------------------------------------
+// Get set of pending signals for this process
+
+externC int sigpending  (sigset_t *set)
+{
+    SIGNAL_ENTRY();
+
+    if( set == NULL )
+        SIGNAL_RETURN(EINVAL);
+    
+    pthread_info *self = pthread_self_info();
+    
+    *set = self->sigpending | sig_pending;
+    
+    SIGNAL_RETURN(0);
+}
+    
+
+//==========================================================================
+// Wait for or accept signals
+
+// -------------------------------------------------------------------------
+// Block signals in set and wait for a signal
+
+externC int sigsuspend  (const sigset_t *set)
+{
+    SIGNAL_ENTRY();
+
+    pthread_info *self = pthread_self_info();
+
+    signal_mutex.lock();
+
+    // Save the old mask and set the current mask to
+    // the one supplied.
+    sigset_t old = self->sigmask;
+    self->sigmask = *set;
+
+    // Loop until a signal gets delivered
+    while( !cyg_deliver_signals() )
+        signal_sigwait.wait();
+
+    self->sigmask = old;
+    
+    signal_mutex.unlock();
+    
+    SIGNAL_RETURN(EINTR);
+}
+    
+
+// -------------------------------------------------------------------------
+// Wait for a signal in set to arrive
+// Implement this as a variant on sigtimedwait().
+
+externC int sigwait  (const sigset_t *set, int *sig)
+{
+    SIGNAL_ENTRY();
+
+    siginfo_t info;
+    
+    int ret = sigtimedwait( set, &info, NULL );
+
+    if( ret == -1 )
+        SIGNAL_RETURN(errno);
+
+    *sig = ret;
+    
+    SIGNAL_RETURN(0);
+}
+
+// -------------------------------------------------------------------------
+// Do the same as sigwait() except return a siginfo_t object too.
+// Implement this as a variant on sigtimedwait().
+
+externC int sigwaitinfo  (const sigset_t *set, siginfo_t *info)
+{
+    SIGNAL_ENTRY();
+
+    int ret = sigtimedwait( set, info, NULL );
+    
+    SIGNAL_RETURN_VALUE(ret);
+}
+
+// -------------------------------------------------------------------------
+// Wait either for a signal in the given set to become pending, or
+// for the timeout to expire. If timeout is NULL, wait for ever.
+
+externC int sigtimedwait  (const sigset_t *set, siginfo_t *info,
+                           const struct timespec *timeout)
+{
+    SIGNAL_ENTRY();
+
+    // check for cancellation first.
+    pthread_testcancel();
+
+    int err = 0;
+    cyg_tick_count ticks;
+
+    if( timeout == NULL ) ticks = 0;
+    else ticks = cyg_timespec_to_ticks( timeout ) +
+             Cyg_Clock::real_time_clock->current_value();
+
+    pthread_info *self = pthread_self_info();
+    
+    signal_mutex.lock();
+
+    sigset_t todo;
+
+    // Wait for a signal in the set to become pending
+    while( (todo = (*set & (sig_pending | self->sigpending))) == 0 )
+    {
+        // If timeout is not NULL, do a timed wait on the
+        // sigwait condition variable. If it is NULL - wait
+        // until we are woken.
+        if( timeout )
+        {
+            if( ticks == 0 || !signal_sigwait.wait(ticks) )
+            {
+                // If the timeout is actually zero, or we have waited and
+                // timed out, then we must quit with an error.
+                err = EAGAIN;
+                break;
+            }
+        }
+        else {
+            if ( !signal_sigwait.wait() ) {
+                // check we weren't woken up forcibly (e.g. to be cancelled)
+                // if so, pretend it's an error
+                err = EAGAIN;
+                break;
+            }
+        }
+        
+        // Special case check for SIGALRM since the fact SIGALRM is masked
+        // would have prevented it being set pending in the alarm handler.
+        check_sigalarm();
+
+        cyg_posix_timer_asr(self);
+    }
+
+    if( err == 0 )
+    {
+        // There is a signal in the set that is pending: deliver
+        // it. todo contains a mask of all the signals that could be
+        // delivered now, but we only want to deliver one of them.
+
+        int signo = 0;
+
+        // Select the lowest numbered signal from the todo mask
+        HAL_LSBIT_INDEX( signo, todo );
+
+        signal_state *ss = &sigstate[signo];
+        sigset_t sigbit = 1L<<signo;
+
+        if( (ss->sa.sa_flags & SA_SIGINFO) && (ss->pending != NULL) )
+        {
+            // If the SA_SIGINFO bit is set, then there
+            // will be a signal_info object queued on the
+            // pending field.
+
+            signal_info *si = ss->pending->next;
+            *info = si->si;
+
+            // Remove the head signal_info object from the
+            // circular list. 
+            if( ss->pending == si )
+                ss->pending = NULL;
+            else
+                ss->pending->next = si->next;
+                
+            si->next = siginfo_next;
+            siginfo_next = si;
+                
+        }
+        else
+        {
+            // Not a queued signal, or there is no signal_info object
+            // on the pending queue: fill in info structure with
+            // default values.
+            info->si_signo           = signo;
+            info->si_code            = SI_USER;
+            info->si_value.sival_int = 0;
+        }
+
+        // Clear the bit from the pending masks. If the pending
+        // queue is not empty, leave the bits set, otherwise clear
+        // them.
+        
+        if( ss->pending == NULL )
+        {
+            // Clear the bit in both masks regardless of which
+            // one it actually came from. This is cheaper than
+            // trying to find out.
+            sig_pending &= ~sigbit;
+            self->sigpending &= ~sigbit;
+        }
+
+        // all done
+    }
+    
+    signal_mutex.unlock();
+
+    pthread_testcancel();
+
+    if (err)
+        SIGNAL_RETURN(err);
+    else
+        SIGNAL_RETURN_VALUE( info->si_signo );
+}
+
+//==========================================================================
+// alarm, pause and sleep
+
+// -------------------------------------------------------------------------
+// Generate SIGALRM after some number of seconds
+
+externC unsigned int alarm( unsigned int seconds )
+{
+    int res = 0;
+    struct timespec tv;
+    cyg_tick_count trigger, interval;
+
+    SIGNAL_ENTRY();
+
+    signal_mutex.lock();
+
+    if( sigalrm_armed )
+    {
+        sigalrm_alarm.disable();
+
+        sigalrm_alarm.get_times( &trigger, &interval );
+
+        // Convert trigger time back to interval
+        trigger -= Cyg_Clock::real_time_clock->current_value();
+        
+        cyg_ticks_to_timespec( trigger, &tv );
+
+        res = tv.tv_sec;
+        
+        sigalrm_armed = false;
+    }
+
+    if( seconds != 0 )
+    {
+        // Here we know that the sigalrm_alarm is unarmed, set it up
+        // to trigger in the required number of seconds.
+
+        tv.tv_sec = seconds;
+        tv.tv_nsec = 0;
+
+        trigger = cyg_timespec_to_ticks( &tv );
+
+        // Convert trigger interval to absolute time
+        trigger += Cyg_Clock::real_time_clock->current_value();
+        
+        sigalrm_alarm.initialize( trigger, 0 );
+
+        sigalrm_armed = true;
+    }
+    
+    signal_mutex.unlock();
+
+    CYG_REPORT_RETVAL(res);
+    
+    return res;
+}
+
+// -------------------------------------------------------------------------
+// Wait for a signal to be delivered.
+
+externC int pause( void )
+{
+    SIGNAL_ENTRY();
+
+    signal_mutex.lock();
+
+    // Check for any pending signals that can be delivered and
+    // if there are none, wait for a signal to be generated
+    if( !cyg_deliver_signals() )
+        signal_sigwait.wait();
+
+    // Now check again for some signals to deliver
+    cyg_deliver_signals();
+    
+    signal_mutex.unlock();
+    
+    SIGNAL_RETURN(EINTR);
+}
+
+//==========================================================================
+// Signal sets
+
+// -------------------------------------------------------------------------
+// Clear all signals from set.
+
+externC int sigemptyset  (sigset_t *set)
+{
+    SIGNAL_ENTRY();
+
+    *set = 0;
+    
+    SIGNAL_RETURN(0);
+}
+    
+
+// -------------------------------------------------------------------------
+// Set all signals in set.
+
+externC int sigfillset  (sigset_t *set)
+{
+    SIGNAL_ENTRY();
+
+    *set = ~0;
+    
+    SIGNAL_RETURN(0);
+}
+    
+
+// -------------------------------------------------------------------------
+// Add signo to set.
+
+externC int sigaddset  (sigset_t *set, int signo)
+{
+    SIGNAL_ENTRY();
+
+    int err = 0;
+    
+    if( !SIGNAL_VALID(signo) )
+        err = EINVAL;
+    else *set |= 1<<signo;
+    
+    SIGNAL_RETURN(err);
+}
+    
+
+// -------------------------------------------------------------------------
+// Remove signo from set.
+
+externC int sigdelset  (sigset_t *set, int signo)
+{
+    SIGNAL_ENTRY();
+
+    int err = 0;
+    
+    if( !SIGNAL_VALID(signo) )
+        err = EINVAL;
+    else *set &= ~(1<<signo);
+    
+    SIGNAL_RETURN(err);
+}
+    
+
+// -------------------------------------------------------------------------
+// Test whether signo is in set
+
+externC int sigismember  (const sigset_t *set, int signo)
+{
+    SIGNAL_ENTRY();
+
+    int ret = 0;
+    
+    if( !SIGNAL_VALID(signo) )
+        SIGNAL_RETURN(EINVAL);
+
+    if( *set & (1<<signo) ) ret = 1;
+
+    CYG_REPORT_RETVAL( ret );
+    return ret;
+}
+
+//==========================================================================
+// ISO C compatibility functions
+
+// -------------------------------------------------------------------------
+// Installs a new signal handler for the specified signal, and returns
+// the old handler
+
+externC sa_sighandler_t signal(int sig, sa_sighandler_t handler)
+{
+    SIGNAL_ENTRY();
+
+    int err;
+    sa_sighandler_t ret;
+    struct sigaction new_action;
+    struct sigaction old_action;
+
+    sigemptyset( &new_action.sa_mask );
+    new_action.sa_flags = 0;
+    new_action.sa_handler = handler;
+
+    err = sigaction( sig, &new_action, &old_action );
+
+    if( err < 0 )
+        ret = SIG_ERR;
+    else ret = old_action.sa_handler;
+    
+    CYG_REPORT_RETVAL( ret );
+    return ret;    
+}
+
+// -------------------------------------------------------------------------
+// raise() - ISO C 7.7.2 //
+//
+// Raises the signal, which will cause the current signal handler for
+// that signal to be called
+
+externC int raise(int sig)
+{
+    return kill( 0, sig );
+}
+
+// -------------------------------------------------------------------------
+// siglongjmp()
+// Restores signal mask and longjumps.
+
+__externC void siglongjmp( sigjmp_buf env, int val )
+{
+    CYG_REPORT_FUNCNAME( "siglongjmp" );
+    CYG_REPORT_FUNCARG2( "&env=%08x, val=%d", &env, val );
+
+    // ISO C says that if we are passed val == 0, then we change it to 1
+    if( val == 0 )
+        val = 1;
+
+    if( env[0].__savemask )
+        pthread_sigmask( SIG_SETMASK, &env[0].__sigsavemask, NULL );
+    
+    HAL_REORDER_BARRIER(); // prevent any chance of optimisation re-ordering
+    hal_longjmp( env[0].__jmp_buf, val );
+    HAL_REORDER_BARRIER(); // prevent any chance of optimisation re-ordering
+
+#ifdef CYGDBG_USE_ASSERTS
+    CYG_ASSERT( 0, "siglongjmp should not have reached this point!" );
+#else
+    for (;;)
+        CYG_EMPTY_STATEMENT;
+#endif
+    
+}
+
+#endif // ifdef CYGPKG_POSIX_SIGNALS
+
+// -------------------------------------------------------------------------
+// EOF signal.cxx
diff --git a/packages/compat/posix/v2_0/src/startup.cxx b/packages/compat/posix/v2_0/src/startup.cxx
new file mode 100644 (file)
index 0000000..9480ab9
--- /dev/null
@@ -0,0 +1,87 @@
+//==========================================================================
+//
+//      startup.cxx
+//
+//      POSIX startup code
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg, jlarmour
+// Contributors:        nickg, jlarmour
+// Date:                2000-03-27
+// Purpose:             POSIX startup code
+// Description:         This file contains code that must be run when the
+//                      POSIX subsystem is started.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/posix.h>
+
+#include <cyg/infra/cyg_type.h>
+#include "pprivate.h"                  // POSIX private header
+
+// -------------------------------------------------------------------------
+
+// define an object that will automatically initialize the POSIX subsystem
+
+class cyg_posix_startup_dummy_constructor_class {
+public:
+    cyg_posix_startup_dummy_constructor_class() { 
+
+#ifdef CYGPKG_POSIX_PTHREAD
+        cyg_posix_pthread_start();
+#endif
+#ifdef CYGPKG_POSIX_SIGNALS
+        cyg_posix_signal_start();
+        cyg_posix_exception_start();
+#endif
+#ifdef CYGPKG_POSIX_TIMERS
+        cyg_posix_clock_start();
+#endif
+
+    }
+};
+
+static cyg_posix_startup_dummy_constructor_class cyg_posix_startup_obj
+                                  CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_COMPAT);
+
+// -------------------------------------------------------------------------
+// EOF startup.cxx
diff --git a/packages/compat/posix/v2_0/src/time.cxx b/packages/compat/posix/v2_0/src/time.cxx
new file mode 100644 (file)
index 0000000..c4f5d70
--- /dev/null
@@ -0,0 +1,700 @@
+//==========================================================================
+//
+//      time.cxx
+//
+//      POSIX time functions implementation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           nickg
+// Contributors:        nickg
+// Date:                2000-03-27
+// Purpose:             POSIX time functions implementation
+// Description:         This file contains the implementation of the POSIX time
+//                      functions.
+//              
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/posix.h>
+
+#ifdef CYGPKG_POSIX_CLOCKS
+
+#include <pkgconf/hal.h>
+#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 "pprivate.h"                   // POSIX private header
+
+#include <time.h>                       // our header
+
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/clock.hxx>
+
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/clock.inl>
+
+// -------------------------------------------------------------------------
+// Internal definitions
+
+// Handle entry to a pthread package function. 
+#define TIME_ENTRY() CYG_REPORT_FUNCTYPE( "returning %d" );
+
+// Do a time package defined return. This requires the error code
+// to be placed in errno, and if it is non-zero, -1 returned as the
+// result of the function. This also gives us a place to put any
+// generic tidyup handling needed for things like signal delivery and
+// cancellation.
+#define TIME_RETURN(err)                        \
+CYG_MACRO_START                                 \
+    int __retval = 0;                           \
+    if( err != 0 ) __retval = -1, errno = err;  \
+    CYG_REPORT_RETVAL( __retval );              \
+    return __retval;                            \
+CYG_MACRO_END
+
+//==========================================================================
+// Timer control structures
+
+#ifdef CYGPKG_POSIX_TIMERS
+typedef struct
+{
+    timer_t             id;             // id value for checking
+    Cyg_Alarm           *alarm;         // eCos alarm object
+    cyg_bool            armed;          // is alarm enabled?
+    cyg_bool            pending;        // is expiry pending?
+    int                 overrun;        // Overrun count
+    struct sigevent     sigev;          // Sigevent to raise on expiry
+    
+    // Space for alarm object
+    cyg_uint8           alarm_obj[sizeof(Cyg_Alarm)];
+    
+} posix_timer;
+
+// Mutex for controlling access to shared data structures
+static Cyg_Mutex timer_mutex CYGBLD_POSIX_INIT;
+
+// Array of timer objects
+static posix_timer timer_table[_POSIX_TIMER_MAX];
+
+// Index of next timer to allocate from array
+static int timer_next = 0;
+
+// This is used to make timer_t values unique even when reusing
+// a table slot. This allows _POSIX_TIMER_MAX to range
+// up to 1024.
+#define TIMER_ID_COOKIE_INC 0x00000400
+#define TIMER_ID_COOKIE_MASK (TIMER_ID_COOKIE_INC-1)
+static timer_t timer_id_cookie = TIMER_ID_COOKIE_INC;
+
+#endif // ifdef CYGPKG_POSIX_TIMERS
+
+//-----------------------------------------------------------------------------
+// new operator to allow us to invoke the constructor on
+// posix_timer.alarm_obj.
+
+inline void *operator new(size_t size,  cyg_uint8 *ptr) { return (void *)ptr; };
+
+//==========================================================================
+// Time conversion variables
+// These are used to interconvert between ticks and POSIX timespecs.
+
+// Converters from sec and ns to ticks
+static struct Cyg_Clock::converter ns_converter, sec_converter;
+
+// Converters from ticks to sec and ns
+static struct Cyg_Clock::converter ns_inverter, sec_inverter;
+
+// tickns is the number of nanoseconds per tick.
+static cyg_tick_count tickns;
+
+static cyg_bool converters_initialized = false;
+
+//==========================================================================
+// Local functions
+
+static void init_converters()
+{
+    if( !converters_initialized )
+    {
+
+        // Create the converters we need.
+        Cyg_Clock::real_time_clock->get_other_to_clock_converter( 1, &ns_converter );
+        Cyg_Clock::real_time_clock->get_other_to_clock_converter( 1000000000, &sec_converter );
+        Cyg_Clock::real_time_clock->get_clock_to_other_converter( 1, &ns_inverter );    
+        Cyg_Clock::real_time_clock->get_clock_to_other_converter( 1000000000, &sec_inverter );
+
+        tickns = Cyg_Clock::convert( 1, &ns_inverter );
+            
+        converters_initialized = true;
+    }
+}
+
+static cyg_bool valid_timespec( const struct timespec *tp )
+{
+    // Fail a NULL pointer
+    if( tp == NULL ) return false;
+
+    // Fail illegal nanosecond values
+    if( tp->tv_nsec < 0 || tp->tv_nsec > 1000000000 )
+        return false;
+
+    return true;
+}
+
+externC cyg_tick_count cyg_timespec_to_ticks( const struct timespec *tp,
+                                              cyg_bool roundup)
+{
+    init_converters();
+
+    // Short circuit zero timespecs
+    if( tp->tv_sec == 0 && tp->tv_nsec == 0 )
+    {
+        return 0;
+    }
+        
+    // Convert the seconds field to ticks.
+    cyg_tick_count ticks = Cyg_Clock::convert( tp->tv_sec, &sec_converter );
+
+    if( roundup )
+    {
+        // Convert the nanoseconds. We add (tickns-1) to round the value up
+        // to the next whole tick.
+
+        ticks += Cyg_Clock::convert( (cyg_tick_count)tp->tv_nsec+tickns-1, &ns_converter );    
+    }
+    else
+    {
+        // Convert the nanoseconds. This will round down to nearest whole tick.
+        ticks += Cyg_Clock::convert( (cyg_tick_count)tp->tv_nsec, &ns_converter );
+    }
+
+    return ticks;
+}
+
+externC void cyg_ticks_to_timespec( cyg_tick_count ticks, struct timespec *tp )
+{
+    init_converters();
+
+    // short circuit zero ticks values
+    if( ticks == 0 )
+    {
+        tp->tv_sec = 0;
+        tp->tv_nsec = 0;
+        return;
+    }
+
+    // Convert everything to nanoseconds with a long long. For 64-bits,
+    // this is safe for 544 years. We'll think about it more closer to
+    // the time...
+
+    unsigned long long nsecs = Cyg_Clock::convert( ticks, &ns_inverter );
+
+    tp->tv_sec = (long)(nsecs / 1000000000ll);
+    tp->tv_nsec = (long)(nsecs % 1000000000ll);
+
+    CYG_POSTCONDITION(valid_timespec(tp), "Failed to make valid timespec!");
+}
+
+//==========================================================================
+// Startup routine.
+
+externC void cyg_posix_clock_start()
+{
+    init_converters();
+}
+
+#ifdef CYGPKG_POSIX_TIMERS
+//==========================================================================
+// Alarm action routine
+// This is called each time an alarm set up by a timer expires.
+
+static void alarm_action( Cyg_Alarm *alarm, CYG_ADDRWORD data )
+{
+    posix_timer *timer = (posix_timer *)data;
+
+    if( timer->pending )
+    {
+        // If the pending flag is already set, count an overrun and
+        // do not bother to try and deliver the expiry.
+        
+        timer->overrun++;
+    }
+    else
+    {
+        if( timer->sigev.sigev_notify == SIGEV_SIGNAL )
+        {
+            // Set the expiry pending and wake a thread to
+            // deliver the signal.
+        
+            timer->pending = true;
+    
+            sigset_t mask;
+            sigemptyset( &mask );
+            sigaddset( &mask, timer->sigev.sigev_signo );
+            cyg_posix_signal_sigwait();
+            cyg_posix_pthread_release_thread( &mask );
+        }
+        else if( timer->sigev.sigev_notify == SIGEV_THREAD )
+        {
+            // Thread style notification
+            // FIXME: implement SIGEV_THREAD
+        }
+        // else do nothing
+    }
+}
+
+//==========================================================================
+// Timer ASR routine
+
+externC void cyg_posix_timer_asr( pthread_info *self )
+{
+
+    // Loop over the timers looking for any that have an
+    // expiry pending and call cyg_sigqueue() for each.
+    
+    for( int i = 0; i < _POSIX_TIMER_MAX; i++ )
+    {
+        posix_timer *timer = &timer_table[i];
+
+        if( timer->id != 0 && timer->pending )
+        {
+            timer->pending = false;
+                
+            // Call into signal subsystem...
+            cyg_sigqueue( &timer->sigev, SI_TIMER );
+
+            timer->overrun = 0;
+        }
+    }
+}
+
+#endif // ifdef CYGPKG_POSIX_TIMERS
+
+//==========================================================================
+// Clock functions
+
+//-----------------------------------------------------------------------------
+// Set the clocks current time
+
+externC int clock_settime( clockid_t clock_id, const struct timespec *tp)
+{
+    TIME_ENTRY();
+
+    if( clock_id != CLOCK_REALTIME )
+        TIME_RETURN(EINVAL);
+
+    if( !valid_timespec( tp ) )
+        TIME_RETURN(EINVAL);
+        
+    cyg_tick_count ticks = cyg_timespec_to_ticks( tp );
+
+    Cyg_Clock::real_time_clock->set_value( ticks );
+    
+    TIME_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Get the clocks current time
+
+externC int clock_gettime( clockid_t clock_id, struct timespec *tp)
+{
+    TIME_ENTRY();
+
+    if( clock_id != CLOCK_REALTIME )
+        TIME_RETURN(EINVAL);
+
+    if( tp == NULL )
+        TIME_RETURN(EINVAL);
+    
+    cyg_tick_count ticks = Cyg_Clock::real_time_clock->current_value();
+
+    cyg_ticks_to_timespec( ticks, tp );
+
+    TIME_RETURN(0);
+}
+   
+
+//-----------------------------------------------------------------------------
+// Get the clocks resolution
+
+externC int clock_getres( clockid_t clock_id, struct timespec *tp)
+{
+    TIME_ENTRY();
+
+    if( clock_id != CLOCK_REALTIME )
+        TIME_RETURN(EINVAL);
+
+    if( tp == NULL )
+        TIME_RETURN(EINVAL);
+
+    // Get the resolution of 1 tick
+    cyg_ticks_to_timespec( 1, tp );
+    
+    TIME_RETURN(0);
+}
+    
+
+//==========================================================================
+// Timer functions
+
+#ifdef CYGPKG_POSIX_TIMERS
+
+//-----------------------------------------------------------------------------
+// Create a timer based on the given clock.
+
+externC int timer_create( clockid_t clock_id,
+                          struct sigevent *evp,
+                          timer_t *timer_id)
+{
+    TIME_ENTRY();
+
+    if( clock_id != CLOCK_REALTIME )
+        TIME_RETURN(EINVAL);
+
+    timer_mutex.lock();
+
+    posix_timer *timer;
+    int next = timer_next;
+
+    // Look for an unused slot in the table
+    while( timer_table[next].id != 0 )
+    {
+        next++;
+        if( next >= _POSIX_TIMER_MAX )
+            next = 0;
+
+        if( next == timer_next )
+        {
+            timer_mutex.unlock();
+            TIME_RETURN(EAGAIN);
+        }
+    }
+
+    timer = &timer_table[next];
+
+    timer_next = next;
+
+    // Make sure we never allocate a zero timer id.
+    while( timer->id == 0 )
+    {
+        timer_id_cookie += TIMER_ID_COOKIE_INC;
+        timer->id        = next+timer_id_cookie;
+    }
+
+    if( evp == NULL )
+    {
+        // If no evp is supplied, set up the timer
+        // to use a default set.
+        timer->sigev.sigev_notify               = SIGEV_SIGNAL;
+        timer->sigev.sigev_signo                = SIGALRM;
+        timer->sigev.sigev_value.sival_int      = timer->id;
+    }
+    else timer->sigev = *evp;
+        
+    timer->alarm        = new( timer->alarm_obj )
+                               Cyg_Alarm( Cyg_Clock::real_time_clock,
+                                          alarm_action,
+                                          (CYG_ADDRWORD)timer );
+
+    timer->armed        = false;
+    timer->overrun      = 0;
+
+    *timer_id = timer->id;
+    
+    timer_mutex.unlock();
+    
+    TIME_RETURN(0);
+}
+
+//-----------------------------------------------------------------------------
+// Delete the timer
+
+externC int timer_delete( timer_t timerid )
+{
+    int err = EINVAL;
+    TIME_ENTRY();
+    
+    posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
+
+    timer_mutex.lock();
+
+    if( timer->id == timerid )
+    {
+        // This is a valid timer, disable the kernel
+        // alarm and delete it.
+
+        // disable alarm
+        timer->alarm->disable();
+
+        // destroy it
+        timer->alarm->~Cyg_Alarm();
+
+        // Mark POSIX timer free
+        timer->id = 0;
+
+        err = 0;
+    }
+
+    timer_mutex.unlock();
+    
+    TIME_RETURN( err );
+}
+
+//-----------------------------------------------------------------------------
+// Set the expiration time of the timer.
+
+externC int timer_settime( timer_t timerid, int flags,
+                           const struct itimerspec *value,
+                           struct itimerspec *ovalue )
+{
+    int err = EINVAL;
+    TIME_ENTRY();
+    
+    if( value == NULL )
+        TIME_RETURN(EINVAL);
+
+    // convert trigger and interval values to ticks.
+    cyg_tick_count trigger = cyg_timespec_to_ticks( &value->it_value, true );
+    cyg_tick_count interval = cyg_timespec_to_ticks( &value->it_interval, true );
+    
+    posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
+
+    timer_mutex.lock();
+
+    if( timer->id == timerid )
+    {
+        // disable the timer
+        timer->alarm->disable();
+        
+        if( ovalue != NULL )
+        {
+            cyg_tick_count otrigger, ointerval;
+
+            timer->alarm->get_times( &otrigger, &ointerval );
+
+            if( timer->armed )
+            {
+                // convert absolute trigger time to interval until next trigger
+                otrigger -= Cyg_Clock::real_time_clock->current_value();
+            }
+            else otrigger = 0;
+
+            // convert ticks to timespecs
+            cyg_ticks_to_timespec( otrigger, &ovalue->it_value );
+            cyg_ticks_to_timespec( ointerval, &ovalue->it_interval );
+        }
+        
+        if( trigger == 0 )
+        {
+            // Mark timer disarmed
+            timer->armed = false;            
+        }
+        else
+        {
+            // If the ABSTIME flag is not set, add the current time
+            if( (flags & TIMER_ABSTIME) == 0 )
+                trigger += Cyg_Clock::real_time_clock->current_value();
+
+            // Set the alarm running.
+            timer->alarm->initialize( trigger, interval );
+
+            // Mark timer armed
+            timer->armed = true;
+
+        }
+        
+        err = 0;
+    }
+    
+    timer_mutex.unlock();
+    
+    TIME_RETURN(err);
+}
+
+//-----------------------------------------------------------------------------
+// Get current timer values
+
+externC int timer_gettime( timer_t timerid, struct itimerspec *value )
+{
+    int err = EINVAL;
+
+    TIME_ENTRY();
+    
+    if( value == NULL )
+        TIME_RETURN(EINVAL);
+    
+    posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
+
+    timer_mutex.lock();
+
+    if( timer->id == timerid )
+    {
+        cyg_tick_count trigger, interval;
+
+        timer->alarm->get_times( &trigger, &interval );
+
+        if( timer->armed )
+        {
+            // convert absolute trigger time to interval until next trigger
+            trigger -= Cyg_Clock::real_time_clock->current_value();
+        }
+        else trigger = 0;
+
+        // convert ticks to timespecs
+        cyg_ticks_to_timespec( trigger, &value->it_value );
+        cyg_ticks_to_timespec( interval, &value->it_interval );
+        err = 0;
+    }
+    
+    timer_mutex.unlock();
+    
+    TIME_RETURN(err);
+}
+
+//-----------------------------------------------------------------------------
+// Get number of missed triggers
+
+externC int timer_getoverrun( timer_t timerid )
+{
+    int overrun = 0;
+    
+    TIME_ENTRY();
+
+    posix_timer *timer = &timer_table[timerid & TIMER_ID_COOKIE_MASK];
+
+    timer_mutex.lock();
+
+    if( timer->id == timerid )
+    {
+        overrun = timer->overrun;
+    }
+    
+    timer_mutex.unlock();
+    
+    CYG_REPORT_RETVAL(overrun);
+    return overrun;
+}
+
+#endif // ifdef CYGPKG_POSIX_TIMERS
+
+//==========================================================================
+// Nanosleep
+// Sleep for the given time.
+
+externC int nanosleep( const struct timespec *rqtp,
+                       struct timespec *rmtp)
+{
+    cyg_tick_count ticks, now, then;
+
+    TIME_ENTRY();
+
+    // check for cancellation first.
+    PTHREAD_TESTCANCEL();
+
+    // Fail an invalid timespec
+    if( !valid_timespec( rqtp ) )
+        TIME_RETURN(EINVAL);
+
+    // Return immediately for a zero delay.
+    if( rqtp->tv_sec == 0 && rqtp->tv_nsec == 0 )
+        TIME_RETURN(0);
+
+    // Convert timespec to ticks
+    ticks = cyg_timespec_to_ticks( rqtp, true );
+
+    CYG_ASSERT( ticks != 0, "Zero tick count");
+    
+    Cyg_Thread *self = Cyg_Thread::self();
+    
+    // Do the delay, keeping track of how long we actually slept for.
+    then = Cyg_Clock::real_time_clock->current_value();
+
+    self->delay( ticks );
+
+    now = Cyg_Clock::real_time_clock->current_value();
+
+    
+    if( rmtp != NULL && (then+ticks) > now )
+    {
+        // We woke up early, return the time left.
+        // FIXME: strictly we only need to do this if we were woken
+        //        by a signal.
+
+        // Calculate remaining number of ticks.
+        ticks -= (now-then);
+
+        cyg_ticks_to_timespec( ticks, rmtp );
+    }
+    
+    // check if we were woken up because we were cancelled.
+    PTHREAD_TESTCANCEL();
+
+    TIME_RETURN(0);
+}    
+
+// -------------------------------------------------------------------------
+// Wait for a signal, or the given number of seconds
+
+externC unsigned int sleep( unsigned int seconds )
+{
+    TIME_ENTRY();
+
+    struct timespec timeout;
+
+    timeout.tv_sec = seconds;
+    timeout.tv_nsec = 0;
+
+    if( nanosleep( &timeout, &timeout ) != 0 )
+    {
+        CYG_REPORT_RETVAL(timeout.tv_sec);
+        return timeout.tv_sec;
+    }
+
+    TIME_RETURN(0);
+} 
+
+#endif // ifdef CYGPKG_POSIX_CLOCKS
+
+// -------------------------------------------------------------------------
+// EOF time.cxx
diff --git a/packages/compat/posix/v2_0/tests/mqueue1.c b/packages/compat/posix/v2_0/tests/mqueue1.c
new file mode 100644 (file)
index 0000000..0c66284
--- /dev/null
@@ -0,0 +1,359 @@
+/*========================================================================
+//
+//      mqueue1.c
+//
+//      POSIX Message queues tests
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     jlarmour
+// Contributors:  
+// Date:          2000-05-18
+// Purpose:       This file provides tests for POSIX mqueues
+// Description:   
+// Usage:         
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/posix.h>
+
+#ifndef CYGPKG_POSIX_MQUEUES
+# define NA_MSG "Message queues not configured"
+#endif
+
+#ifdef NA_MSG
+#include <cyg/infra/testcase.h>      // test API
+void
+cyg_user_start(void)
+{
+    CYG_TEST_NA( NA_MSG );
+}
+
+#else
+
+/* INCLUDES */
+
+#include <fcntl.h>                   // O_*
+#include <errno.h>                   // errno
+#include <sys/stat.h>                // file modes
+#include <mqueue.h>                  // Mqueue Header
+#include <cyg/infra/testcase.h>      // test API
+
+/* FUNCTIONS */
+
+static int
+my_memcmp(const void *m1, const void *m2, size_t n)
+{
+    char *s1 = (char *)m1;
+    char *s2 = (char *)m2;
+
+    while (n--) {
+        if (*s1 != *s2)
+            return *s1 - *s2;
+        s1++;
+        s2++;
+    }
+    return 0;
+} // my_memcmp()
+
+//************************************************************************
+
+int
+main(void)
+{
+    mqd_t q1, q2;
+    char buf[20];
+    ssize_t recvlen;
+    unsigned int prio;
+    struct mq_attr attr, oattr;
+    mode_t mode;
+    int err;
+
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Starting POSIX message test 1" );
+
+    q1 = mq_open( "/mq1", O_RDWR );
+    CYG_TEST_PASS_FAIL( q1 == (mqd_t)-1, "error for non-existent queue" );
+    CYG_TEST_PASS_FAIL( ENOENT == errno,
+                        "errno correct for non-existent queue" );
+
+    attr.mq_flags = 0;
+    attr.mq_maxmsg = 4;
+    attr.mq_msgsize = 20;
+    mode = S_IRWXU|S_IRWXG|S_IRWXO; // rwx for all
+
+    q1 = mq_open( "/mq1", O_CREAT|O_NONBLOCK|O_WRONLY, mode, &attr );
+    CYG_TEST_PASS_FAIL( q1 != (mqd_t)-1, "simple mq_open (write only)" );
+    
+    err = mq_getattr( q1, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
+                        (0 == attr.mq_curmsgs ), "getattr attributes correct" );
+                        
+    err = mq_send( q1, "Vik is brill", sizeof("Vik is brill"), 10 );
+
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_send" );
+    
+    err = mq_getattr( q1, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr after send" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
+                        (1 == attr.mq_curmsgs ),
+                        "getattr attributes correct #2" );
+                        
+    q2 = mq_open( "/mq1", O_RDONLY|O_CREAT|O_EXCL );
+    CYG_TEST_PASS_FAIL( q2 == (mqd_t)-1,
+                        "error for exclusive open of existing queue" );
+    CYG_TEST_PASS_FAIL( EEXIST == errno,
+                        "errno correct for exclusive open of existing queue" );
+    
+    q2 = mq_open( "/mq1", O_RDONLY );
+    CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "simple mq_open (read only)" );
+    
+    err = mq_getattr( q2, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr, different mqd_t" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK != (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
+                        (1 == attr.mq_curmsgs ),
+                        "getattr attributes correct #3" );
+
+    err = mq_close( q2 );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_close" );
+    
+    q2 = mq_open( "/mq1", O_RDONLY );
+    CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "mq_open reopen (read only)" );
+    
+    err = mq_getattr( q2, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr, different mqd_t" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK != (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
+                        (1 == attr.mq_curmsgs ),
+                        "getattr attributes correct #4" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == sizeof("Vik is brill"),
+                        "receive message length" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "Vik is brill",
+                                        sizeof("Vik is brill")),
+                        "received message data intact" );
+    CYG_TEST_PASS_FAIL( 10 == prio, "received at correct priority" );
+
+    err = mq_getattr( q1, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr after send" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
+                        (0 == attr.mq_curmsgs ),
+                        "getattr attributes correct #5" );
+
+    attr.mq_flags |= O_NONBLOCK;
+    err = mq_setattr( q2, &attr, &oattr );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_setattr O_NONBLOCK" );
+    CYG_TEST_PASS_FAIL( (4 == oattr.mq_maxmsg) &&
+                        (20 == oattr.mq_msgsize) &&
+                        (O_NONBLOCK != (oattr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY == (oattr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY != (oattr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (oattr.mq_flags & O_RDWR)) &&
+                        (0 == oattr.mq_curmsgs ),
+                        "old attribute correct" );
+    err = mq_getattr( q2, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_getattr after O_NONBLOCK" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
+                        (0 == attr.mq_curmsgs ),
+                        "new attribute correct" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
+                        "mq_receive, empty buffer, non-blocking" );
+    CYG_TEST_PASS_FAIL( EAGAIN == errno,
+                        "errno correct for non-blocking" );
+    
+    err = mq_send( q2, "foo", sizeof("foo"), 1 );
+    CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send on read-only descriptor" );
+    CYG_TEST_PASS_FAIL( EBADF == errno,
+                        "errno correct for mq_send on r/o descriptor" );
+    
+    err = mq_send( q2, "supercalifragilisticexpealidocious", 21, 2 );
+    CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send (message too long)" );
+    CYG_TEST_PASS_FAIL( EMSGSIZE == errno,
+                        "errno correct for mq_send (message too long)" );
+    
+    err = mq_send( q1, "", sizeof(""), 5 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send \"\"" );
+    
+    err = mq_send( q1, "I love Vik", sizeof("I love Vik"), 7 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (different priority)" );
+    
+    err = mq_send( q1, "a lot!", sizeof("a lot!"), 7 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (same priority)" );
+    
+    err = mq_send( q1, "Vik is a babe", sizeof("Vik is a babe"), 6 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (middle priority)" );
+    
+    err = mq_send( q1, "wibble", sizeof("wibble"), 6 );
+    CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send with full queue" );
+    CYG_TEST_PASS_FAIL( EAGAIN == errno,
+                        "errno correct for mq_send full queue" );
+    
+    err = mq_getattr( q2, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_getattr after sends" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
+                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
+                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
+                        (4 == attr.mq_curmsgs ),
+                        "getattr attributes correct #5" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == sizeof("I love Vik"),
+                        "receive message length (prioritized) #1" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "I love Vik",
+                                        sizeof("I love Vik")),
+                        "received message data intact (prioritized) #1" );
+    CYG_TEST_PASS_FAIL( 7 == prio,
+                        "received at correct priority (prioritized) #1" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == sizeof("a lot!"),
+                        "receive message length (prioritized) #2" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "a lot!",
+                                        sizeof("a lot!")),
+                        "received message data intact (prioritized) #2" );
+    CYG_TEST_PASS_FAIL( 7 == prio,
+                        "received at correct priority (prioritized) #2" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == sizeof("Vik is a babe"),
+                        "receive message length (prioritized) #3" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "Vik is a babe",
+                                        sizeof("Vik is a babe")),
+                        "received message data intact (prioritized) #3" );
+    CYG_TEST_PASS_FAIL( 6 == prio,
+                        "received at correct priority (prioritized) #3" );
+
+    recvlen = mq_receive( q2, buf, 0, &prio );
+    CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
+                        "mq_receive, zero-sized buffer" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == sizeof(""),
+                        "receive message length (prioritized) #4" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "",
+                                        sizeof("")),
+                        "received message data intact (prioritized) #4" );
+    CYG_TEST_PASS_FAIL( 5 == prio,
+                        "received at correct priority (prioritzed) #4" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
+                        "mq_receive, empty buffer, non-blocking #2" );
+    CYG_TEST_PASS_FAIL( EAGAIN == errno,
+                        "errno correct for non-blocking #2" );
+    
+    err = mq_send( q1, "12345678901234567890", 20, 15 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (before closing)" );
+    
+    err = mq_unlink( "/foo" );
+    CYG_TEST_PASS_FAIL( -1 == err, "mq_unlink (wrong name)" );
+    CYG_TEST_PASS_FAIL( ENOENT == errno,
+                        "errno correct for mq_unlink (wrong name)" );
+
+    err = mq_unlink( "/mq1" );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_unlink (before closing)" );
+
+    err = mq_close( q1 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_close (send descriptor)" );
+
+    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
+    CYG_TEST_PASS_FAIL( recvlen == 20,
+                        "receive message length (mid close)" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "12345678901234567890", 20 ),
+                        "received message data intact (mid close)" );
+    CYG_TEST_PASS_FAIL( 15 == prio,
+                        "received at correct priority (mid close)" );
+
+    err = mq_close( q2 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_close (receive descriptor)" );
+
+    q1 = mq_open( "/mq1", O_RDONLY );
+    CYG_TEST_PASS_FAIL( q1 == (mqd_t)-1, "error for non-existent queue" );
+    CYG_TEST_PASS_FAIL( ENOENT == errno,
+                        "errno correct for non-existent queue" );
+
+    CYG_TEST_EXIT("POSIX message test 1");
+
+    return 0;
+} // main()
+
+//------------------------------------------------------------------------
+
+#endif
+
+/* EOF mqueue1.c */
diff --git a/packages/compat/posix/v2_0/tests/mqueue2.c b/packages/compat/posix/v2_0/tests/mqueue2.c
new file mode 100644 (file)
index 0000000..f140550
--- /dev/null
@@ -0,0 +1,276 @@
+/*========================================================================
+//
+//      mqueue2.c
+//
+//      POSIX Message queues tests - mq_notify
+//
+//========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     jlarmour
+// Contributors:  
+// Date:          2000-05-18
+// Purpose:       This file provides tests for POSIX mqueue mq_notify
+// Description:   
+// Usage:         
+//
+//####DESCRIPTIONEND####
+//
+//======================================================================
+*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/posix.h>
+
+#ifndef CYGPKG_POSIX_MQUEUES
+# define NA_MSG "Message queues not configured"
+#elif !defined(CYGPKG_POSIX_SIGNALS)
+# define NA_MSG "No POSIX signals configured"
+#endif
+
+#ifdef NA_MSG
+#include <cyg/infra/testcase.h>      // test API
+void
+cyg_user_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( NA_MSG );
+}
+
+#else
+
+/* INCLUDES */
+
+#include <fcntl.h>                   // O_*
+#include <errno.h>                   // errno
+#include <sys/stat.h>                // file modes
+#include <mqueue.h>                  // Mqueue Header
+#include <cyg/infra/testcase.h>      // test API
+#include <signal.h>                  // signals
+
+/* GLOBALS */
+sig_atomic_t signals=0;
+char buf[20];
+unsigned int prio;
+
+
+/* FUNCTIONS */
+
+static int
+my_memcmp(const void *m1, const void *m2, size_t n)
+{
+    char *s1 = (char *)m1;
+    char *s2 = (char *)m2;
+
+    while (n--) {
+        if (*s1 != *s2)
+            return *s1 - *s2;
+        s1++;
+        s2++;
+    }
+    return 0;
+} // my_memcmp()
+
+static char *
+my_strcpy(char *s1, const char *s2)
+{
+    char *s = s1;
+    while (*s2) {
+        *s1++ = *s2++;
+    }
+    return s;
+} // my_strcpy()
+
+static size_t
+my_strlen(const char *s)
+{
+    const char *start = s;
+    while (*s)
+        s++;
+    return (s - start);
+} // my_strcpy()
+
+
+
+//************************************************************************
+
+static void
+sigusr1_handler( int signo, siginfo_t *info, void *context )
+{
+    ssize_t recvlen;
+    char mybuf[20];
+    unsigned int myprio;
+    mqd_t *q = (mqd_t *)info->si_value.sival_ptr;
+
+    CYG_TEST_PASS_FAIL( SIGUSR1 == signo, "correct signal number #1" );
+    CYG_TEST_PASS_FAIL( SIGUSR1 == info->si_signo, "correct signal number #2" );
+    CYG_TEST_PASS_FAIL( SI_MESGQ == info->si_code, "correct signal code" );
+
+    signals++;
+
+    // retrieve message and compare with buf
+    recvlen = mq_receive( *q, mybuf, sizeof(mybuf), &myprio );
+    CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
+                        "receive message length" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
+                        "received message data intact" );
+    CYG_TEST_PASS_FAIL( prio == myprio,
+                        "received at correct priority" );
+}
+
+//************************************************************************
+
+int
+main(void)
+{
+    mqd_t q1;
+    struct mq_attr attr;
+    mode_t mode;
+    int err;
+    ssize_t recvlen;
+    char mybuf[20];
+    unsigned int myprio;
+    struct sigevent ev;
+    struct sigaction act;
+
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Starting POSIX message test 2" );
+
+#if 0
+    if ( 0 != pthread_create( &thr, NULL, &thread, NULL ) ) {
+        CYG_TEST_FAIL_FINISH( "Couldn't create a helper thread" );
+    }
+#endif
+
+    attr.mq_flags = 0;
+    attr.mq_maxmsg = 4;
+    attr.mq_msgsize = 20;
+    mode = S_IRWXU|S_IRWXG|S_IRWXO; // rwx for all
+
+    q1 = mq_open( "/mq1", O_CREAT|O_NONBLOCK|O_RDWR, mode, &attr );
+    CYG_TEST_PASS_FAIL( q1 != (mqd_t)-1, "simple mq_open (write only)" );
+    
+    err = mq_getattr( q1, &attr );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr" );
+    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
+                        (20 == attr.mq_msgsize) &&
+                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
+                        (O_RDWR == (attr.mq_flags & O_RDWR)) &&
+                        (0 == attr.mq_curmsgs ), "getattr attributes correct" );
+
+
+    act.sa_sigaction = &sigusr1_handler;
+    sigfillset( &act.sa_mask ); // enable all signals
+    act.sa_flags = SA_SIGINFO;
+    
+    if ( 0 != sigaction( SIGUSR1, &act, NULL ) ) {
+        CYG_TEST_FAIL_FINISH( "Couldn't register signal handler" );
+    }
+
+    ev.sigev_notify = SIGEV_SIGNAL;
+    ev.sigev_signo = SIGUSR1;
+    ev.sigev_value.sival_ptr = (void *)&q1;
+
+    err = mq_notify( q1, &ev );
+    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_notify" );
+
+    my_strcpy( buf, "Vik is the best" );
+    prio = 7;
+    err = mq_send( q1, buf, my_strlen(buf), prio );
+
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send #1" );
+
+    CYG_TEST_PASS_FAIL( 1 == signals, "got notification" );
+
+    my_strcpy( buf, "Scrummy Vik" );
+    prio = 6;
+    err = mq_send( q1, buf, my_strlen(buf), prio );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send #2" );
+
+    CYG_TEST_PASS_FAIL( 1 == signals, "correctly didn't get notification" );
+
+    recvlen = mq_receive( q1, mybuf, sizeof(mybuf), &myprio );
+    CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
+                        "receive message length" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
+                        "received message data intact" );
+    CYG_TEST_PASS_FAIL( prio == myprio,
+                        "received at correct priority" );
+
+    err = mq_notify( q1, &ev );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_notify #2" );
+
+    err = mq_notify( q1, &ev );
+    CYG_TEST_PASS_FAIL( -1 == err, "second mq_notify returns error" );
+    CYG_TEST_PASS_FAIL( EBUSY == errno,
+                        "errno correct for second mq_notify error" );
+
+    err = mq_notify( q1, NULL );
+    CYG_TEST_PASS_FAIL( 0 == err, "clear notification" );
+
+    my_strcpy( buf, "Vik is k3wl" );
+    prio = 8;
+    err = mq_send( q1, buf, my_strlen(buf), prio );
+
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_send #2" );
+
+    CYG_TEST_PASS_FAIL( 1 == signals, "correctly didn't get notification #2" );
+
+    recvlen = mq_receive( q1, mybuf, sizeof(mybuf), &myprio );
+    CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
+                        "receive message length" );
+    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
+                        "received message data intact" );
+    CYG_TEST_PASS_FAIL( prio == myprio,
+                        "received at correct priority" );
+    
+    err = mq_close( q1 );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_close" );
+
+    err = mq_unlink( "/mq1" );
+    CYG_TEST_PASS_FAIL( 0 == err, "mq_unlink" );
+
+    CYG_TEST_EXIT("POSIX message test 2");
+
+    return 0;
+} // main()
+
+//------------------------------------------------------------------------
+
+#endif
+
+/* EOF mqueue2.c */
diff --git a/packages/compat/posix/v2_0/tests/mutex3.c b/packages/compat/posix/v2_0/tests/mutex3.c
new file mode 100644 (file)
index 0000000..c35d9ef
--- /dev/null
@@ -0,0 +1,672 @@
+//==========================================================================
+//
+//        mutex3.cxx
+//
+//        Mutex test 3 - priority inheritance
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     hmt
+// Contributors:  hmt, nickg, jlarmour
+// Date:          2000-01-06
+// Description:   Tests mutex priority inheritance. This is simply a translation
+//                of the similarly named kernel test to the POSIX API
+//####DESCRIPTIONEND####
+
+// ------------------------------------------------------------------------
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+#include <pkgconf/system.h>
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif
+
+#ifdef CYGPKG_ISOINFRA
+# include <sys/types.h>
+# include <pthread.h>
+# include <semaphore.h>
+# include <time.h>
+# include <unistd.h>
+#endif
+
+#if !defined(CYGPKG_POSIX_PTHREAD)
+#define NA_MSG "POSIX threads not enabled"
+
+// ------------------------------------------------------------------------
+//
+// These checks should be enough; any other scheduler which has priorities
+// should manifest as having no priority inheritance, but otherwise fine,
+// so the test should work correctly.
+
+#elif !defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+#define NA_MSG "No POSIX thread priority scheduling enabled"
+#elif !defined(_POSIX_THREAD_PRIO_INHERIT)
+#define NA_MSG "No POSIX thread priority inheritance enabled"
+#elif !defined(_POSIX_SEMAPHORES)
+#define NA_MSG "No POSIX sempaphore support enabled enabled"
+#elif !defined(CYGFUN_KERNEL_API_C)
+#define NA_MSG "Kernel C API not enabled"
+#elif defined(CYGPKG_KERNEL_SMP_SUPPORT)
+#define NA_MSG "Test cannot run with SMP support"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/cyg_trac.h>
+#include <cyg/infra/diag.h>             // diag_printf
+
+#include <cyg/kernel/kapi.h>            // Some extras
+
+// ------------------------------------------------------------------------
+// Management functions
+//
+// Stolen from testaux.hxx and copied in here because I want to be able to
+// reset the world also.
+// ... and subsequently POSIXized out of all similarly with its progenitors.
+
+#define NTHREADS 7
+
+#define STACKSIZE (PTHREAD_STACK_MIN*2)
+
+static pthread_t thread[NTHREADS] = { 0 };
+
+typedef CYG_WORD64 CYG_ALIGNMENT_TYPE;
+
+static CYG_ALIGNMENT_TYPE stack[NTHREADS] [
+   (STACKSIZE+sizeof(CYG_ALIGNMENT_TYPE)-1)
+     / sizeof(CYG_ALIGNMENT_TYPE)                     ];
+
+// Semaphores to halt execution of threads     
+static sem_t hold[NTHREADS];
+
+// Flag to tell all threads to exit
+static int all_exit;
+
+// Application thread data is passed here, the thread
+// argument is 
+static CYG_ADDRWORD thread_data[NTHREADS];
+
+static volatile int nthreads = 0;
+
+// Sleep for 1 tick...
+static struct timespec sleeptime;
+
+
+static pthread_t new_thread( void *(*entry)(void *),
+                             CYG_ADDRWORD data,
+                             int priority,
+                             int do_resume)
+{
+    pthread_attr_t attr;
+    int _nthreads = nthreads++;
+
+    struct sched_param schedparam;
+    schedparam.sched_priority = priority;
+        
+    pthread_attr_init( &attr );
+    pthread_attr_setstackaddr( &attr, (void *)((char *)(&stack[_nthreads])+STACKSIZE) );        
+    pthread_attr_setstacksize( &attr, STACKSIZE );
+    pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+    pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    CYG_ASSERT(_nthreads < NTHREADS, 
+               "Attempt to create more than NTHREADS threads");
+
+    thread_data[_nthreads] = data;
+
+    sem_init( &hold[_nthreads], 0, do_resume ? 1 : 0 );
+    all_exit = 0;
+
+    pthread_create( &thread[_nthreads],
+                    &attr,
+                    entry,
+                    (void *)_nthreads);
+
+    return thread[_nthreads];
+}
+
+
+static void kill_threads( void )
+{
+    CYG_ASSERT(nthreads <= NTHREADS, 
+               "More than NTHREADS threads");
+    CYG_ASSERT( pthread_equal(pthread_self(),thread[0]),
+                "kill_threads() not called from thread 0");
+    all_exit = 1;
+    while ( nthreads > 1 ) {
+        nthreads--;
+        if ( 0 != thread[nthreads] ) {
+            sem_post( &hold[nthreads] );
+            pthread_cancel( thread[nthreads] );
+            pthread_join( thread[nthreads], NULL );
+            thread[nthreads] = 0;
+            sem_destroy( &hold[nthreads] );
+        }
+    }
+    CYG_ASSERT(nthreads == 1,
+               "No threads left");
+}
+
+// ------------------------------------------------------------------------
+
+#define DELAYFACTOR 1 // for debugging
+
+// ------------------------------------------------------------------------
+
+pthread_mutex_t mutex;
+
+// These are for reporting back to the master thread
+volatile int got_it  = 0;
+volatile int t3ran   = 0;
+volatile int t3ended = 0;
+volatile int extras[4] = {0,0,0,0};
+    
+volatile int go_flag = 0; // but this one controls thread 3 from thread 2
+
+// ------------------------------------------------------------------------
+// 0 to 3 of these run generally to interfere with the other processing,
+// to cause multiple prio inheritances, and clashes in any orders.
+
+static void *extra_thread( void *arg )
+{
+#define XINFO( z ) \
+    do { z[13] = '0' + data; CYG_TEST_INFO( z ); } while ( 0 )
+
+    static char running[]  = "Extra thread Xa running";
+    static char exiting[]  = "Extra thread Xa exiting";
+    static char resumed[]  = "Extra thread Xa resumed";
+    static char locked[]   = "Extra thread Xa locked";
+    static char unlocked[] = "Extra thread Xa unlocked";
+
+    int id = (int)arg;
+    CYG_ADDRWORD data = thread_data[id];
+
+    CYG_ASSERT( (id >= 4 && id <= 6), "extra_thread invalid id" );
+    
+    // Emulate resume behaviour
+    sem_wait( &hold[id] );
+    if( all_exit ) return 0;
+    
+    XINFO( running );
+
+    sem_wait( &hold[id] );
+    
+    XINFO( resumed );
+
+    pthread_mutex_lock( &mutex );
+
+    XINFO( locked );
+
+    pthread_mutex_unlock( &mutex );    
+
+    XINFO( unlocked );
+
+    extras[ data ] ++;
+
+    XINFO( exiting );
+
+    return NULL;
+}
+
+// ------------------------------------------------------------------------
+
+static void *t1( void *arg )
+{
+    int id = (int)arg;
+    //CYG_ADDRWORD data = thread_data[id];
+    
+    // Emulate resume behaviour
+    sem_wait( &hold[id] );
+    if( all_exit ) return 0;
+
+    CYG_TEST_INFO( "Thread 1 running" );
+
+    sem_wait( &hold[id] );    
+
+    pthread_mutex_lock( &mutex );
+
+    got_it++;
+
+    CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,1]" );
+
+    pthread_mutex_unlock( &mutex );
+
+    CYG_TEST_CHECK( 0 == t3ended, "T3 ended prematurely [T1,2]" );
+
+    // That's all.
+
+    CYG_TEST_INFO( "Thread 1 exit" );
+
+    return 0;    
+}
+
+// ------------------------------------------------------------------------
+
+static void *t2( void *arg )
+{
+    int i;
+    int id = (int)arg;
+    CYG_ADDRWORD data = thread_data[id];
+    cyg_tick_count_t now, then;
+    
+    // Emulate resume behaviour
+    sem_wait( &hold[id] );
+    if( all_exit ) return 0;
+
+    CYG_TEST_INFO( "Thread 2 running" );
+
+    CYG_TEST_CHECK( 0 == (data & ~0x77), "Bad T2 arg: extra bits" );
+    CYG_TEST_CHECK( 0 == (data & (data >> 4)), "Bad T2 arg: overlap" );
+
+    sem_wait( &hold[id] );
+
+    // depending on our config argument, optionally restart some of the
+    // extra threads to throw noise into the scheduler:
+    for ( i = 0; i < 3; i++ )
+        if ( (1 << i) & data )          // bits 0-2 control
+            sem_post( &hold[i+4] );     // made sure extras are thread[4-6]
+
+    // let those threads run
+    for( i = 0; i < DELAYFACTOR * 10; i++ )
+        nanosleep( &sleeptime, NULL );
+
+    cyg_scheduler_lock();               // do this next lot atomically
+
+    go_flag = 1;                        // unleash thread 3
+    sem_post( &hold[1] );               // resume thread 1
+
+    // depending on our config argument, optionally restart some of the
+    // extra threads to throw noise into the scheduler at this later point:
+    for ( i = 4; i < 7; i++ )
+        if ( (1 << i) & data )          // bits 4-6 control
+            sem_post( &hold[i] );       // made sure extras are thread[4-6]
+
+    cyg_scheduler_unlock();             // let scheduling proceed
+
+    // Need a delay (but not a CPU yield) to allow t3 to awaken and act on
+    // the go_flag, otherwise we check these details below too soon.
+    // Actually, waiting for the clock to tick a couple of times would be
+    // better, so that is what we will do.  Must be a busy-wait.
+    then = cyg_current_time();
+    do {
+        now = cyg_current_time();
+        // Wait longer than the delay in t3 waiting on go_flag
+    } while ( now < (then + 3) );
+
+#ifdef _POSIX_THREAD_PRIO_INHERIT
+    CYG_TEST_INFO( "Checking for mutex priority inheritance" );
+    CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+    CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+#else
+    CYG_TEST_INFO( "Checking for NO mutex priority inheritance" );
+    CYG_TEST_CHECK( 0 == t3ran, "Thread 3 DID run" );
+    CYG_TEST_CHECK( 0 == got_it, "Thread 1 DID get the mutex" );
+#endif
+
+    CYG_TEST_CHECK( 0 == t3ended, "Thread 3 ended prematurely [T2,1]" );
+
+    for( i = 0; i < DELAYFACTOR * 20; i++ )    
+        nanosleep( &sleeptime, NULL );      // let those threads run  
+
+    CYG_TEST_CHECK( 1 == t3ran, "Thread 3 did not run" );
+    CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+    CYG_TEST_CHECK( 1 == t3ended, "Thread 3 has not ended" );
+
+    for ( i = 0; i < 3; i++ )
+        if ( (1 << i) & (data | data >> 4) ) // bits 0-2 and 4-6 control
+            CYG_TEST_CHECK( 1 == extras[i+1], "Extra thread did not run" );
+        else
+            CYG_TEST_CHECK( 0 == extras[i+1], "Extra thread ran" );
+
+    CYG_TEST_PASS( "Thread 2 exiting, AOK" );
+    // That's all: restart the control thread.
+    sem_post( &hold[0] );
+
+    return 0;    
+}
+
+// ------------------------------------------------------------------------
+
+static void *t3( void *arg )
+{
+    int i;
+    int id = (int)arg;
+    //CYG_ADDRWORD data = thread_data[id];
+    
+    // Emulate resume behaviour
+    sem_wait( &hold[id] );
+    if( all_exit ) return 0;
+    
+    CYG_TEST_INFO( "Thread 3 running" );
+
+    pthread_mutex_lock( &mutex );
+
+    for( i = 0; i < DELAYFACTOR * 5; i++ )    
+        nanosleep( &sleeptime, NULL );      // let thread 3a run
+
+    sem_post( &hold[2] );               // resume thread 2
+
+    while ( 0 == go_flag )
+        nanosleep( &sleeptime, NULL );  // wait until we are told to go
+
+    t3ran ++;                           // record the fact
+
+    CYG_TEST_CHECK( 0 == got_it, "Thread 1 claims to have got my mutex" );
+
+    pthread_mutex_unlock( &mutex );
+
+    t3ended ++;                         // record that we came back
+
+    CYG_TEST_CHECK( 1 == got_it, "Thread 1 did not get the mutex" );
+
+    CYG_TEST_INFO( "Thread 3 exit" );
+
+    return 0;
+}
+
+// ------------------------------------------------------------------------
+
+static void *control_thread( void *arg )
+{
+    int i,z;
+    int id = (int)arg;
+    //CYG_ADDRWORD data = thread_data[id];
+    
+    // Emulate resume behaviour
+    sem_wait( &hold[id] );
+    if( all_exit ) return 0;
+    
+    // one tick sleep time
+    sleeptime.tv_nsec = 10000000;
+    sleeptime.tv_sec = 0;
+    
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Control Thread running" );
+
+    // Go through the 27 possibilitied of resuming the extra threads
+    //     0: not at all
+    //     1: early in the process
+    //     2: later on
+    // which are represented by bits 0-3 and 4-6 resp in the argument to
+    // thread 2 (none set means no resume at all).
+    for ( i = 0; i < 27; i++ ) {
+        static int xx[] = { 0, 1, 16 };
+        int j = i % 3;
+        int k = (i / 3) % 3;
+        int l = (i / 9) % 3;
+
+        int d = xx[j] | (xx[k]<<1) | (xx[l]<<2) ;
+
+        if ( cyg_test_is_simulator && (0 != i && 13 != i && 26 != i) )
+            continue;    // 13 is 111 base 3, 26 is 222 base 3
+
+#ifdef _POSIX_THREAD_PRIO_INHERIT
+        // If the simple scheme plus relay enhancement, or any other
+        // *complete* scheme, we can run all three ancillary threads no
+        // problem, so no special action here.
+
+#else
+        // If no priority inheritance at all, running threads 1a and 2a is
+        // OK, but not thread 3a; it blocks the world.
+        if ( l )                        // Cannot run thread 3a if no
+            break;                      //     priority inheritance at all.
+#endif
+
+        // Reinitialize mutex to provide priority inheritance
+        {
+            pthread_mutexattr_t attr;
+            pthread_mutexattr_init( &attr );
+            pthread_mutexattr_setprotocol( &attr, PTHREAD_PRIO_INHERIT );
+            pthread_mutex_init( &mutex, &attr );
+        }
+
+        got_it  = 0;
+        t3ran   = 0;
+        t3ended = 0;
+        for ( z = 0; z < 4; z++ ) extras[z] = 0;
+        go_flag = 0;
+        
+        new_thread( t1, 0, 15, 1 );            // Slot 1
+        new_thread( t2, d, 10, 1 );            // Slot 2
+        new_thread( t3, 0,  5, 1 );            // Slot 3
+        
+        new_thread( extra_thread, 1, 17, j );  // Slot 4
+        new_thread( extra_thread, 2, 12, k );  // Slot 5
+        new_thread( extra_thread, 3,  8, l );  // Slot 6
+        
+        {
+            static char *a[] = { "inactive", "run early", "run late" };
+            diag_printf( "\n----- [%2d] New Cycle: 0x%02x, Threads 1a %s, 2a %s, 3a %s -----\n",
+                         i, d,  a[j], a[k], a[l] );
+        }
+
+        sem_wait( &hold[0] );
+        
+        kill_threads();
+        pthread_mutex_destroy( &mutex );
+    }
+    CYG_TEST_EXIT( "Control Thread exit" );
+
+    return 0;
+}
+
+// ------------------------------------------------------------------------
+
+static sem_t main_sem;
+
+externC int
+main( int argc, char **argv )
+{ 
+    new_thread( control_thread, 0, 20, 1 );
+
+    // We have nothing for main to do here, so put it to sleep on
+    // its own semaphore. We cannot let it just exit since that
+    // will end the whole program.
+
+    sem_init( &main_sem, 0, 0 );
+    
+    for(;;) sem_wait( &main_sem );
+}
+
+// ------------------------------------------------------------------------
+// Documentation: enclosed is the design of this test.
+//
+// It has been carefully constructed so that it does NOT use other kernel
+// facilities (aside from delay-task) to test that priority inheritance is
+// working, or not, as intended by the configuration.
+//
+// These notes describe the flow of control in one run of the test with the
+// ancillary tasks optionally interspersed.  The details of how those extra
+// tasks are or are not allowed to run are not described.
+// 
+// 
+// 
+// The only change in the test that depends on whether there is inheritance or
+// not is the check in thread 2 on "3-ran" and "got it" flags marked ****
+// 
+// 
+// volatile &c booleans:
+//         "got it"     = FALSE
+//         "3-ran"      = FALSE
+//         "3-ended"    = FALSE
+//         "extras"[3]  = FALSE
+// 
+// thread 1.  prio 5, self-suspend.
+// 
+// thread 1a, prio 8, self-suspend.
+// 
+// thread 2.  prio 10, self-suspend.
+// 
+// thread 2a, prio 12, self-suspend.
+// 
+// thread 3.  prio 15, runs, lock mutex, resume(2)
+// 
+// thread 3a, prio 17, self-suspend.
+// 
+//        2.  runs,
+//        2.  resume(3a) +++OPTIONAL
+//        2.  resume(2a) +++OPTIONAL
+//        2.  resume(1a) +++OPTIONAL
+//        [1a lock-fail]       thread 3->prio := 8
+// 
+//        [3. runs maybe, does the looping thing]
+// 
+//        2.  sleep a while...
+// 
+//        [2a lock-fail]       thread 3->prio := 12
+// 
+//        [3. runs maybe, does the looping thing]
+// 
+//        [3a lock-fail]   thread 3->prio unchanged
+// 
+//        [3. runs maybe, does the looping thing]
+// 
+//        2.  lock scheduler
+//        2.  set "go-flag"
+//        2.  resume(1)
+//        2.  resume(1a) +++OPTIONAL
+//        2.  resume(2a) +++OPTIONAL
+//        2.  resume(3a) +++OPTIONAL
+//        2.  unlock scheduler
+// 
+//        1.  runs, lock mutex - thread 3 has it locked
+//
+//        2.  busy-waits a bit for thread 3 to come out of its delay() loop.
+//            This must be a *busy*wait so that 3 can only run via the
+//            inherited raised priority.
+// 
+//        [xa. all do the same: lock mutex,                ]
+//        [xa. unlock mutex                                ]
+//        [xa. set a flag "extras"[x] to say we are done.  ]
+//        [xa. exit                                        ]
+// 
+// 
+// 
+// INHERIT
+// -------
+// 
+//                 thread 3->prio := 5
+// 
+//        3.  runs,
+//        3.  set a flag to say "3-ran",
+//        3.  loop with a sleep(1) until "go-flag" is set.
+//        3.  check "got it" is false,
+//        3.  then unlock mutex,
+// 
+//                 thread 3->prio := 15
+// 
+//        1.  runs, set a flag to say "got it",
+//        1.  check "3-ended" flag is false
+//        1.  unlock mutex,
+//        1.  check "3-ended" flag is still false
+//        1.  exit.
+// 
+//        [1a locks, unlocks, exits]
+// 
+//        2.  runs, check "3-ran" and "got it" flags are TRUE ****
+//        2.  check "3-ended" flag is false
+//        2.  sleeps for a while so that...
+// 
+//        [2a locks, unlocks, exits]
+//            
+//        3.  runs, set "3-ended" flag,
+//        3.  check "3-ran" and "got it" flags
+//        3.  exit
+// 
+//        [3a locks, unlocks, exits]
+// 
+//        2.  awakens, checks all flags true,
+//        2.  check that all "extra" threads that we started have indeed run
+//        2.  end of test.
+// 
+// 
+// 
+// 
+// NO-INHERIT
+// ----------
+//                 thread 1 is waiting on the mutex
+// 
+//        [1a lock-fail]
+// 
+//        2.  runs, checks that "3-ran" and "got it" flags are FALSE ****
+//        2.  check "3-ended" flag is false
+//        2.  sleeps for a while so that...
+// 
+//        [2a. lock-fail]
+//            
+//        3.  runs, set a flag to say "3-ran",
+//        3.  check "got it" is false,
+//        3.  then unlock mutex,
+// 
+//        1.  runs, set a flag to say "got it",
+//        1.  check "3-ended" flag is false
+//        1.  unlock mutex,
+//        1.  check "3-ended" flag is still false
+//        1.  exit.
+// 
+//        [1a locks, unlocks, exits]
+//        [2a locks, unlocks, exits]
+// 
+//        3.  runs, set "3-ended" flag,
+//        3.  check "3-ran" and "got it" flags
+//        3.  exit
+// 
+//        [3a locks, unlocks, exits]
+//                
+//        2.  awakens, checks all flags true, 
+//        2.  check that all "extra" threads that we started have indeed run
+//        2.  end of test.
+// 
+// 
+// (the end)
+// 
+// 
+// ------------------------------------------------------------------------
+
+#endif
+
+// EOF mutex3.cxx
diff --git a/packages/compat/posix/v2_0/tests/pthread1.c b/packages/compat/posix/v2_0/tests/pthread1.c
new file mode 100644 (file)
index 0000000..116bfdf
--- /dev/null
@@ -0,0 +1,119 @@
+//==========================================================================
+//
+//        pthread1.cxx
+//
+//        POSIX pthread test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-04-10
+// Description:   Tests POSIX join functionality.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#ifndef CYGPKG_POSIX_PTHREAD
+#define NA_MSG "POSIX threads not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <sys/types.h>
+#include <pthread.h>
+
+//--------------------------------------------------------------------------
+// Thread stack.
+
+char thread_stack[PTHREAD_STACK_MIN*2];
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry1( void *arg)
+{
+    CYG_TEST_INFO( "Thread 1 running" );
+    
+    pthread_exit( (void *)((int)arg+1) );
+}
+
+//--------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+    pthread_t thread;
+    pthread_attr_t attr;
+    void *retval;
+
+    CYG_TEST_INIT();
+
+    // Create test thread
+    pthread_attr_init( &attr );
+
+    pthread_attr_setstackaddr( &attr, (void *)&thread_stack[sizeof(thread_stack)] );
+    pthread_attr_setstacksize( &attr, sizeof(thread_stack) );
+
+    pthread_create( &thread,
+                    &attr,
+                    pthread_entry1,
+                    (void *)0x12345678);
+
+    // Now join with it
+    pthread_join( thread, &retval );
+
+    // check retval
+    
+    if( (long)retval == 0x12345679 )
+        CYG_TEST_PASS_FINISH( "pthread1" );
+    else
+        CYG_TEST_FAIL_FINISH( "pthread1" );
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of pthread1.c
diff --git a/packages/compat/posix/v2_0/tests/pthread2.c b/packages/compat/posix/v2_0/tests/pthread2.c
new file mode 100644 (file)
index 0000000..a501fe6
--- /dev/null
@@ -0,0 +1,176 @@
+//==========================================================================
+//
+//        pthread2.cxx
+//
+//        POSIX pthread test 2 - per-thread data
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-04-10
+// Description:   Tests POSIX per-thread data.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#ifndef CYGPKG_POSIX_PTHREAD
+#define NA_MSG "POSIX threads not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <sys/types.h>
+#include <pthread.h>
+
+//--------------------------------------------------------------------------
+// Thread stack.
+
+char thread_stack[2][PTHREAD_STACK_MIN*2];
+
+pthread_t thread[2];
+
+pthread_key_t key;
+
+//--------------------------------------------------------------------------
+
+void key_destructor( void *val )
+{
+    int ret;
+
+    CYG_TEST_INFO( "key destructor called" );
+
+    if( (long)val == 0xAAAAAAAA )
+    {
+        ret = pthread_setspecific( key, NULL );
+        CYG_TEST_CHECK( ret == 0, "pthread_setspecific() returned error");
+    }
+    else
+    {
+        ret = pthread_setspecific( key, (void *)0xAAAAAAAA );
+        CYG_TEST_CHECK( ret == 0, "pthread_setspecific() returned error");
+    }
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry( void *arg)
+{
+    int ret;
+    int retval = 1;
+    void *val;
+    
+    CYG_TEST_INFO( "Thread running" );
+
+    ret = pthread_setspecific( key, arg );
+    CYG_TEST_CHECK( ret == 0, "pthread_setspecific() returned error");
+    val = pthread_getspecific( key );
+    CYG_TEST_CHECK( val == arg, "pthread_getspecific() did not return expected value");
+    if( val != arg ) retval = 0;
+    
+    sched_yield();
+
+    val = pthread_getspecific( key );
+    CYG_TEST_CHECK( val == arg, "pthread_getspecific() did not return expected value");
+    if( val != arg ) retval = 0;
+    
+    pthread_exit( (void *)retval );
+}
+
+//--------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+    int i;
+    int ret;
+    void *retval[2];
+
+    CYG_TEST_INIT();
+
+    // allocate data key
+    ret = pthread_key_create( &key, key_destructor );
+    CYG_TEST_CHECK( ret == 0, "pthread_key_create() returned error");
+    
+    // Create test threads
+    for( i = 0; i < 2; i++ )
+    {
+        pthread_attr_t attr;
+        pthread_attr_init( &attr );
+
+        pthread_attr_setstackaddr( &attr, (void *)&thread_stack[i][sizeof(thread_stack[i])] );
+        pthread_attr_setstacksize( &attr, sizeof(thread_stack[i]) );
+
+        ret = pthread_create( &thread[i],
+                              &attr,
+                              pthread_entry,
+                              (void *)(0x12340000+i));
+        CYG_TEST_CHECK( ret == 0, "pthread_create() returned error");
+    }
+    
+    // Now join with threads
+    for( i = 0; i < 2; i++ )
+        pthread_join( thread[i], &retval[i] );
+
+
+    ret = pthread_key_delete( key );
+    CYG_TEST_CHECK( ret == 0, "pthread_key_delete() returned error");
+            
+    // check retvals
+
+    for( i = 0; i < 2; i++ )
+        if( !(long)retval[0] )
+            CYG_TEST_FAIL_FINISH( "pthread2" );
+                
+    CYG_TEST_PASS_FINISH( "pthread2" );
+        
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of pthread2.c
diff --git a/packages/compat/posix/v2_0/tests/pthread3.c b/packages/compat/posix/v2_0/tests/pthread3.c
new file mode 100644 (file)
index 0000000..1f61960
--- /dev/null
@@ -0,0 +1,269 @@
+//==========================================================================
+//
+//        pthread3.cxx
+//
+//        POSIX pthread test 2 - cancellation
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg, jlarmour
+// Date:          2000-04-10
+// Description:   Tests POSIX cancellation.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#ifndef CYGPKG_POSIX_PTHREAD
+#define NA_MSG "POSIX threads not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <unistd.h> // sleep()
+
+//--------------------------------------------------------------------------
+// Thread info
+
+#define NTHREADS 3
+
+char thread_stack[NTHREADS][PTHREAD_STACK_MIN*2];
+
+pthread_t thread[NTHREADS];
+
+void *pthread_entry1( void *arg);
+void *pthread_entry2( void *arg);
+void *pthread_entry3( void *arg);
+
+void *(*pthread_entry[NTHREADS])(void *) =
+{
+    pthread_entry1,
+    pthread_entry2,
+    pthread_entry3
+};
+
+//--------------------------------------------------------------------------
+
+volatile cyg_bool cancel_handler1_called = false;
+volatile cyg_bool cancel_handler2_called = false;
+volatile cyg_bool cancel_handler3_called = false;
+volatile cyg_bool thread_ready[NTHREADS];
+
+//--------------------------------------------------------------------------
+
+void cancel_handler1( void * arg )
+{
+    CYG_TEST_INFO( "cancel_handler1 called" );
+
+    CYG_TEST_CHECK( (long)arg == 0x12340000, "cancel_handler1: bad arg value");
+    
+    cancel_handler1_called = true;
+}
+
+//--------------------------------------------------------------------------
+
+void cancel_handler2( void * arg )
+{
+    CYG_TEST_INFO( "cancel_handler2 called" );
+
+    CYG_TEST_CHECK( (long)arg == 0xFFFF1111, "cancel_handler2: bad arg value");
+    
+    cancel_handler2_called = true;    
+}
+
+//--------------------------------------------------------------------------
+
+void cancel_handler3( void * arg )
+{
+    CYG_TEST_INFO( "cancel_handler3 called" );
+
+    CYG_TEST_CHECK( (long)arg == 0x12340001, "cancel_handler3: bad arg value");    
+    
+    cancel_handler3_called = true;
+}
+
+//--------------------------------------------------------------------------
+
+void function1(void)
+{
+
+    pthread_cleanup_push( cancel_handler2, (void *)0xFFFF1111 );
+
+    for(;;)
+    {
+        sched_yield();
+        pthread_testcancel();
+    }
+
+    pthread_cleanup_pop( 0 );
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry1( void *arg)
+{
+    int retval = 1;
+
+    CYG_TEST_INFO( "pthread_entry1 entered");
+
+    pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, NULL );
+    
+    pthread_cleanup_push( cancel_handler1, arg );
+
+    thread_ready[0] = true;
+
+    function1();    
+    
+    pthread_cleanup_pop( 0 );
+
+    pthread_exit( (void *)retval );
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry2( void *arg)
+{
+    int retval = 1;
+
+    CYG_TEST_INFO( "pthread_entry2 entered");
+
+    pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
+    
+    pthread_cleanup_push( cancel_handler3, arg );
+
+    thread_ready[1] = true;
+
+    for(;;) sched_yield();
+    
+    pthread_cleanup_pop( 0 );
+
+    pthread_exit( (void *)retval );
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry3( void *arg)
+{
+    int retval = 1;
+
+    CYG_TEST_INFO( "pthread_entry3 entered");
+
+    pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, NULL );
+    
+    thread_ready[2] = true;
+
+    // stop in a cancellation point
+    sleep( 99999 );
+    
+    pthread_exit( (void *)retval );
+}
+
+//--------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+    int i, j;
+    int ret;
+    void *retval[NTHREADS];
+
+    CYG_TEST_INIT();
+
+    // Create test threads
+    for( i = 0; i < NTHREADS; i++ )
+    {
+        pthread_attr_t attr;
+        pthread_attr_init( &attr );
+
+        pthread_attr_setstackaddr( &attr, (void *)&thread_stack[i][sizeof(thread_stack[i])] );
+        pthread_attr_setstacksize( &attr, sizeof(thread_stack[i]) );
+
+        ret = pthread_create( &thread[i],
+                              &attr,
+                              pthread_entry[i],
+                              (void *)(0x12340000+i));
+        CYG_TEST_CHECK( ret == 0, "pthread_create() returned error");
+    }
+
+    // Let the threads get going    
+    for ( i = 0; i < NTHREADS ; i++ ) {
+        while ( thread_ready[i] == false )
+            sched_yield();
+    }
+
+    // Now wait a bit to be sure that the other threads have reached
+    // their cancellation points.
+    for ( j = 0; j < 20 ; j++ )
+        sched_yield();
+    
+    // Now cancel them
+    for( i = 0; i < NTHREADS; i++ )    
+        pthread_cancel( thread[i] );
+        
+    // Now join with threads
+    for( i = 0; i < NTHREADS; i++ )
+        pthread_join( thread[i], &retval[i] );
+
+
+    // check retvals
+    for( i = 0; i < NTHREADS; i++ )
+        CYG_TEST_CHECK( retval[i] == PTHREAD_CANCELED,
+                        "thread didn't exit with PTHREAD_CANCELED" );
+
+    CYG_TEST_CHECK( cancel_handler1_called, "cancel_handler1 not called" );
+    CYG_TEST_CHECK( cancel_handler2_called, "cancel_handler2 not called" );
+    CYG_TEST_CHECK( cancel_handler3_called, "cancel_handler3 not called" );
+
+    CYG_TEST_PASS_FINISH( "pthread3" );
+        
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of pthread3.c
diff --git a/packages/compat/posix/v2_0/tests/signal1.c b/packages/compat/posix/v2_0/tests/signal1.c
new file mode 100644 (file)
index 0000000..f414c28
--- /dev/null
@@ -0,0 +1,302 @@
+//==========================================================================
+//
+//        signal1.cxx
+//
+//        POSIX signal test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-04-10
+// Description:   Tests POSIX signal functionality.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#if !defined(CYGPKG_POSIX_SIGNALS)
+#define NA_MSG "POSIX signals not enabled"
+#elif !defined(CYGPKG_POSIX_PTHREAD)
+#define NA_MSG "POSIX threads not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <errno.h>
+
+//--------------------------------------------------------------------------
+// Thread stack.
+
+char thread_stack[PTHREAD_STACK_MIN*2];
+
+//--------------------------------------------------------------------------
+// Local variables
+
+// Sync semaphore
+sem_t sem;
+
+// Thread ID
+pthread_t thread1;
+
+volatile int sigusr2_called = 0;
+volatile int sigalrm_called = 0;
+
+//--------------------------------------------------------------------------
+// Signal handler functions
+
+static void sigusr2( int signo )
+{
+    CYG_TEST_INFO( "sigusr2() handler called" );
+    CYG_TEST_CHECK( signo == SIGUSR2, "Signal not SIGUSR2");
+    CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
+
+    sigusr2_called++;
+}
+
+static void sigalrm( int signo )
+{
+    CYG_TEST_INFO( "sigalrm() handler called" );
+    CYG_TEST_CHECK( signo == SIGALRM, "Signal not SIGALRM");
+    CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
+
+    sigalrm_called++;
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry1( void *arg)
+{
+    sigset_t mask;
+    siginfo_t info;
+    struct timespec timeout;
+    int sig, sig2, err;
+    
+    CYG_TEST_INFO( "Thread 1 running" );
+
+    // Should have inherited parent's signal mask
+    pthread_sigmask( 0, NULL, &mask );
+    CYG_TEST_CHECK( sigismember( &mask, SIGALRM),
+                                 "SIGALRM mask inherited");
+    CYG_TEST_CHECK( sigismember( &mask, SIGUSR1),
+                                 "SIGUSR1 mask inherited");
+    CYG_TEST_CHECK( sigismember( &mask, SIGUSR2),
+                                 "SIGUSR2 mask inherited");
+    CYG_TEST_CHECK( sigismember( &mask, SIGSEGV),
+                                 "SIGSEGV mask inherited");
+
+    // Make a full set
+    sigfillset( &mask );
+
+    // remove USR2 and ALRM signals
+    sigdelset( &mask, SIGUSR2 );
+    sigdelset( &mask, SIGALRM );
+
+    // Set signal mask
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    // Get main thread going again
+    sem_post( &sem );
+
+    // set up timeout
+    timeout.tv_sec = 10;
+    timeout.tv_nsec = 0;
+
+    CYG_TEST_INFO( "Thread1: calling sigtimedwait()");
+    
+    // Wait for a signal to be delivered
+    sig = sigtimedwait( &mask, &info, &timeout );
+
+    sig2 = info.si_signo;
+    
+    CYG_TEST_CHECK( sig == sig2, "sigtimedwait return value not equal");
+    CYG_TEST_CHECK( sig == SIGUSR1, "Signal not delivered");
+
+    while( sigusr2_called != 2 )
+    {
+        CYG_TEST_INFO( "Thread1: calling pause()");        
+        pause();
+    }
+
+    errno = 0; // strictly correct to reset errno first
+
+    // now wait for SIGALRM to be delivered
+    CYG_TEST_INFO( "Thread1: calling pause()");            
+    err = pause();
+    CYG_TEST_CHECK( -1==err, "pause returned -1");
+    CYG_TEST_CHECK( EINTR==errno, "errno set to EINTR");
+
+    // generate another SIGALRM and wait for it to be delivered too
+    // we need to mask it first though
+
+    // Make a full set
+    sigfillset( &mask );
+
+    // Set signal mask
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    alarm(1);
+    CYG_TEST_INFO( "Thread1: calling sigwait()");            
+    err = sigwait( &mask, &sig);
+    CYG_TEST_CHECK( 0==err, "sigwait returned -1");
+    CYG_TEST_CHECK( sig==SIGALRM, "sigwait caught alarm");
+
+    CYG_TEST_INFO( "Thread1: calling pthread_exit()");    
+    pthread_exit( (void *)((int)arg+sig2) );
+}
+
+//--------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+    int ret;
+    sigset_t mask;
+    pthread_attr_t attr;
+    void *retval;
+    union sigval value;
+    
+    CYG_TEST_INIT();
+
+    // Make a full signal set
+    sigfillset( &mask );
+
+    
+    // Install signal handlers
+    {
+        struct sigaction sa;
+
+        sa.sa_handler = sigusr2;
+        sa.sa_mask = mask;
+        sa.sa_flags = 0;
+
+        ret = sigaction( SIGUSR2, &sa, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+    }
+
+    {
+        struct sigaction sa;
+
+        sa.sa_handler = sigalrm;
+        sa.sa_mask = mask;
+        sa.sa_flags = 0;
+
+        ret = sigaction( SIGALRM, &sa, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+    }
+    
+    
+    // Mask all signals
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    sem_init( &sem, 0, 0 );
+    
+    // Create test thread
+    pthread_attr_init( &attr );
+
+    pthread_attr_setstackaddr( &attr, (void *)&thread_stack[sizeof(thread_stack)] );
+    pthread_attr_setstacksize( &attr, sizeof(thread_stack) );
+
+    pthread_create( &thread1,
+                    &attr,
+                    pthread_entry1,
+                    (void *)0x12345678);
+
+    // Wait for other thread to get started
+    CYG_TEST_INFO( "Main: calling sem_wait()");
+    sem_wait( &sem );
+
+    value.sival_int = 0;
+
+    // send a signal to the other thread
+    CYG_TEST_INFO( "Main: calling sigqueue(SIGUSR1)");
+    sigqueue( 0, SIGUSR1, value );
+
+    // Send the signal via kill
+    CYG_TEST_INFO( "Main: calling kill(0, SIGUSR2)");
+    kill( 0, SIGUSR2 );
+
+    // Wait for thread1 to call pause()
+    CYG_TEST_INFO( "Main: calling sleep(1)");
+    sleep(1);
+
+    // And again
+    CYG_TEST_INFO( "Main: calling kill(0, SIGUSR2)");
+    kill( 0, SIGUSR2 );
+
+    // Set up an alarm for 1 second hence
+    CYG_TEST_INFO( "Main: calling alarm(1)");
+    alarm(1);
+    
+    // Wait for alarm signal to be delivered to thread1
+    CYG_TEST_INFO( "Main: calling sleep(2)");
+    sleep(2);
+    
+    // Now join with thread1
+    CYG_TEST_INFO( "Main: calling pthread_join()");
+    pthread_join( thread1, &retval );
+
+    CYG_TEST_CHECK( sigusr2_called == 2, "SIGUSR2 signal handler not called twice" );
+
+    CYG_TEST_CHECK( sigalrm_called == 1, "SIGALRM signal handler not called" );    
+    
+    // check retval
+    
+    if( (long)retval == 0x12345678+SIGUSR1 )
+        CYG_TEST_PASS_FINISH( "signal1" );
+    else
+        CYG_TEST_FAIL_FINISH( "signal1" );
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of signal1.c
diff --git a/packages/compat/posix/v2_0/tests/signal2.c b/packages/compat/posix/v2_0/tests/signal2.c
new file mode 100644 (file)
index 0000000..358965d
--- /dev/null
@@ -0,0 +1,313 @@
+//==========================================================================
+//
+//        signal2.cxx
+//
+//        POSIX signal test 2
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  jlarmour
+// Date:          2000-04-10
+// Description:   Tests POSIX signal functionality.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <pkgconf/isoinfra.h>
+#include <cyg/hal/hal_intr.h>   // For exception codes
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <semaphore.h>
+
+#include <setjmp.h>
+
+#include <cyg/infra/testcase.h>
+
+#if CYGINT_ISO_SETJMP == 0
+# define NA_MSG "Requires setjmp/longjmp implementation"
+#elif !defined(CYGPKG_POSIX_SIGNALS)
+# define NA_MSG "POSIX signals not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( NA_MSG );
+}
+#else
+
+//--------------------------------------------------------------------------
+// Local variables
+
+static jmp_buf jbuf;
+
+//--------------------------------------------------------------------------
+
+// PowerPC is a special case as it has the alignment exception, but it
+// doesn't trigger for this function unless in little-endian mode (although
+// the exception exists for other instructions not used by this function so
+// CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS will still be defined
+
+#if defined(CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS) && !(defined(CYGPKG_HAL_POWERPC) && (CYG_BYTEORDER==CYG_MSBFIRST))
+
+static void
+cause_unaligned_access(void)
+{
+    volatile int x;
+    volatile CYG_ADDRESS p=(CYG_ADDRESS) &jbuf;
+
+    x = *(volatile int *)(p+1);
+
+} // cause_unaligned_access()
+
+#endif
+
+//--------------------------------------------------------------------------
+
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
+
+static void
+cause_illegal_access(void)
+{
+#ifdef CYGPKG_HAL_I386
+
+    // In the x86 architecture, although we have the DATA_ACCESS
+    // exception available, it is not possible to provoke it using the
+    // normal code of this test. This is because the normal segments we
+    // have installed in the segment registers cover all of memory. Instead we
+    // set GS to a descriptor that does not cover 0xF0000000-0xFFFFFFFF and
+    // poke at that.
+
+    __asm__ ( "movw     $0x20,%%ax\n"
+              "movw     %%ax,%%gs\n"
+              "movl     %%gs:0xF0000000,%%eax\n"
+              :
+              :
+              : "eax"
+            );
+    
+#else    
+    volatile int x;
+    volatile CYG_ADDRESS p=(CYG_ADDRESS) &jbuf;
+
+    do
+    {
+        x = *(volatile int *)(p);
+        p += (CYG_ADDRESS)0x100000;
+    } while( p != (CYG_ADDRESS)&jbuf );
+
+#endif    
+} // cause_illegal_access()
+
+#endif
+
+//--------------------------------------------------------------------------
+
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
+
+// num must always be 0 - do it this way in case the optimizer tries to
+// get smart
+
+static int
+cause_fpe(int num)
+{
+    double a;
+
+    a = 1.0/num;                        // Depending on FPU emulation and/or
+                                        // the FPU architecture, this may
+                                        // cause an exception.
+                                        // (float division by zero)
+
+    return ((int)a)/num;                // This may cause an exception if
+                                        // the architecture supports it.
+                                        // (integer division by zero).
+} // cause_fpe()
+
+#endif
+
+//--------------------------------------------------------------------------
+// Signal handler functions
+
+static void sigsegv( int signo )
+{
+    CYG_TEST_INFO( "sigsegv() handler called" );
+    CYG_TEST_CHECK( signo == SIGSEGV, "Signal not SIGSEGV");
+
+    longjmp( jbuf, 1 );
+}
+
+static void sigbus( int signo )
+{
+    CYG_TEST_INFO( "sigbus() handler called" );
+    CYG_TEST_CHECK( signo == SIGBUS, "Signal not SIGBUS");
+
+    longjmp( jbuf, 1 );
+}
+
+static void sigfpe( int signo )
+{
+    CYG_TEST_INFO( "sigfpe() handler called" );
+    CYG_TEST_CHECK( signo == SIGFPE, "Signal not SIGFPE");
+
+    longjmp( jbuf, 1 );
+}
+
+
+//--------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+    int ret;
+    sigset_t mask;
+    struct sigaction sa;
+    
+    CYG_TEST_INIT();
+
+    // Make a full signal set
+    sigfillset( &mask );
+
+   
+    // Install signal handlers
+
+    sa.sa_mask = mask;
+    sa.sa_flags = 0;
+
+    sa.sa_handler = sigsegv;
+    ret = sigaction( SIGSEGV, &sa, NULL );
+    CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+
+    sa.sa_handler = sigbus;
+    ret = sigaction( SIGBUS, &sa, NULL );
+    CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+
+    sa.sa_handler = sigfpe;
+    ret = sigaction( SIGFPE, &sa, NULL );
+    CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+
+    // now make an empty signal set
+    sigemptyset( &mask );
+    
+// Now reset the various exception handlers to eCos handlers so that we
+// have control; this is the target side equivalent of the CYG_TEST_GDBCMD
+// lines above:
+#ifdef HAL_VSR_SET_TO_ECOS_HANDLER
+    // Reclaim the VSR off CygMon possibly
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
+    HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS
+    HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS
+    HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
+    HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION, NULL );
+#endif
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
+    HAL_VSR_SET_TO_ECOS_HANDLER( CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO, NULL );
+#endif
+#endif
+
+    // PowerPC is a special case as it has the alignment exception, but it
+    // doesn't trigger for this function unless in little-endian mode (although
+    // the exception exists for other instructions not used by this function so
+    // CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS will still be defined
+
+#if defined(CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS) && !(defined(CYGPKG_HAL_POWERPC) && (CYG_BYTEORDER==CYG_MSBFIRST))
+    
+    CYG_TEST_INFO("Test 1 - provoke unaligned access");
+    
+    if( setjmp( jbuf ) == 0 )
+    {
+        pthread_sigmask( SIG_SETMASK, &mask, NULL );
+        cause_unaligned_access();
+        CYG_TEST_FAIL("Didn't cause exception");        
+    }
+
+#else
+
+    CYG_TEST_INFO("Test 1 - provoke unaligned access - not supported");
+
+#endif    
+
+#ifdef CYGNUM_HAL_EXCEPTION_DATA_ACCESS
+    
+    CYG_TEST_INFO("Test 2 - provoke illegal access");
+    
+    if( setjmp( jbuf ) == 0 )
+    {
+        pthread_sigmask( SIG_SETMASK, &mask, NULL );
+        cause_illegal_access();
+        CYG_TEST_FAIL("Didn't cause exception");        
+    }
+
+#else
+
+    CYG_TEST_INFO("Test 1 - provoke illegal access - not supported");
+
+#endif    
+    
+#ifdef CYGNUM_HAL_EXCEPTION_FPU_DIV_BY_ZERO
+    
+    CYG_TEST_INFO("Test 3 - provoke FP error");    
+
+    if( setjmp( jbuf ) == 0 )
+    {
+        pthread_sigmask( SIG_SETMASK, &mask, NULL );
+        cause_fpe(0);
+        CYG_TEST_FAIL("Didn't cause exception");        
+    }
+
+#else
+
+    CYG_TEST_INFO("Test 3 - provoke FP error - not supported");    
+    
+#endif    
+
+    CYG_TEST_PASS_FINISH( "signal2" );
+}
+
+#endif // ifndef NA_MSG
+
+//--------------------------------------------------------------------------
+// end of signal1.c
diff --git a/packages/compat/posix/v2_0/tests/signal3.c b/packages/compat/posix/v2_0/tests/signal3.c
new file mode 100644 (file)
index 0000000..5829289
--- /dev/null
@@ -0,0 +1,174 @@
+//==========================================================================
+//
+//        signal3.cxx
+//
+//        POSIX signal test 3
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2003-01-30
+// Description:   Tests POSIX signal functionality.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#if !defined(CYGPKG_POSIX_SIGNALS)
+#define NA_MSG "POSIX signals not enabled"
+#elif !defined(CYGPKG_POSIX_PTHREAD)
+#define NA_MSG "POSIX threads not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <signal.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <errno.h>
+#include <cyg/infra/diag.h>
+
+volatile int sigusr1_called = 0;
+
+//--------------------------------------------------------------------------
+// Signal handler functions
+
+static void sigusr1( int signo )
+{
+    CYG_TEST_INFO( "sigusr1() handler called" );
+    CYG_TEST_CHECK( signo == SIGUSR1, "Signal not SIGUSR1");
+
+    sigusr1_called++;
+}
+
+//--------------------------------------------------------------------------
+
+int main (int argc, char **argv)
+{
+    int ret_val;
+    sigset_t set;
+    int sig;
+    struct itimerspec timerValue;      // Timeout value on eCos
+    timer_t timer1;                    // Timer
+    struct sigevent sev;
+
+    CYG_TEST_INIT();
+
+    {
+        struct sigaction sa;
+
+        sa.sa_handler = sigusr1;
+        sigfillset( &sa.sa_mask );
+        sa.sa_flags = 0;
+
+        ret_val = sigaction( SIGUSR1, &sa, NULL );
+
+        CYG_TEST_CHECK( ret_val == 0 , "sigaction returned error");
+    }
+    
+    // unblock all the signals
+    sigfillset (&set);
+    pthread_sigmask (SIG_UNBLOCK, &set, (sigset_t*)NULL);
+    
+    //--------------------------------------------------------------------
+    // <start of timer initialization section>
+    //--------------------------------------------------------------------
+       
+    // Notification type --- Deliver the signal
+    sev.sigev_notify                = SIGEV_SIGNAL;
+    sev.sigev_signo                 = SIGUSR1;
+    sev.sigev_value.sival_int       = 0xABCDEF01;
+       
+    // Timer values    --- 1 Second
+    timerValue.it_value.tv_sec           = 1;
+    timerValue.it_value.tv_nsec          = 0;
+    timerValue.it_interval.tv_sec        = 1;
+    timerValue.it_interval.tv_nsec       = 0;
+       
+    ret_val = timer_create (CLOCK_REALTIME, &sev, &timer1);
+
+    CYG_TEST_CHECK( ret_val==0, "Error in creating the timer");
+
+    ret_val = timer_settime (timer1, 0, &timerValue, NULL );
+    CYG_TEST_CHECK( ret_val==0,"Error in setting the time");
+
+    //--------------------------------------------------------------------
+    // <end of timer initialization section>
+    //--------------------------------------------------------------------
+
+    CYG_TEST_INFO ("Timer initialisation is completed..");
+
+    CYG_TEST_INFO ("Calling pause()");
+    ret_val = pause();
+    CYG_TEST_CHECK( ret_val==-1, "pause() did not return -1");
+    CYG_TEST_CHECK( EINTR==errno, "errno set to EINTR");
+    CYG_TEST_CHECK( sigusr1_called==1, "Siguser1 handler not called");
+    
+    // Block all the signals
+    sigfillset (&set);
+    pthread_sigmask (SIG_BLOCK, &set, (sigset_t*)NULL);
+
+    CYG_TEST_INFO ("Calling sigwait()");    
+    // Wait for any signal to arrive
+    sigfillset (&set);
+    ret_val = sigwait (&set, &sig);
+
+    CYG_TEST_CHECK( ret_val==0, "sigwait returned error");
+    CYG_TEST_CHECK( sig==SIGUSR1, "sigwait returned wrong signo!");
+    CYG_TEST_CHECK( sigusr1_called==1, "Siguser1 handler called!");
+    
+    CYG_TEST_INFO ("Program terminating");
+
+    CYG_TEST_PASS_FINISH( "signal3" );
+    return 0;
+}
+
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of signal3.c
diff --git a/packages/compat/posix/v2_0/tests/sigsetjmp.c b/packages/compat/posix/v2_0/tests/sigsetjmp.c
new file mode 100644 (file)
index 0000000..6fd0f11
--- /dev/null
@@ -0,0 +1,383 @@
+//==========================================================================
+//
+//        sigsetjmp.c
+//
+//        POSIX sigsetjmp test
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-04-10
+// Description:   Tests POSIX sigsetjmp functionality.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#if !defined(CYGPKG_POSIX_SIGNALS)
+#define NA_MSG "POSIX signals not enabled"
+#elif !defined(CYGPKG_POSIX_PTHREAD)
+#define NA_MSG "POSIX threads not enabled"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <time.h>
+#include <setjmp.h>
+
+#include <cyg/infra/testcase.h>
+
+//--------------------------------------------------------------------------
+// Thread stack.
+
+char thread1_stack[PTHREAD_STACK_MIN*2];
+char thread2_stack[PTHREAD_STACK_MIN*2];
+
+//--------------------------------------------------------------------------
+// Local variables
+
+// Sync semaphore
+sem_t sem;
+
+// Thread IDs
+pthread_t thread1;
+pthread_t thread2;
+
+timer_t timer1;
+timer_t timer2;
+
+volatile int sigusr1_called = 0;
+volatile int sigusr2_called = 0;
+
+sigjmp_buf jmpbuf1;
+sigjmp_buf jmpbuf2;
+
+//--------------------------------------------------------------------------
+// Signal handler functions
+
+static void sigusr1( int signo, siginfo_t *info, void *context )
+{
+    CYG_TEST_INFO( "sigusr1() handler called" );
+    CYG_TEST_CHECK( signo == SIGUSR1, "Signal not SIGUSR1");
+    CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
+    CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
+    CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF01, "Siginfo value wrong");
+    CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
+
+    sigusr1_called++;
+
+    CYG_TEST_INFO( "sigusr1() handler calling siglongjmp()" );
+    
+    siglongjmp( jmpbuf1, sigusr1_called );
+}
+
+static void sigusr2( int signo, siginfo_t *info, void *context )
+{
+    CYG_TEST_INFO( "sigusr2() handler called" );
+    CYG_TEST_CHECK( signo == SIGUSR2, "Signal not SIGUSR2");
+    CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
+    CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
+    CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF02, "Siginfo value wrong");
+    CYG_TEST_CHECK( pthread_equal(pthread_self(), thread2), "Not called in thread2");
+
+    sigusr2_called++;
+
+    CYG_TEST_INFO( "sigusr2() handler calling siglongjmp()" );
+    siglongjmp( jmpbuf2, sigusr2_called );    
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry1( void *arg)
+{
+    sigset_t mask;
+
+    
+    CYG_TEST_INFO( "Thread 1 running" );
+
+    // Make a full set
+    sigfillset( &mask );
+
+    // remove USR1 signal
+    sigdelset( &mask, SIGUSR1 );
+
+    // Set signal mask
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    // Get main thread going again
+    sem_post( &sem );
+
+    do
+    {
+        sigset_t curmask;
+
+        CYG_TEST_INFO( "Thread1: calling sigsetjmp()");                
+        if( sigsetjmp( jmpbuf1, 1 ) != 0 )
+            CYG_TEST_INFO( "Thread1: sigsetjmp() returned non-zero");
+        
+        pthread_sigmask( SIG_SETMASK, NULL, &curmask );
+        CYG_TEST_CHECK( curmask == mask, "Thread1: Signal masks not equal" );
+
+        if ( sigusr1_called >= 1 )
+            break;
+        
+        CYG_TEST_INFO( "Thread1: calling pause()");        
+        pause();
+
+        CYG_TEST_INFO( "Thread1: pause() returned");        
+    } while(1);
+
+    CYG_TEST_INFO( "Thread1: calling pthread_exit()");    
+    pthread_exit( arg );
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry2( void *arg)
+{
+    sigset_t mask;
+    
+    CYG_TEST_INFO( "Thread 2 running" );
+
+    // Make a full set
+    sigfillset( &mask );
+
+    // remove USR2 signal
+    sigdelset( &mask, SIGUSR2 );
+
+    // Set signal mask
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    // Get main thread going again
+    sem_post( &sem );
+
+    do 
+    {
+        sigset_t curmask;
+
+        CYG_TEST_INFO( "Thread2: calling sigsetjmp()");
+        if( sigsetjmp( jmpbuf2, 1 ) != 0 )
+            CYG_TEST_INFO( "Thread2: sigsetjmp() returned non-zero");
+        
+        pthread_sigmask( SIG_SETMASK, NULL, &curmask );
+        CYG_TEST_CHECK( curmask == mask, "Thread2: Signal masks not equal" );
+
+        if ( sigusr2_called >= 6 )
+            break;
+        
+        CYG_TEST_INFO( "Thread2: calling pause()");        
+        pause();
+
+        CYG_TEST_INFO( "Thread2: pause() returned");
+    } while(1);
+
+    CYG_TEST_INFO( "Thread2: calling pthread_exit()");    
+    pthread_exit( arg );
+}
+
+//--------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+    int ret;
+    sigset_t mask;
+    pthread_attr_t attr;
+    void *retval;
+    
+    CYG_TEST_INIT();
+
+    // Make a full signal set
+    sigfillset( &mask );
+
+    
+    // Install signal handlers
+    {
+        struct sigaction sa;
+
+        sa.sa_sigaction = sigusr1;
+        sa.sa_mask = mask;
+        sa.sa_flags = SA_SIGINFO;
+
+        ret = sigaction( SIGUSR1, &sa, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+    }
+    {
+        struct sigaction sa;
+
+        sa.sa_sigaction = sigusr2;
+        sa.sa_mask = mask;
+        sa.sa_flags = SA_SIGINFO;
+
+        ret = sigaction( SIGUSR2, &sa, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+    }
+
+
+    // Create the timers
+
+    {
+        struct sigevent sev;
+        struct itimerspec value;
+        
+        sev.sigev_notify                = SIGEV_SIGNAL;
+        sev.sigev_signo                 = SIGUSR1;
+        sev.sigev_value.sival_int       = 0xABCDEF01;
+
+        value.it_value.tv_sec           = 1;
+        value.it_value.tv_nsec          = 0;
+        value.it_interval.tv_sec        = 0;
+        value.it_interval.tv_nsec       = 0;
+        
+        ret = timer_create( CLOCK_REALTIME, &sev, &timer1 );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
+
+        ret = timer_settime( timer1, 0, &value, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
+    }
+
+    {
+        struct sigevent sev;
+        struct itimerspec value;
+        
+        sev.sigev_notify                = SIGEV_SIGNAL;
+        sev.sigev_signo                 = SIGUSR2;
+        sev.sigev_value.sival_int       = 0xABCDEF02;
+
+        value.it_value.tv_sec           = 0;
+        value.it_value.tv_nsec          = 500000000;
+        value.it_interval.tv_sec        = 0;
+        value.it_interval.tv_nsec       = 250000000;
+        
+        ret = timer_create( CLOCK_REALTIME, &sev, &timer2 );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
+
+        ret = timer_settime( timer2, 0, &value, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
+    }
+
+    
+    // Mask all signals
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    sem_init( &sem, 0, 0 );
+    
+    // Create test threads
+
+    {
+        pthread_attr_init( &attr );
+
+        pthread_attr_setstackaddr( &attr, (void *)&thread1_stack[sizeof(thread1_stack)] );
+        pthread_attr_setstacksize( &attr, sizeof(thread1_stack) );
+
+        pthread_create( &thread1,
+                        &attr,
+                        pthread_entry1,
+                        (void *)0x12345671);
+    }
+
+    {
+        pthread_attr_init( &attr );
+
+        pthread_attr_setstackaddr( &attr, (void *)&thread2_stack[sizeof(thread2_stack)] );
+        pthread_attr_setstacksize( &attr, sizeof(thread2_stack) );
+
+        pthread_create( &thread2,
+                        &attr,
+                        pthread_entry2,
+                        (void *)0x12345672);
+    }
+    
+    // Wait for other thread to get started
+    CYG_TEST_INFO( "Main: calling sem_wait()");
+    sem_wait( &sem );
+    CYG_TEST_INFO( "Main: calling sem_wait() again");    
+    sem_wait( &sem );
+
+    // Now join with thread1
+    CYG_TEST_INFO( "Main: calling pthread_join(thread1)");
+    pthread_join( thread1, &retval );
+
+    CYG_TEST_CHECK( retval == (void *)0x12345671, "Thread 1 retval wrong");
+    
+    // And thread 2
+    CYG_TEST_INFO( "Main: calling pthread_join(thread2)");
+    pthread_join( thread2, &retval );
+
+    // now delete the timers
+    CYG_TEST_INFO( "Main: calling timer_delete(timer1)");    
+    ret = timer_delete( timer1 );
+
+    CYG_TEST_CHECK( ret == 0 , "timer_delete(timer1) returned error");
+
+    CYG_TEST_INFO( "Main: calling timer_delete(timer2)");    
+    ret = timer_delete( timer2 );
+
+    CYG_TEST_CHECK( ret == 0 , "timer_delete(timer2) returned error");
+
+    
+    CYG_TEST_CHECK( retval == (void *)0x12345672, "Thread 2 retval wrong");
+    
+    CYG_TEST_CHECK( sigusr1_called == 1, "SIGUSR1 signal handler not called once" );
+    CYG_TEST_CHECK( sigusr2_called == 6, "SIGUSR2 signal handler not called six times" );
+
+    CYG_TEST_PASS_FINISH( "sigsetjmp" );
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of sigsetjmp.c
diff --git a/packages/compat/posix/v2_0/tests/timer1.c b/packages/compat/posix/v2_0/tests/timer1.c
new file mode 100644 (file)
index 0000000..38d22b5
--- /dev/null
@@ -0,0 +1,343 @@
+//==========================================================================
+//
+//        timer1.cxx
+//
+//        POSIX signal test 1
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     nickg
+// Contributors:  nickg
+// Date:          2000-04-10
+// Description:   Tests POSIX signal functionality.
+//
+//####DESCRIPTIONEND####
+//==========================================================================
+
+#include <cyg/infra/testcase.h>
+#include <pkgconf/posix.h>
+
+#ifndef CYGPKG_POSIX_SIGNALS
+#define NA_MSG "No POSIX signals"
+#elif !defined(CYGPKG_POSIX_TIMERS)
+#define NA_MSG "No POSIX timers"
+#endif
+
+#ifdef NA_MSG
+void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <semaphore.h>
+#include <time.h>
+
+//--------------------------------------------------------------------------
+// Thread stack.
+
+char thread1_stack[PTHREAD_STACK_MIN*2];
+char thread2_stack[PTHREAD_STACK_MIN*2];
+
+//--------------------------------------------------------------------------
+// Local variables
+
+// Sync semaphore
+sem_t sem;
+
+// Thread IDs
+pthread_t thread1;
+pthread_t thread2;
+
+timer_t timer1;
+timer_t timer2;
+
+volatile int sigusr1_called = 0;
+volatile int sigusr2_called = 0;
+
+//--------------------------------------------------------------------------
+// Signal handler functions
+
+static void sigusr1( int signo, siginfo_t *info, void *context )
+{
+    CYG_TEST_INFO( "sigusr1() handler called" );
+    CYG_TEST_CHECK( signo == SIGUSR1, "Signal not SIGUSR1");
+    CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
+    CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
+    CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF01, "Siginfo value wrong");
+    CYG_TEST_CHECK( pthread_equal(pthread_self(), thread1), "Not called in thread1");
+
+    sigusr1_called++;
+}
+
+static void sigusr2( int signo, siginfo_t *info, void *context )
+{
+    CYG_TEST_INFO( "sigusr2() handler called" );
+    CYG_TEST_CHECK( signo == SIGUSR2, "Signal not SIGUSR2");
+    CYG_TEST_CHECK( signo == info->si_signo, "Bad signal number in siginfo" );
+    CYG_TEST_CHECK( info->si_code == SI_TIMER, "Siginfo code not SI_TIMER" );
+    CYG_TEST_CHECK( info->si_value.sival_int == 0xABCDEF02, "Siginfo value wrong");
+    CYG_TEST_CHECK( pthread_equal(pthread_self(), thread2), "Not called in thread2");
+
+    sigusr2_called++;
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry1( void *arg)
+{
+    sigset_t mask;
+
+    
+    CYG_TEST_INFO( "Thread 1 running" );
+
+    // Make a full set
+    sigfillset( &mask );
+
+    // remove USR1 signal
+    sigdelset( &mask, SIGUSR1 );
+
+    // Set signal mask
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    // Get main thread going again
+    sem_post( &sem );
+
+    while( sigusr1_called < 1 )
+    {
+        CYG_TEST_INFO( "Thread1: calling pause()");        
+        pause();
+    }
+
+    CYG_TEST_INFO( "Thread1: calling pthread_exit()");    
+    pthread_exit( arg );
+}
+
+//--------------------------------------------------------------------------
+
+void *pthread_entry2( void *arg)
+{
+    sigset_t mask;
+    
+    CYG_TEST_INFO( "Thread 2 running" );
+
+    // Make a full set
+    sigfillset( &mask );
+
+    // remove USR2 signal
+    sigdelset( &mask, SIGUSR2 );
+
+    // Set signal mask
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    // Get main thread going again
+    sem_post( &sem );
+
+    while( sigusr2_called < 6 )
+    {
+        CYG_TEST_INFO( "Thread2: calling pause()");        
+        pause();
+    }
+
+    CYG_TEST_INFO( "Thread2: calling pthread_exit()");    
+    pthread_exit( arg );
+}
+
+//--------------------------------------------------------------------------
+
+int main(int argc, char **argv)
+{
+    int ret;
+    sigset_t mask;
+    pthread_attr_t attr;
+    void *retval;
+    
+    CYG_TEST_INIT();
+
+    // Make a full signal set
+    sigfillset( &mask );
+
+    
+    // Install signal handlers
+    {
+        struct sigaction sa;
+
+        sa.sa_sigaction = sigusr1;
+        sa.sa_mask = mask;
+        sa.sa_flags = SA_SIGINFO;
+
+        ret = sigaction( SIGUSR1, &sa, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+    }
+    {
+        struct sigaction sa;
+
+        sa.sa_sigaction = sigusr2;
+        sa.sa_mask = mask;
+        sa.sa_flags = SA_SIGINFO;
+
+        ret = sigaction( SIGUSR2, &sa, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "sigaction returned error");
+    }
+
+
+    // Create the timers
+
+    {
+        struct sigevent sev;
+        struct itimerspec value;
+        
+        sev.sigev_notify                = SIGEV_SIGNAL;
+        sev.sigev_signo                 = SIGUSR1;
+        sev.sigev_value.sival_int       = 0xABCDEF01;
+
+        value.it_value.tv_sec           = 1;
+        value.it_value.tv_nsec          = 0;
+        value.it_interval.tv_sec        = 0;
+        value.it_interval.tv_nsec       = 0;
+        
+        ret = timer_create( CLOCK_REALTIME, &sev, &timer1 );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
+
+        ret = timer_settime( timer1, 0, &value, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
+    }
+
+#if 1    
+    {
+        struct sigevent sev;
+        struct itimerspec value;
+        
+        sev.sigev_notify                = SIGEV_SIGNAL;
+        sev.sigev_signo                 = SIGUSR2;
+        sev.sigev_value.sival_int       = 0xABCDEF02;
+
+        value.it_value.tv_sec           = 0;
+        value.it_value.tv_nsec          = 500000000;
+        value.it_interval.tv_sec        = 0;
+        value.it_interval.tv_nsec       = 250000000;
+        
+        ret = timer_create( CLOCK_REALTIME, &sev, &timer2 );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_create returned error");
+
+        ret = timer_settime( timer2, 0, &value, NULL );
+
+        CYG_TEST_CHECK( ret == 0 , "timer_settime returned error");
+    }
+#endif    
+    
+    // Mask all signals
+    pthread_sigmask( SIG_SETMASK, &mask, NULL );
+    
+    sem_init( &sem, 0, 0 );
+    
+    // Create test threads
+
+    {
+        pthread_attr_init( &attr );
+
+        pthread_attr_setstackaddr( &attr, (void *)&thread1_stack[sizeof(thread1_stack)] );
+        pthread_attr_setstacksize( &attr, sizeof(thread1_stack) );
+
+        pthread_create( &thread1,
+                        &attr,
+                        pthread_entry1,
+                        (void *)0x12345671);
+    }
+
+    {
+        pthread_attr_init( &attr );
+
+        pthread_attr_setstackaddr( &attr, (void *)&thread2_stack[sizeof(thread2_stack)] );
+        pthread_attr_setstacksize( &attr, sizeof(thread2_stack) );
+
+        pthread_create( &thread2,
+                        &attr,
+                        pthread_entry2,
+                        (void *)0x12345672);
+    }
+    
+    // Wait for other thread to get started
+    CYG_TEST_INFO( "Main: calling sem_wait()");
+    sem_wait( &sem );
+    CYG_TEST_INFO( "Main: calling sem_wait() again");    
+    sem_wait( &sem );
+
+    // Now join with thread1
+    CYG_TEST_INFO( "Main: calling pthread_join(thread1)");
+    pthread_join( thread1, &retval );
+
+    CYG_TEST_CHECK( retval == (void *)0x12345671, "Thread 1 retval wrong");
+    
+    // And thread 2
+    CYG_TEST_INFO( "Main: calling pthread_join(thread2)");
+    pthread_join( thread2, &retval );
+
+    // now delete the timers
+    CYG_TEST_INFO( "Main: calling timer_delete(timer1)");    
+    ret = timer_delete( timer1 );
+
+    CYG_TEST_CHECK( ret == 0 , "timer_delete(timer1) returned error");
+
+    CYG_TEST_INFO( "Main: calling timer_delete(timer2)");    
+    ret = timer_delete( timer2 );
+
+    CYG_TEST_CHECK( ret == 0 , "timer_delete(timer2) returned error");
+
+    
+    CYG_TEST_CHECK( retval == (void *)0x12345672, "Thread 2 retval wrong");
+    
+    CYG_TEST_CHECK( sigusr1_called == 1, "SIGUSR1 signal handler not called once" );
+    CYG_TEST_CHECK( sigusr2_called == 6, "SIGUSR2 signal handler not called six times" );
+
+    CYG_TEST_PASS_FINISH( "timer1" );
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// end of timer1.c
diff --git a/packages/compat/posix/v2_0/tests/tm_basic.cxx b/packages/compat/posix/v2_0/tests/tm_basic.cxx
new file mode 100644 (file)
index 0000000..1f8d952
--- /dev/null
@@ -0,0 +1,1696 @@
+//==========================================================================
+//
+//        tm_basic.cxx
+//
+//        Basic timing test / scaffolding
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 Jonathan Larmour
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     gthomas,nickg
+// Contributors:  jlarmour
+// Date:          1998-10-19
+// Description:   Very simple kernel timing test
+//####DESCRIPTIONEND####
+//==========================================================================
+
+
+#include <cyg/infra/testcase.h>
+#include <cyg/infra/diag.h>
+#include <pkgconf/posix.h>
+#include <pkgconf/system.h>
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>
+#endif
+
+#ifndef CYGPKG_POSIX_SIGNALS
+#define NA_MSG "No POSIX signals"
+#elif !defined(CYGPKG_POSIX_TIMERS)
+#define NA_MSG "No POSIX timers"
+#elif !defined(CYGPKG_POSIX_PTHREAD)
+#define NA_MSG "POSIX threads not enabled"
+#elif !defined(CYGFUN_KERNEL_API_C)
+#define NA_MSG "Kernel C API not enabled"
+#elif !defined(CYGSEM_KERNEL_SCHED_MLQUEUE)
+#define NA_MSG "Kernel mlqueue scheduler not enabled"
+#elif !defined(CYGVAR_KERNEL_COUNTERS_CLOCK)
+#define NA_MSG "Kernel clock not enabled"
+#elif CYGNUM_KERNEL_SCHED_PRIORITIES <= 12
+#define NA_MSG "Kernel scheduler properties <= 12"
+#endif
+
+//==========================================================================
+
+#ifdef NA_MSG
+extern "C" void
+cyg_start(void)
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA(NA_MSG);
+}
+#else
+
+#include <pkgconf/kernel.h>
+#include <pkgconf/hal.h>
+
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/thread.hxx>
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/mutex.hxx>
+#include <cyg/kernel/sema.hxx>
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/clock.inl>
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/infra/testcase.h>
+
+#include <cyg/kernel/test/stackmon.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+
+
+// POSIX headers
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <time.h>
+#include <signal.h>
+#include <errno.h>
+
+//==========================================================================
+// Define this to see the statistics with the first sample datum removed.
+// This can expose the effects of caches on the speed of operations.
+
+#undef STATS_WITHOUT_FIRST_SAMPLE
+
+//==========================================================================
+
+// Structure used to keep track of times
+typedef struct fun_times {
+    cyg_uint32 start;
+    cyg_uint32 end;
+} fun_times;
+
+//==========================================================================
+
+#define STACK_SIZE (PTHREAD_STACK_MIN*2)
+
+// Defaults
+#define NTEST_THREADS    16
+#define NMUTEXES         32
+#define NMBOXES          32
+#define NSEMAPHORES      32
+#define NTIMERS          32
+
+
+#define NSAMPLES         32
+#define NTHREAD_SWITCHES 128
+#define NSCHEDS          128
+
+#define NSAMPLES_SIM         2
+#define NTEST_THREADS_SIM    2
+#define NTHREAD_SWITCHES_SIM 4
+#define NMUTEXES_SIM         2
+#define NMBOXES_SIM          2
+#define NSEMAPHORES_SIM      2
+#define NSCHEDS_SIM          4
+#define NTIMERS_SIM          2
+
+//==========================================================================
+
+static int nsamples;
+static int ntest_threads;
+static int nthread_switches;
+static int nmutexes;
+static int nmboxes;
+static int nsemaphores;
+static int nscheds;
+static int ntimers;
+
+static char stacks[NTEST_THREADS][STACK_SIZE];
+static pthread_t threads[NTEST_THREADS];
+static int overhead;
+static sem_t synchro;
+static fun_times thread_ft[NTEST_THREADS];
+
+static fun_times test2_ft[NTHREAD_SWITCHES];
+
+static pthread_mutex_t test_mutexes[NMUTEXES];
+static fun_times mutex_ft[NMUTEXES];
+static pthread_t mutex_test_thread_handle;
+
+#if 0
+static cyg_mbox test_mboxes[NMBOXES];
+static cyg_handle_t test_mbox_handles[NMBOXES];
+static fun_times mbox_ft[NMBOXES];
+static cyg_thread mbox_test_thread;
+static cyg_handle_t mbox_test_thread_handle;
+#endif
+
+static sem_t test_semaphores[NSEMAPHORES];
+static fun_times semaphore_ft[NSEMAPHORES];
+static pthread_t semaphore_test_thread_handle;
+
+static fun_times sched_ft[NSCHEDS];
+
+static timer_t timers[NTIMERS];
+static fun_times timer_ft[NTIMERS];
+
+static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;
+static long ns_per_system_clock;
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY)
+// Data kept by kernel real time clock measuring clock interrupt latency
+extern cyg_tick_count total_clock_latency, total_clock_interrupts;
+extern cyg_int32 min_clock_latency, max_clock_latency;
+extern bool measure_clock_latency;
+#endif
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY)
+extern cyg_tick_count total_clock_dsr_latency, total_clock_dsr_calls;
+extern cyg_int32 min_clock_dsr_latency, max_clock_dsr_latency;
+extern bool measure_clock_latency;
+#endif
+
+//==========================================================================
+
+void run_sched_tests(void);
+void run_thread_tests(void);
+void run_thread_switch_test(void);
+void run_mutex_tests(void);
+void run_mutex_circuit_test(void);
+void run_mbox_tests(void);
+void run_mbox_circuit_test(void);
+void run_semaphore_tests(void);
+void run_semaphore_circuit_test(void);
+void run_timer_tests(void);
+
+//==========================================================================
+
+#ifndef max
+#define max(n,m) (m > n ? n : m)
+#endif
+
+//==========================================================================
+// Wait until a clock tick [real time clock] has passed.  This should keep it
+// from happening again during a measurement, thus minimizing any fluctuations
+void
+wait_for_tick(void)
+{
+    cyg_tick_count_t tv0, tv1;
+    tv0 = cyg_current_time();
+    while (true) {
+        tv1 = cyg_current_time();
+        if (tv1 != tv0) break;
+    }
+}
+
+//--------------------------------------------------------------------------
+// Display a number of ticks as microseconds
+// Note: for improved calculation significance, values are kept in ticks*1000
+void
+show_ticks_in_us(cyg_uint32 ticks)
+{
+    long long ns;
+    ns = (ns_per_system_clock * (long long)ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD;
+    ns += 5;  // for rounding to .01us
+    diag_printf("%5d.%02d", (int)(ns/1000), (int)((ns%1000)/10));
+}
+
+//--------------------------------------------------------------------------
+//
+// If the kernel is instrumented to measure clock interrupt latency, these
+// measurements can be drastically perturbed by printing via "diag_printf()"
+// since that code may run with interrupts disabled for long periods.
+//
+// In order to get accurate/reasonable latency figures _for the kernel 
+// primitive functions beint tested_, the kernel's latency measurements
+// are suspended while the printing actually takes place.
+//
+// The measurements are reenabled after the printing, thus allowing for
+// fair measurements of the kernel primitives, which are not distorted
+// by the printing mechanisms.
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
+void
+disable_clock_latency_measurement(void)
+{
+    wait_for_tick();
+    measure_clock_latency = false;
+}
+
+void
+enable_clock_latency_measurement(void)
+{
+    wait_for_tick();
+    measure_clock_latency = true;
+}
+
+// Ensure that the measurements are reasonable (no startup anomalies)
+void
+reset_clock_latency_measurement(void)
+{
+  disable_clock_latency_measurement();
+  total_clock_latency = 0;
+  total_clock_interrupts = 0;
+  min_clock_latency = 0x7FFFFFFF;
+  max_clock_latency = 0;
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY)  
+  total_clock_dsr_latency = 0;
+  total_clock_dsr_calls = 0;
+  min_clock_dsr_latency = 0x7FFFFFFF;
+  max_clock_dsr_latency = 0;
+#endif  
+  enable_clock_latency_measurement();
+  
+}
+#else
+#define disable_clock_latency_measurement()
+#define enable_clock_latency_measurement()
+#define reset_clock_latency_measurement()
+#endif
+
+//--------------------------------------------------------------------------
+
+void
+show_times_hdr(void)
+{
+    disable_clock_latency_measurement();
+    diag_printf("\n");
+    diag_printf("                                 Confidence\n");
+    diag_printf("     Ave     Min     Max     Var  Ave  Min  Function\n");
+    diag_printf("  ======  ======  ======  ====== ========== ========\n");
+    enable_clock_latency_measurement();
+}
+
+void
+show_times_detail(fun_times ft[], int nsamples, char *title, bool ignore_first)
+{
+    int i, delta, min, max, con_ave, con_min, ave_dev;
+    int start_sample, total_samples;   
+    cyg_int32 total, ave;
+
+    if (ignore_first) {
+        start_sample = 1;
+        total_samples = nsamples-1;
+    } else {
+        start_sample = 0;
+        total_samples = nsamples;
+    }
+    total = 0;
+    min = 0x7FFFFFFF;
+    max = 0;
+    for (i = start_sample;  i < nsamples;  i++) {
+        if (ft[i].end < ft[i].start) {
+            // Clock wrapped around (timer tick)
+            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
+        } else {
+            delta = ft[i].end - ft[i].start;
+        }
+        delta -= overhead;
+        if (delta < 0) delta = 0;
+        delta *= 1000;
+        total += delta;
+        if (delta < min) min = delta;
+        if (delta > max) max = delta;
+    }
+    ave = total / total_samples;
+    total = 0;
+    ave_dev = 0;
+    for (i = start_sample;  i < nsamples;  i++) {
+        if (ft[i].end < ft[i].start) {
+            // Clock wrapped around (timer tick)
+            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
+        } else {
+            delta = ft[i].end - ft[i].start;
+        }
+        delta -= overhead;
+        if (delta < 0) delta = 0;
+        delta *= 1000;
+        delta = delta - ave;
+        if (delta < 0) delta = -delta;
+        ave_dev += delta;
+    }
+    ave_dev /= total_samples;
+    con_ave = 0;
+    con_min = 0;
+    for (i = start_sample;  i < nsamples;  i++) {
+        if (ft[i].end < ft[i].start) {
+            // Clock wrapped around (timer tick)
+            delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start;
+        } else {
+            delta = ft[i].end - ft[i].start;
+        }
+        delta -= overhead;
+        if (delta < 0) delta = 0;
+        delta *= 1000;
+        if ((delta <= (ave+ave_dev)) && (delta >= (ave-ave_dev))) con_ave++;
+        if ((delta <= (min+ave_dev)) && (delta >= (min-ave_dev))) con_min++;
+    }
+    con_ave = (con_ave * 100) / total_samples;
+    con_min = (con_min * 100) / total_samples;
+    show_ticks_in_us(ave);
+    show_ticks_in_us(min);
+    show_ticks_in_us(max);
+    show_ticks_in_us(ave_dev);
+    disable_clock_latency_measurement();
+    diag_printf("  %3d%% %3d%%", con_ave, con_min);
+    diag_printf(" %s\n", title);
+    enable_clock_latency_measurement();
+}
+
+void
+show_times(fun_times ft[], int nsamples, char *title)
+{
+    show_times_detail(ft, nsamples, title, false);
+#ifdef STATS_WITHOUT_FIRST_SAMPLE
+    show_times_detail(ft, nsamples, "", true);
+#endif
+}
+
+//--------------------------------------------------------------------------
+
+void
+show_test_parameters(void)
+{
+    disable_clock_latency_measurement();
+    diag_printf("\nTesting parameters:\n");
+    diag_printf("   Clock samples:         %5d\n", nsamples);
+    diag_printf("   Threads:               %5d\n", ntest_threads);
+    diag_printf("   Thread switches:       %5d\n", nthread_switches);
+    diag_printf("   Mutexes:               %5d\n", nmutexes);
+    diag_printf("   Mailboxes:             %5d\n", nmboxes);
+    diag_printf("   Semaphores:            %5d\n", nsemaphores);
+    diag_printf("   Scheduler operations:  %5d\n", nscheds);
+    diag_printf("   Timers:                %5d\n", ntimers);
+    diag_printf("\n"); 
+    enable_clock_latency_measurement();
+}
+
+void
+end_of_test_group(void)
+{
+    disable_clock_latency_measurement();
+    diag_printf("\n"); 
+    enable_clock_latency_measurement();
+}
+
+//--------------------------------------------------------------------------
+// Compute a name for a thread
+
+char *
+thread_name(char *basename, int indx) {
+    return "<<NULL>>";  // Not currently used
+}
+
+//--------------------------------------------------------------------------
+// test0 - null test, just return
+
+void *
+test0(void *indx)
+{
+    return indx;
+}
+
+//--------------------------------------------------------------------------
+// test3 - loop, yeilding repeatedly and checking for cancellation
+
+void *
+test3(void *indx)
+{
+    for(;;)
+    {
+        sched_yield();
+        pthread_testcancel();
+    }
+    
+    return indx;
+}
+
+//--------------------------------------------------------------------------
+// test1 - empty test, simply exit.  Last thread signals parent.
+
+void *
+test1( void *indx)
+{
+    if ((cyg_uint32)indx == (cyg_uint32)(ntest_threads-1)) {
+        sem_post(&synchro);  // Signal that last thread is dying
+    }
+    return indx;
+}
+
+//--------------------------------------------------------------------------
+// test2 - measure thread switch times
+
+void *
+test2(void *indx)
+{
+    int i;
+    for (i = 0;  i < nthread_switches;  i++) {
+        if ((int)indx == 0) {
+            HAL_CLOCK_READ(&test2_ft[i].start);
+        } else {
+            HAL_CLOCK_READ(&test2_ft[i].end);
+        }
+        sched_yield();
+    }
+    if ((int)indx == 1) {
+        sem_post(&synchro);
+    }
+
+    return indx;
+}
+
+//--------------------------------------------------------------------------
+// Full-circuit mutex unlock/lock test
+
+void *
+mutex_test(void * indx)
+{
+    int i;
+    pthread_mutex_lock(&test_mutexes[0]);
+    for (i = 0;  i < nmutexes;  i++) {
+        sem_wait(&synchro);
+        wait_for_tick(); // Wait until the next clock tick to minimize aberations
+        HAL_CLOCK_READ(&mutex_ft[i].start);
+        pthread_mutex_unlock(&test_mutexes[0]);
+        pthread_mutex_lock(&test_mutexes[0]);
+        sem_post(&synchro);
+    }
+    return indx;
+}
+
+//--------------------------------------------------------------------------
+// Full-circuit mbox put/get test
+
+#if 0
+void
+mbox_test(cyg_uint32 indx)
+{
+    void *item;
+    do {
+        item = cyg_mbox_get(test_mbox_handles[0]);
+        HAL_CLOCK_READ(&mbox_ft[(int)item].end);
+        cyg_semaphore_post(&synchro);
+    } while ((int)item != (nmboxes-1));
+    cyg_thread_exit(0);
+}
+#endif
+
+//--------------------------------------------------------------------------
+// Full-circuit semaphore post/wait test
+
+void *
+semaphore_test(void * indx)
+{
+    int i;
+    for (i = 0;  i < nsemaphores;  i++) {
+        sem_wait(&test_semaphores[0]);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+        sem_post(&synchro);
+    }
+    return indx;
+}
+
+//--------------------------------------------------------------------------
+//
+// This set of tests is used to measure kernel primitives that deal with threads
+//
+
+void
+run_thread_tests(void)
+{
+
+    
+    int i;
+    struct sched_param schedparam;
+    pthread_attr_t attr;
+    int policy;
+    void *retval;
+    
+    // Set my priority higher than any I plan to create
+    schedparam.sched_priority = 30;
+    pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
+
+    // Initiaize thread creation attributes
+
+    pthread_attr_init( &attr );
+    pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+    pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    schedparam.sched_priority = 10;
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+
+        pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
+        pthread_attr_setstacksize( &attr, STACK_SIZE );
+        pthread_create( &threads[i],
+                        &attr,
+                        test0,
+                        (void *)i
+                        );
+        
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Create thread");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+        sched_yield();
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Yield thread [all lower priority]");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+
+        schedparam.sched_priority = 11;
+        pthread_attr_setschedparam( &attr, &schedparam );
+        pthread_setschedparam(threads[i], SCHED_RR, &schedparam);
+
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Set priority");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+        pthread_getschedparam( threads[i], &policy, &schedparam );
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Get priority");
+
+    cyg_thread_delay(1);        // Let the test threads run
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+        pthread_join(threads[i], &retval);
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Join exited thread");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+        sched_yield();
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Yield [no other] thread");
+
+    
+    // Recreate the test set
+
+    schedparam.sched_priority = 10;
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    for (i = 0;  i < ntest_threads;  i++) {
+        pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
+        pthread_attr_setstacksize( &attr, STACK_SIZE );
+        pthread_create( &threads[i],
+                        &attr,
+                        test3,
+                        (void *)i
+                        );
+    }
+
+    cyg_thread_delay(1);        // Let the test threads run    
+    
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+        pthread_cancel(threads[i]);
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Cancel [running] thread");
+
+    cyg_thread_delay(1);        // Let the test threads do their cancellations
+    
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+        pthread_join(threads[i], &retval);
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Join [cancelled] thread");
+
+    
+    // Set my priority lower than any I plan to create
+    schedparam.sched_priority = 5;
+    pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
+    
+    // Set up the end-of-threads synchronizer
+    sem_init(&synchro, 0, 0);
+
+    schedparam.sched_priority = 10;
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntest_threads;  i++) {
+        HAL_CLOCK_READ(&thread_ft[i].start);
+
+        pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
+        pthread_attr_setstacksize( &attr, STACK_SIZE );
+        pthread_create( &threads[i],
+                        &attr,
+                        test2,
+                        (void *)i
+                        );
+        
+        HAL_CLOCK_READ(&thread_ft[i].end);
+    }
+    show_times(thread_ft, ntest_threads, "Create [high priority] thread");
+
+    sem_wait(&synchro);  // Wait for all threads to finish
+
+    // Make sure they are all dead
+    for (i = 0;  i < ntest_threads;  i++) {
+        pthread_join(threads[i], &retval);
+    }
+
+    run_thread_switch_test();
+    end_of_test_group();
+
+}
+
+//--------------------------------------------------------------------------
+
+void
+run_thread_switch_test(void)
+{
+
+    int i;
+    struct sched_param schedparam;
+    pthread_attr_t attr;
+    void *retval;
+
+    // Set my priority higher than any I plan to create
+    schedparam.sched_priority = 30;
+    pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
+
+    // Initiaize thread creation attributes
+
+    pthread_attr_init( &attr );
+    pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+    pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    schedparam.sched_priority = 10;
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    // Set up the end-of-threads synchronizer
+
+    sem_init(&synchro, 0, 0);
+        
+    // Set up for thread context switch 
+
+    for (i = 0;  i < 2;  i++) {
+        pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
+        pthread_attr_setstacksize( &attr, STACK_SIZE );
+        pthread_create( &threads[i],
+                        &attr,
+                        test2,
+                        (void *)i
+                        );
+    }
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations    
+    
+    sem_wait(&synchro);
+
+    show_times(test2_ft, nthread_switches, "Thread switch");
+
+    // Clean up
+    for (i = 0;  i < 2;  i++) {
+        pthread_join(threads[i], &retval);
+    }
+
+}
+
+
+//--------------------------------------------------------------------------
+
+void
+run_mutex_tests(void)
+{
+
+    int i;
+    pthread_mutexattr_t attr;
+
+    pthread_mutexattr_init( &attr );
+    
+    // Mutex primitives
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmutexes;  i++) {
+        HAL_CLOCK_READ(&mutex_ft[i].start);
+        pthread_mutex_init(&test_mutexes[i], &attr);
+        HAL_CLOCK_READ(&mutex_ft[i].end);
+    }
+    show_times(mutex_ft, nmutexes, "Init mutex");
+
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmutexes;  i++) {
+        HAL_CLOCK_READ(&mutex_ft[i].start);
+        pthread_mutex_lock(&test_mutexes[i]);
+        HAL_CLOCK_READ(&mutex_ft[i].end);
+    }
+    show_times(mutex_ft, nmutexes, "Lock [unlocked] mutex");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmutexes;  i++) {
+        HAL_CLOCK_READ(&mutex_ft[i].start);
+        pthread_mutex_unlock(&test_mutexes[i]);
+        HAL_CLOCK_READ(&mutex_ft[i].end);
+    }
+    show_times(mutex_ft, nmutexes, "Unlock [locked] mutex");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmutexes;  i++) {
+        HAL_CLOCK_READ(&mutex_ft[i].start);
+        pthread_mutex_trylock(&test_mutexes[i]);
+        HAL_CLOCK_READ(&mutex_ft[i].end);
+    }
+    show_times(mutex_ft, nmutexes, "Trylock [unlocked] mutex");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmutexes;  i++) {
+        HAL_CLOCK_READ(&mutex_ft[i].start);
+        pthread_mutex_trylock(&test_mutexes[i]);
+        HAL_CLOCK_READ(&mutex_ft[i].end);
+    }
+    show_times(mutex_ft, nmutexes, "Trylock [locked] mutex");
+
+    // Must unlock mutices before destroying them.
+    for (i = 0;  i < nmutexes;  i++) {
+        pthread_mutex_unlock(&test_mutexes[i]);
+    }
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmutexes;  i++) {
+        HAL_CLOCK_READ(&mutex_ft[i].start);
+        pthread_mutex_destroy(&test_mutexes[i]);
+        HAL_CLOCK_READ(&mutex_ft[i].end);
+    }
+    show_times(mutex_ft, nmutexes, "Destroy mutex");
+
+
+    run_mutex_circuit_test();
+    end_of_test_group();
+}
+
+//--------------------------------------------------------------------------
+
+void
+run_mutex_circuit_test(void)
+{
+    int i;
+    pthread_mutexattr_t mattr;
+    struct sched_param schedparam;
+    pthread_attr_t attr;
+    void *retval;
+
+    // Set my priority lower than any I plan to create
+    schedparam.sched_priority = 5;
+    pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
+
+    // Initiaize thread creation attributes
+
+    pthread_attr_init( &attr );
+    pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+    pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    schedparam.sched_priority = 10;
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    // Set up for full mutex unlock/lock test
+    pthread_mutexattr_init( &mattr );    
+    pthread_mutex_init(&test_mutexes[0], &mattr);
+    sem_init(&synchro, 0, 0);
+
+    pthread_attr_setstackaddr( &attr, &stacks[0][STACK_SIZE] );
+    pthread_attr_setstacksize( &attr, STACK_SIZE );
+    pthread_create( &mutex_test_thread_handle,
+                    &attr,
+                    mutex_test,
+                    (void *)0
+        );
+    
+    // Need to raise priority so that this thread will block on the "lock"
+    schedparam.sched_priority = 20;
+    pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
+    
+    for (i = 0;  i < nmutexes;  i++) {
+        sem_post(&synchro);
+        pthread_mutex_lock(&test_mutexes[0]);
+        HAL_CLOCK_READ(&mutex_ft[i].end);
+        pthread_mutex_unlock(&test_mutexes[0]);
+        sem_wait(&synchro);
+    }
+    pthread_join(mutex_test_thread_handle, &retval);
+    show_times(mutex_ft, nmutexes, "Unlock/Lock mutex");
+
+}
+
+
+//--------------------------------------------------------------------------
+// Message queue tests
+
+// Currently disabled, pending implementation of POSIX message queues
+
+#if 0
+void
+run_mbox_tests(void)
+{
+    int i, cnt;
+    void *item;
+    // Mailbox primitives
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_create(&test_mbox_handles[i], &test_mboxes[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Create mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cnt = cyg_mbox_peek(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Peek [empty] mbox");
+
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_put(test_mbox_handles[i], (void *)i);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Put [first] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cnt = cyg_mbox_peek(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Peek [1 msg] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_put(test_mbox_handles[i], (void *)i);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Put [second] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cnt = cyg_mbox_peek(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Peek [2 msgs] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        item = cyg_mbox_get(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Get [first] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        item = cyg_mbox_get(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Get [second] mbox");
+#endif // ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_tryput(test_mbox_handles[i], (void *)i);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Tryput [first] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        item = cyg_mbox_peek_item(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Peek item [non-empty] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        item = cyg_mbox_tryget(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Tryget [non-empty] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        item = cyg_mbox_peek_item(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Peek item [empty] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        item = cyg_mbox_tryget(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Tryget [empty] mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_waiting_to_get(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Waiting to get mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_waiting_to_put(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Waiting to put mbox");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nmboxes;  i++) {
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_delete(test_mbox_handles[i]);
+        HAL_CLOCK_READ(&mbox_ft[i].end);
+    }
+    show_times(mbox_ft, nmboxes, "Delete mbox");
+
+    run_mbox_circuit_test();
+    end_of_test_group();
+}
+
+//--------------------------------------------------------------------------
+
+void
+run_mbox_circuit_test(void)
+{
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+    int i;
+    // Set my priority lower than any I plan to create
+    cyg_thread_set_priority(cyg_thread_self(), 3);
+    // Set up for full mbox put/get test
+    cyg_mbox_create(&test_mbox_handles[0], &test_mboxes[0]);
+    cyg_semaphore_init(&synchro, 0);
+    cyg_thread_create(2,              // Priority - just a number
+                      mbox_test,           // entry
+                      0,               // index
+                      thread_name("thread", 0),     // Name
+                      &stacks[0][0],   // Stack
+                      STACK_SIZE,      // Size
+                      &mbox_test_thread_handle,   // Handle
+                      &mbox_test_thread    // Thread data structure
+        );
+    cyg_thread_resume(mbox_test_thread_handle);
+    for (i = 0;  i < nmboxes;  i++) {
+        wait_for_tick(); // Wait until the next clock tick to minimize aberations
+        HAL_CLOCK_READ(&mbox_ft[i].start);
+        cyg_mbox_put(test_mbox_handles[0], (void *)i);
+        cyg_semaphore_wait(&synchro);
+    }
+    cyg_thread_delete(mbox_test_thread_handle);
+    show_times(mbox_ft, nmboxes, "Put/Get mbox");
+#endif
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+
+void
+run_semaphore_tests(void)
+{
+
+    int i;
+    int sem_val;
+
+    // Semaphore primitives
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nsemaphores;  i++) {
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_init(&test_semaphores[i], 0, 0);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+    }
+    show_times(semaphore_ft, nsemaphores, "Init semaphore");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nsemaphores;  i++) {
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_post(&test_semaphores[i]);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+    }
+    show_times(semaphore_ft, nsemaphores, "Post [0] semaphore");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nsemaphores;  i++) {
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_wait(&test_semaphores[i]);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+    }
+    show_times(semaphore_ft, nsemaphores, "Wait [1] semaphore");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nsemaphores;  i++) {
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_trywait(&test_semaphores[i]);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+    }
+    show_times(semaphore_ft, nsemaphores, "Trywait [0] semaphore");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nsemaphores;  i++) {
+        sem_post(&test_semaphores[i]);
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_trywait(&test_semaphores[i]);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+    }
+    show_times(semaphore_ft, nsemaphores, "Trywait [1] semaphore");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nsemaphores;  i++) {
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_getvalue(&test_semaphores[i], &sem_val);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+    }
+    show_times(semaphore_ft, nsemaphores, "Get value of semaphore");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < nsemaphores;  i++) {
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_destroy(&test_semaphores[i]);
+        HAL_CLOCK_READ(&semaphore_ft[i].end);
+    }
+    show_times(semaphore_ft, nsemaphores, "Destroy semaphore");
+
+    run_semaphore_circuit_test();
+    end_of_test_group();
+}
+
+//--------------------------------------------------------------------------
+
+void
+run_semaphore_circuit_test(void)
+{
+
+    int i;
+    struct sched_param schedparam;
+    pthread_attr_t attr;
+    void *retval;
+
+    // Set my priority lower than any I plan to create
+    schedparam.sched_priority = 5;
+    pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
+
+    // Initiaize thread creation attributes
+
+    pthread_attr_init( &attr );
+    pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+    pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    schedparam.sched_priority = 10;
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    // Set up for full semaphore post/wait test
+    sem_init(&test_semaphores[0], 0, 0);
+    sem_init(&synchro, 0, 0);
+
+    pthread_attr_setstackaddr( &attr, &stacks[0][STACK_SIZE] );
+    pthread_attr_setstacksize( &attr, STACK_SIZE );
+    pthread_create( &semaphore_test_thread_handle,
+                    &attr,
+                    semaphore_test,
+                    (void *)0
+        );
+    
+    
+    for (i = 0;  i < nsemaphores;  i++) {
+        wait_for_tick(); // Wait until the next clock tick to minimize aberations
+        HAL_CLOCK_READ(&semaphore_ft[i].start);
+        sem_post(&test_semaphores[0]);
+        sem_wait(&synchro);
+    }
+    pthread_join(semaphore_test_thread_handle, &retval);
+    
+    show_times(semaphore_ft, nsemaphores, "Post/Wait semaphore");
+
+
+}
+
+//--------------------------------------------------------------------------
+
+// Timer callback function
+void
+sigrt0(int signo, siginfo_t *info, void *context)
+{
+    diag_printf("sigrt0 called\n");
+    // empty call back
+}
+
+// Callback used to test determinancy
+static volatile int timer_cnt;
+void
+sigrt1(int signo, siginfo_t *info, void *context)
+{
+    if (timer_cnt == nscheds) return;
+    sched_ft[timer_cnt].start = 0;
+    HAL_CLOCK_READ(&sched_ft[timer_cnt++].end);
+    if (timer_cnt == nscheds) {
+        sem_post(&synchro);
+    }
+}
+
+static sem_t timer_sem;
+
+static void
+sigrt2(int signo, siginfo_t *info, void *context)
+{
+    if (timer_cnt == nscheds) {
+        sem_post(&synchro);
+        sem_post(&timer_sem);        
+    } else {
+        sched_ft[timer_cnt].start = 0;
+        sem_post(&timer_sem);
+    }
+}
+
+// Null thread, used to keep scheduler busy
+void *
+timer_test(void * id)
+{
+    while (true) {
+        cyg_thread_yield();
+        pthread_testcancel();
+    }
+
+    return id;
+}
+
+// Thread that suspends itself at the first opportunity
+void *
+timer_test2(void *id)
+{
+    while (timer_cnt != nscheds) {
+        HAL_CLOCK_READ(&sched_ft[timer_cnt++].end);
+        sem_wait(&timer_sem);
+    }
+    return id;
+}
+
+void
+run_timer_tests(void)
+{
+    int res;
+    int i;
+    struct sigaction sa;
+    struct sigevent sigev;
+    struct itimerspec tp;
+    
+    // Install signal handlers
+    sigemptyset( &sa.sa_mask );
+    sa.sa_flags = SA_SIGINFO;
+
+    sa.sa_sigaction = sigrt0;
+    sigaction( SIGRTMIN, &sa, NULL );
+
+    sa.sa_sigaction = sigrt1;
+    sigaction( SIGRTMIN+1, &sa, NULL );
+
+    sa.sa_sigaction = sigrt2;
+    sigaction( SIGRTMIN+2, &sa, NULL );
+
+    // Set up common bits of sigevent
+
+    sigev.sigev_notify = SIGEV_SIGNAL;
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntimers;  i++) {
+        HAL_CLOCK_READ(&timer_ft[i].start);
+        sigev.sigev_signo = SIGRTMIN;
+        sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
+        res = timer_create( CLOCK_REALTIME, &sigev, &timers[i]);
+        HAL_CLOCK_READ(&timer_ft[i].end);
+        CYG_ASSERT( res == 0 , "timer_create() returned error");
+    }
+    show_times(timer_ft, ntimers, "Create timer");
+
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    tp.it_value.tv_sec = 0;
+    tp.it_value.tv_nsec = 0;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 0;
+    for (i = 0;  i < ntimers;  i++) {
+        HAL_CLOCK_READ(&timer_ft[i].start);
+        res = timer_settime( timers[i], 0, &tp, NULL );
+        HAL_CLOCK_READ(&timer_ft[i].end);
+        CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    }
+    show_times(timer_ft, ntimers, "Initialize timer to zero");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    tp.it_value.tv_sec = 1;
+    tp.it_value.tv_nsec = 250000000;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 0;
+    for (i = 0;  i < ntimers;  i++) {
+        HAL_CLOCK_READ(&timer_ft[i].start);
+        res = timer_settime( timers[i], 0, &tp, NULL );
+        HAL_CLOCK_READ(&timer_ft[i].end);
+        CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    }
+    show_times(timer_ft, ntimers, "Initialize timer to 1.25 sec");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    tp.it_value.tv_sec = 0;
+    tp.it_value.tv_nsec = 0;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 0;
+    for (i = 0;  i < ntimers;  i++) {
+        HAL_CLOCK_READ(&timer_ft[i].start);
+        res = timer_settime( timers[i], 0, &tp, NULL );
+        HAL_CLOCK_READ(&timer_ft[i].end);
+        CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    }
+    show_times(timer_ft, ntimers, "Disable timer");
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    for (i = 0;  i < ntimers;  i++) {
+        HAL_CLOCK_READ(&timer_ft[i].start);
+        res = timer_delete( timers[i] );
+        HAL_CLOCK_READ(&timer_ft[i].end);
+        CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    }
+    show_times(timer_ft, ntimers, "Delete timer");
+    
+    
+
+    sigev.sigev_signo = SIGRTMIN+1;
+    sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
+    res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
+    CYG_ASSERT( res == 0 , "timer_create() returned error");
+    tp.it_value.tv_sec = 0;
+    tp.it_value.tv_nsec = 50000000;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 50000000;;
+    timer_cnt = 0;
+    res = timer_settime( timers[0], 0, &tp, NULL );
+    CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    sem_init(&synchro, 0, 0);
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    do
+    { res = sem_wait(&synchro);
+    } while( res == -1 && errno == EINTR );
+    CYG_ASSERT( res == 0 , "sem_wait() returned error");        
+    tp.it_value.tv_sec = 0;
+    tp.it_value.tv_nsec = 0;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 0;
+    res = timer_settime( timers[0], 0, &tp, NULL );
+    CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    res = timer_delete( timers[0] );
+    CYG_ASSERT( res == 0 , "timer_delete() returned error");
+    show_times(sched_ft, nscheds, "Timer latency [0 threads]");
+
+
+    
+
+    struct sched_param schedparam;
+    pthread_attr_t attr;
+    void *retval;
+    
+    // Set my priority higher than any I plan to create
+    schedparam.sched_priority = 20;
+    pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
+
+    
+    // Initiaize thread creation attributes
+
+    pthread_attr_init( &attr );
+    pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
+    pthread_attr_setschedpolicy( &attr, SCHED_RR );
+    schedparam.sched_priority = 10;
+    pthread_attr_setschedparam( &attr, &schedparam );
+    
+    for (i = 0;  i < 2;  i++) {
+        pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
+        pthread_attr_setstacksize( &attr, STACK_SIZE );
+        res = pthread_create( &threads[i],
+                        &attr,
+                        timer_test,
+                        (void *)i
+                        );
+        CYG_ASSERT( res == 0 , "pthread_create() returned error");
+    }
+
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+
+    sigev.sigev_signo = SIGRTMIN+1;
+    sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
+    res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
+    CYG_ASSERT( res == 0 , "timer_create() returned error");
+    tp.it_value.tv_sec = 0;
+    tp.it_value.tv_nsec = 50000000;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 50000000;;
+    timer_cnt = 0;
+    res = timer_settime( timers[0], 0, &tp, NULL );
+    CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    
+    sem_init(&synchro, 0, 0);
+    do
+    { res = sem_wait(&synchro);
+    } while( res == -1 && errno == EINTR );
+    CYG_ASSERT( res == 0 , "sem_wait() returned error");        
+    res = timer_delete(timers[0]);
+    CYG_ASSERT( res == 0 , "timerdelete() returned error");    
+    show_times(sched_ft, nscheds, "Timer latency [2 threads]");
+    for (i = 0;  i < 2;  i++) {
+        pthread_cancel(threads[i]);
+        pthread_join(threads[i], &retval);
+    }
+
+
+    
+    for (i = 0;  i < ntest_threads;  i++) {
+        pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
+        pthread_attr_setstacksize( &attr, STACK_SIZE );
+        res = pthread_create( &threads[i],
+                        &attr,
+                        timer_test,
+                        (void *)i
+                        );
+        CYG_ASSERT( res == 0 , "pthread_create() returned error");
+    }
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    sigev.sigev_signo = SIGRTMIN+1;
+    sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
+    res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
+    CYG_ASSERT( res == 0 , "timer_create() returned error");
+    tp.it_value.tv_sec = 0;
+    tp.it_value.tv_nsec = 50000000;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 50000000;;
+    timer_cnt = 0;
+    res = timer_settime( timers[0], 0, &tp, NULL );
+    CYG_ASSERT( res == 0 , "timer_settime() returned error");
+    
+    sem_init(&synchro, 0, 0);
+    do
+    { res = sem_wait(&synchro);
+    } while( res == -1 && errno == EINTR );
+    CYG_ASSERT( res == 0 , "sem_wait() returned error");        
+    res = timer_delete(timers[0]);
+    CYG_ASSERT( res == 0 , "timerdelete() returned error");        
+    show_times(sched_ft, nscheds, "Timer latency [many threads]");
+    for (i = 0;  i < ntest_threads;  i++) {
+        pthread_cancel(threads[i]);
+        pthread_join(threads[i], &retval);
+    }
+
+    sem_init(&synchro, 0, 0);
+    sem_init(&timer_sem, 0, 0);    
+    pthread_attr_setstackaddr( &attr, &stacks[0][STACK_SIZE] );
+    pthread_attr_setstacksize( &attr, STACK_SIZE );
+    res = pthread_create( &threads[0],
+                          &attr,
+                          timer_test2,
+                          (void *)0
+        );
+    CYG_ASSERT( res == 0 , "pthread_create() returned error");
+    
+    wait_for_tick(); // Wait until the next clock tick to minimize aberations
+    sigev.sigev_signo = SIGRTMIN+2;
+    sigev.sigev_value.sival_ptr = (void*)(threads[0]);
+    res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
+    CYG_ASSERT( res == 0 , "timer_create() returned error");
+    tp.it_value.tv_sec = 0;
+    tp.it_value.tv_nsec = 50000000;
+    tp.it_interval.tv_sec = 0;
+    tp.it_interval.tv_nsec = 50000000;;
+    timer_cnt = 0;
+    res = timer_settime( timers[0], 0, &tp, NULL );
+    CYG_ASSERT( res == 0 , "timer_settime() returned error");
+
+    do
+    { res = sem_wait(&synchro);
+    } while( res == -1 && errno == EINTR );
+    CYG_ASSERT( res == 0 , "sem_wait() returned error");        
+    res = timer_delete(timers[0]);
+    CYG_ASSERT( res == 0 , "timerdelete() returned error");        
+    show_times(sched_ft, nscheds, "Timer -> thread post latency");
+    sem_post(&timer_sem);
+//    pthread_cancel(threads[0]);
+    pthread_join(threads[0], &retval);
+
+
+    end_of_test_group();
+}
+
+
+//--------------------------------------------------------------------------
+
+void 
+run_all_tests()
+{
+    int i;
+    cyg_uint32 tv[nsamples], tv0, tv1;
+//    cyg_uint32 min_stack, max_stack, total_stack, actual_stack, j;
+    cyg_tick_count_t ticks, tick0, tick1;
+#ifdef CYG_SCHEDULER_LOCK_TIMINGS
+    cyg_uint32 lock_ave, lock_max;
+#endif
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
+    cyg_int32 clock_ave;
+#endif
+
+    disable_clock_latency_measurement();
+
+//    cyg_test_dump_thread_stack_stats( "Startup, main stack", thread[0] );
+    cyg_test_dump_interrupt_stack_stats( "Startup" );
+    cyg_test_dump_idlethread_stack_stats( "Startup" );
+    cyg_test_clear_interrupt_stack();
+
+    diag_printf("\neCos Kernel Timings\n");
+    diag_printf("Notes: all times are in microseconds (.000001) unless otherwise stated\n");
+#ifdef STATS_WITHOUT_FIRST_SAMPLE
+    diag_printf("       second line of results have first sample removed\n");
+#endif
+
+    cyg_thread_delay(2);  // Make sure the clock is actually running
+
+    ns_per_system_clock = 1000000/rtc_resolution[1];
+
+    for (i = 0;  i < nsamples;  i++) {
+        HAL_CLOCK_READ(&tv[i]);
+    }
+    tv0 = 0;
+    for (i = 1;  i < nsamples;  i++) {
+        tv0 += tv[i] - tv[i-1];
+    }
+    end_of_test_group();
+    
+    overhead = tv0 / (nsamples-1);
+    diag_printf("Reading the hardware clock takes %d 'ticks' overhead\n", overhead);
+    diag_printf("... this value will be factored out of all other measurements\n");
+
+    // Try and measure how long the clock interrupt handling takes
+    for (i = 0;  i < nsamples;  i++) {
+        tick0 = cyg_current_time();
+        while (true) {
+            tick1 = cyg_current_time();
+            if (tick0 != tick1) break;
+        }
+        HAL_CLOCK_READ(&tv[i]);
+    }
+    tv1 = 0;
+    for (i = 0;  i < nsamples;  i++) {
+        tv1 += tv[i] * 1000;
+    }
+    tv1 = tv1 / nsamples;
+    tv1 -= overhead;  // Adjust out the cost of getting the timer value
+    diag_printf("Clock interrupt took");
+    show_ticks_in_us(tv1);
+    diag_printf(" microseconds (%d raw clock ticks)\n", tv1/1000);
+    enable_clock_latency_measurement();
+
+    ticks = cyg_current_time();
+
+    show_test_parameters();
+    show_times_hdr();
+
+    reset_clock_latency_measurement();
+
+    run_thread_tests();
+    run_mutex_tests();
+//    run_mbox_tests();
+    run_semaphore_tests();
+    run_timer_tests();
+
+#ifdef CYG_SCHEDULER_LOCK_TIMINGS
+    Cyg_Scheduler::get_lock_times(&lock_ave, &lock_max);
+    diag_printf("\nMax lock:");
+    show_ticks_in_us(lock_max);
+    diag_printf(", Ave lock:");
+    show_ticks_in_us(lock_ave);
+    diag_printf("\n");
+#endif
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
+    // Display latency figures in same format as all other numbers
+    disable_clock_latency_measurement();
+    clock_ave = (total_clock_latency*1000) / total_clock_interrupts;
+    show_ticks_in_us(clock_ave);
+    show_ticks_in_us(min_clock_latency*1000);
+    show_ticks_in_us(max_clock_latency*1000);
+    show_ticks_in_us(0);
+    diag_printf("            Clock/interrupt latency\n\n");
+    enable_clock_latency_measurement();    
+#endif
+
+#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY)
+    disable_clock_latency_measurement();    
+    clock_ave = (total_clock_dsr_latency*1000) / total_clock_dsr_calls;
+    show_ticks_in_us(clock_ave);
+    show_ticks_in_us(min_clock_dsr_latency*1000);
+    show_ticks_in_us(max_clock_dsr_latency*1000);
+    show_ticks_in_us(0);
+    diag_printf("            Clock DSR latency\n\n");
+    enable_clock_latency_measurement();
+#endif
+
+#if 0    
+    disable_clock_latency_measurement();
+    min_stack = STACK_SIZE;
+    max_stack = 0;
+    total_stack = 0;
+    for (i = 0;  i < (int)NTEST_THREADS;  i++) {
+        for (j = 0;  j < STACK_SIZE;  j++) {
+            if (stacks[i][j]) break;
+        }
+        actual_stack = STACK_SIZE-j;
+        if (actual_stack < min_stack) min_stack = actual_stack;
+        if (actual_stack > max_stack) max_stack = actual_stack;
+        total_stack += actual_stack;
+    }
+    for (j = 0;  j < STACKSIZE;  j++) {
+        if (((char *)stack[0])[j]) break;
+    }
+    diag_printf("%5d   %5d   %5d  (main stack: %5d)  Thread stack used (%d total)\n", 
+                total_stack/NTEST_THREADS, min_stack, max_stack, 
+                STACKSIZE - j, STACK_SIZE);
+#endif
+    
+//    cyg_test_dump_thread_stack_stats( "All done, main stack", thread[0] );
+    cyg_test_dump_interrupt_stack_stats( "All done" );
+    cyg_test_dump_idlethread_stack_stats( "All done" );
+
+    enable_clock_latency_measurement();
+
+    ticks = cyg_current_time();
+    diag_printf("\nTiming complete - %d ms total\n\n", (int)((ticks*ns_per_system_clock)/1000));
+
+    CYG_TEST_PASS_FINISH("Basic timing OK");
+}
+
+int main( int argc, char **argv )
+{
+    CYG_TEST_INIT();
+
+    if (cyg_test_is_simulator) {
+        nsamples = NSAMPLES_SIM;
+        ntest_threads = NTEST_THREADS_SIM;
+        nthread_switches = NTHREAD_SWITCHES_SIM;
+        nmutexes = NMUTEXES_SIM;
+        nmboxes = NMBOXES_SIM;
+        nsemaphores = NSEMAPHORES_SIM;
+        nscheds = NSCHEDS_SIM;
+        ntimers = NTIMERS_SIM;  
+    } else {
+        nsamples = NSAMPLES;
+        ntest_threads = NTEST_THREADS;
+        nthread_switches = NTHREAD_SWITCHES;
+        nmutexes = NMUTEXES; 
+        nmboxes = NMBOXES;
+        nsemaphores = NSEMAPHORES;
+        nscheds = NSCHEDS;
+        ntimers = NTIMERS;
+    }
+
+    // Sanity
+#ifdef WORKHORSE_TEST
+    ntest_threads = max(512, ntest_threads);
+    nmutexes = max(1024, nmutexes);
+    nsemaphores = max(1024, nsemaphores);
+    nmboxes = max(1024, nmboxes);
+    ncounters = max(1024, ncounters);
+    ntimers = max(1024, ntimers);
+#else
+    ntest_threads = max(64, ntest_threads);
+    nmutexes = max(32, nmutexes);
+    nsemaphores = max(32, nsemaphores);
+    nmboxes = max(32, nmboxes);
+    ntimers = max(32, ntimers);
+#endif
+
+    run_all_tests();
+   
+}
+
+#endif // CYGFUN_KERNEL_API_C, etc.
+
+// EOF tm_basic.cxx
diff --git a/packages/compat/uitron/v2_0/ChangeLog b/packages/compat/uitron/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..225ce80
--- /dev/null
@@ -0,0 +1,877 @@
+2005-08-02  Andrew Lunn  <andrew.lunn@ascom.ch>
+
+       * tests/test2.c (task1): Cast to fix compiler warning.
+
+2003-02-24  Jonathan Larmour  <jifl@eCosCentric.com>
+
+       * cdl/uitron.cdl: Update doc link.
+
+2002-05-27  Jesper Skov  <jskov@redhat.com>
+
+       * cdl/uitron.cdl: Don't build C tests when C++ options selected.
+
+2002-05-22  Nick Garnett  <nickg@redhat.com>
+
+       * doc/uitron.sgml: Fixed dangling xref.
+
+2002-02-19  Mark Salter  <msalter@redhat.com>
+
+       * doc/uitron.sgml: Fixed typos and such.
+
+2002-02-14  Hugo Tyson  <hmt@redhat.com>
+
+       * doc/uitron.sgml: General polishing... Tidied up broken emPHAsis
+       on closing parentheses of function lists.  Reduced line length of
+       same to fit real paper, I hope.  Added LITERAL tags all over
+       config option mentions.
+
+       New stuff... Added a whole new section "[u]ITRON Configuration
+       FAQ" based on some email answers I have given in the past in
+       support of customers.
+
+2002-02-13  Hugo Tyson  <hmt@redhat.com>
+
+       * doc/uitron.sgml: NEW FILE: Make id tags qualified with
+       compat-uitron- and add a couple of tags; tidy up formatting of
+       some function listings; correct comment on using functions in your
+       own DSRs and ISRs.
+
+2002-01-24  Jesper Skov  <jskov@redhat.com>
+
+       * include/uit_func.inl (ena_int, dis_int): Wrap
+       HAL_MASK_INTERRUPT/HAL_UNMASK_INTERRUPT in interrupt
+       disable/restore pairs.
+       * tests/testintr.cxx (detach_isr, attach_isr): Change order of
+       mask/unmask and disable/restore.
+
+2001-04-30  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * src/uit_objs.cxx: Workaround xscale tools preprocessor bug
+       by avoiding determining the stack size with the preprocessor.
+       * cdl/tasks.cdl (CYGDAT_UITRON_TASK_EXTERNS and 
+       CYGDAT_UITRON_TASK_INITIALISERS): Ditto
+
+2001-04-21  Bart Veer  <bartv@redhat.com>
+
+       * tests/testintr.cxx (task1):
+       Disable one of the tests on the synthetic target, it requires
+       consistent cpu timing that cannot be guaranteed.
+
+2000-11-01  Jesper Skov  <jskov@redhat.com>
+
+       * include/uit_func.inl: CYG_SCHED_UNIQUE_PRIORITIES changed to
+       CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
+
+2000-09-13  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * include/uit_objs.hxx (CYG_UITRON_OBJS_INIT_PRIORITY): Define
+       with correct priority now.
+
+2000-08-03  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * include/uit_func.inl (ref_mpf): Compute used blocks from
+       bytes used / blocks size rather than now obsolete blockcount member
+
+2000-07-04  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * include/uit_func.inl: Update all memory pool related functions to
+       reflect the new interface to memory pools, and that they come from
+       the new CYGPKG_MEMALLOC package
+
+       * cdl/uitron.cdl: CYGPKG_UITRON_MEMPOOLFIXED and
+       CYGPKG_UITRON_MEMPOOLVAR require the CYGPKG_MEMALLOC package
+
+       * include/uit_objs.hxx: Update includes - memory pool implementations
+       are now in CYGPKG_MEMALLOC
+
+2000-06-15  Gary Thomas  <gthomas@redhat.com>
+
+       * include/uit_ifnc.h (CYGPRI_UITRON_SET_RETCODE): Always return
+       'HANDLED'.  This fixes some confusion when interrupt chaining.
+
+2000-05-15  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_ifnc.h (cyg_uitron_dsr): make this be extern "C"
+       always; it went wrong when uitron funcs are inline or C++.
+
+       * src/uit_ifnc.cxx (CYGIMP_UITRON_INLINE_FUNCS): When [re]defining
+       this, match what CDL defined.  Warnings--;
+
+2000-05-08  Jesper Skov  <jskov@redhat.com>
+
+       * tests/testintr.cxx (attach_isr, detach_isr): Don't check for
+       clean vector after a detach when chaining is enabled.
+
+2000-03-28  Jesper Skov  <jskov@redhat.com>
+
+       * tests/testintr.cxx: Synchronize with clock before making timer
+       measurement.
+
+2000-03-28  John Dallaway  <jld@cygnus.co.uk>
+
+       * cdl/uitron.cdl:
+
+       Adjust documentation URLs.
+
+2000-03-22  Jesper Skov  <jskov@redhat.com>
+
+       * include/uit_ifnc.h (ret_int): Fix compiler warning.
+
+2000-03-13  Jesper Skov  <jskov@redhat.com>
+
+       * tests/testintr.cxx: Don't try to disable clock on PowerPC.
+
+2000-03-03  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testintr.cxx (task1): Only test ena_int() and dis_int()
+       for E_PAR if CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS.
+
+2000-02-28  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.h: add ena_int() and dis_int().
+
+       * include/uit_func.inl (dis_int): New function added.
+       (ena_int): New function added.
+
+       * tests/testintr.cxx (task1): Add a test of ena_int() and
+       dis_int(); easiest done here because we have an interrupt number -
+       for the clock - in our hands here already for the rest of the
+       test.
+
+2000-02-02  Jesper Skov  <jskov@redhat.com>
+
+       * tests/testintr.cxx: Don't output DELAYLOCKSCHED quite so often
+       on synthetic target.
+
+2000-01-31  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testintr.cxx (CHECK_TID): Test that get_tid() returns 0 in
+       ISR context ie. non-task portion.
+
+       * include/uit_func.inl (get_tid): Check the sched lock for
+       non-task portions, ie. ISR/DSR will have the scheduler locked.
+
+2000-01-31 Simon FitzMaurice  <sdf@cygnus.co.uk>
+  * compat/uitron/current/cdl/uitron.cdl
+
+  Adjust help URLs in line with new doc layout.
+
+2000-01-28 Simon FitzMaurice  <sdf@cygnus.co.uk>
+  * compat/uitron/current/cdl/uitron.cdl
+
+  Adjust help URLs in line with new doc layout.
+
+2000-01-28  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * tests/testintr.cxx (DELAYLOCKSCHED): When in long testing loops,
+       occasionally output a message to show the test is still alive
+
+2000-01-26  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: Add new option
+       CYGSEM_UITRON_TIME_IS_MILLISECONDS to control just what it says.
+
+       * include/uit_func.inl (CYG_UITRON_TIME_UIT_TO_SYS32): et al; new
+       macros optionally to convert to/from milliSeconds if option
+       CYGSEM_UITRON_TIME_IS_MILLISECONDS is set.
+
+       * src/uit_func.cxx: Initialize Cyg_Clock::converter type objects
+       if the time unit is set to milliSeconds.
+
+       * cdl/uitron.cdl: Add new option
+       CYGSEM_UITRON_TIME_IS_MILLISECONDS to control just what it says.
+
+       Add an include of the kernel config file to the generated
+       pkgconf/uitron.h: tests at the very least need it!  This is a
+       correct thing to do because the kernel config defines a lot of the
+       semantics of the uITRON layer, as well as being needed for
+       backward compatibility.
+
+       Also add uit_ifnc.cxx to the files that need compiling.  Due to
+       the previous screwup, no testing has been applied to the uITRON
+       system under CDL, because it thought the kernel was absent, so
+       this had not been detected.  Doh.
+
+2000-01-25  Jesper Skov  <jskov@cygnus.co.uk>
+
+       * tests/testintr.cxx (cyg_start): externC addded.
+
+2000-01-19  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * cdl/*.cdl: Add descriptions to a number of options &c which were
+       lacking same, also tidied up other typos as noticed en passant.
+
+1999-11-09  Jonathan Larmour  <jlarmour@cygnus.co.uk>
+
+       * src/uit_objs.cxx: Make the stack size failsafe be tested against
+       the minimum stack size, not the typical one.
+
+1999-11-03  John Dallaway  <jld@cygnus.co.uk>
+
+       * cdl/uitron.cdl: Define tests.
+
+1999-10-07  John Dallaway  <jld@cygnus.co.uk>
+
+       * cdl/uitron.cdl: Specify radio buttons using CDL interfaces.
+
+1999-09-06  Jonathan Larmour  <jlarmour@cygnus.co.uk>
+
+       * include/uit_objs.hxx (CYG_UITRON_OBJS_INIT_PRIORITY): Revert the
+       below change - we may still be shipping antiquated compilers to
+       customers. Sigh.
+
+1999-09-02  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_objs.hxx (CYG_UITRON_OBJS_INIT_PRIORITY): Enable
+       using init priority on uitron objects, now that the compilers all
+       support it fully.  AFAI can tell from a quite broad experiment.
+
+1999-09-01  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testintr.cxx (attach_isr): Make it all work: my chosen
+       default interrupt "level" of 0 means make no interrupts on the
+       tx39 ;-( oh well.  Made the whole test simulator-friendly ie. much
+       shorter, made the output more friendly to me.
+
+1999-08-26  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * cdl/uitron.cdl (CYGNUM_UITRON_ISR_ACTION_QUEUESIZE): add a
+       "default_value 32" - ooops.
+
+1999-08-26  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * cdl/uitron.cdl: Add configury for lovely new interrupt-safe
+       functions: just "try immediate execution" [is the sched lock one?]
+       and queue size.
+
+       * include/pkgconf/uitron.h: Add configury for lovely new
+       interrupt-safe functions: just "try immediate execution" [ie. if
+       the sched lock is one] and queue size.
+
+       * include/uit_ifnc.inl: Respond to general configury wrt the
+       presence of semas, flags, mboxes: only define the ixxx_yyy()
+       function if the corresponding xxx_yyy() func exists.  Remove the
+       static definitions of the configuration symbols.
+
+       * src/uit_ifnc.cxx: Respond to general configury wrt the presence
+       of semas, flags, mboxes: the functions called may not exist!
+
+1999-08-25  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_ifnc.h: New file.  Prototypes of interrupt-safe
+       ixxx_yyy() style functions as a porting/backwards-compatibility
+       aid.  Prototype of a suitable DSR to mate with an ISR that uses
+       them too.
+
+       * include/uit_ifnc.inl: New file.  Bodies for possible inlining of
+       the ixxx_yyy() style functions; organized much like the standard
+       uITRON functions.
+
+       * src/uit_ifnc.cxx: New file.  Implementation of the DSR provided,
+       plus concrete instantiations of the ixxx_yyy() style functions.
+
+       * tests/testintr.cxx: New file.  Test for the ixxx_yyy() functions
+       newly provided above.  Rather unpleasant: it is necessary to break
+       type-safety to get access to the kernel's interrupt object that
+       drives the realtime clock.  Perhaps a neater way will follow.
+
+       * tests/PKGconf.mak (TESTS): Add new testcase testintr.cxx
+       * src/PKGconf.mak (COMPILE): Add new source file uit_ifnc.cxx
+
+1999-08-17  John Dallaway  <jld@cygnus.co.uk>
+
+       * cdl/uitron.cdl: Implement radio buttons using
+       "FIXME radio" hack in description field for now.
+
+1999-07-30  John Dallaway  <jld@cygnus.co.uk>
+
+       * cdl/uitron.cdl: Tidy display string capitalisation.
+
+1999-05-26  Jesper Skov  <jskov@cygnus.co.uk>
+
+       * tests/testcx7.cxx: Include new stackmon header.
+
+1999-05-20  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testcx7.cxx (task1): Add some statistics dumping about
+       stack usage; since this is quite a long and arduous test.  This
+       just helps en passant with testing the interrupt stack work that's
+       been happening recently.  C++ only, so not for test7.
+
+1999-05-17  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/uit_func.inl (ter_tsk): Only up the priority of the
+       killee if priorities are not unique or we are not already
+       elevated.  This is to prevent asserts with the bitmap scheduler.
+       (chg_pri): Support a level X feature, pri zero => reset to the
+       thread's initial priority.
+
+1999-05-14  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/uit_objs.hxx: object array declaration macro now
+       contains constructor priority ordering rune; if 0'd out pending 
+       99r1 compiler cutover.
+
+1999-04-23  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testcx7.cxx: T2_MALLOC definition; only make it smaller
+       than the main consumer malloc if coaleasing is enabled, otherwise
+       the mempool cannot allocate blocks for the consumer for next time.
+       Fixes PR 18817 - only a random perm disable coalescence.
+
+       * tests/test7.c: Ditto.
+
+1999-04-15  John Dallaway  <jld@cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: Tidy display string capitalization.
+
+1999-04-09  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.inl (dis_dsp): Remove bad old code which used
+       to lock the scheduler to implement dis_dsp() and ena_dsp() - which
+       also stopped the clock, for example.  Instead change the calling
+       thread's priority to 0 internally so that it cannot be preempted
+       by uITRON threads at least, whose priorities are 1--N.  Same
+       applies to loc/unl_cpu().  Save the "real" priority in a static,
+       and take notice of it everywhere relevant, such as thread and
+       system state inquiries, changing (our own) priority, checking for
+       dispatch enabled in sleeping calls, and so on.
+
+       * src/uit_func.cxx: New variable cyg_uitron_dis_dsp_old_priority
+       for holding the "real" priority of a thread whilst we change our
+       priority to zero (the highest) to prevent dispatching in dis_dsp()
+       or loc_cpu().
+
+       * include/uit_func.inl (get_tid): Return 0 for the task id if not
+       in a uITRON thread, this is better conformance to the spec.
+
+1999-03-22  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * src/uit_objs.cxx: 
+       Use CYGNUM_HAL_STACK_SIZE_TYPICAL for the stack size instead of
+       CYGNUM_HAL_MINIMUM_STACK_SIZE.
+
+1999-02-23  Jonathan Larmour  <jlarmour@cygnus.co.uk>
+
+       * tests/test1.c, tests/test2.c, tests/test3.c, tests/test4.c,
+         tests/test5.c, tests/test6.c, tests/test7.c, tests/test8.c,
+         tests/test9.c, tests/testcxx.cxx, tests/testcx2.cxx,
+         tests/testcx3.cxx, tests/testcx4.cxx, tests/testcx5.cxx,
+         tests/testcx6.cxx, tests/testcx7.cxx, tests/testcx8.cxx,
+         tests/testcx9.cxx:
+       Change all non-applicable cases to use CYG_TEST_NA rather than
+       CYG_TEST_PASS/CYG_TEST_EXIT
+
+1999-02-22  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * src/uit_objs.cxx: Eeeek!  Previous fix was bogus: the override
+       was too late in the file to take effect.  The declaration of the
+       objects (including stacks) is moved to below the override CPP
+       runes.
+
+1999-02-12  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * src/uit_objs.cxx (CYG_UITRON_DECL):
+       Override CYGNUM_UITRON_STACK_SIZE if CYGNUM_HAL_MINIMUM_STACK_SIZE
+       demands it.
+
+       * include/pkgconf/uitron.h (CYGNUM_UITRON_STACK_SIZE): 
+       Document that this option can be overridden by HALs demands.
+
+1999-02-02  Jesper Skov  <jskov@cygnus.co.uk>
+        PR 18968
+       * tests/test2.c (task1): 
+       * tests/testcx2.cxx (task1): 
+       Reduce run time on SIM.
+
+1999-01-26  Jesper Skov  <jskov@cygnus.co.uk>
+        PR 18788
+       * tests/test4.c (task1): 
+       * tests/testcx4.cxx (task1): 
+       Extend timeouts when running on HW to avoid failures due to
+       overhead of GDB interaction.
+
+1999-01-25  Jesper Skov  <jskov@cygnus.co.uk>
+        PR 18576
+       * include/pkgconf/uitron.h (CYGDAT_UITRON_SEMA_INITIALIZERS): 
+       Let default initializers have values that don't cause tests to
+       fail.
+
+1998-11-25  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.inl (del_xxx &c):
+       Make error returns more consistent; E_NOEXS rather than E_OBJ if
+       the object disappeared during a race.
+
+1998-11-19  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * src/uit_func.cxx (SET_UP_PTRS): 
+       PR 17999; work around codegen bug on tx39 with -Os.
+       The code is better with the fix regardless, so it's got no
+       downside.  Explicitly condition whether to run a follow-on loop
+       rather than letting the for-loop sort it out itself.
+
+1998-11-16  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testcx7.cxx (check_waitstate): 
+       Add a routine to check the reported waiting state of the synch
+       object in question, and call it as necessary.  This only added to
+       the C++ version of the test for enhanced coverage, in case the
+       enquiry call perturbs the object state; having both versions
+       present is better.  This checks a very recent fix to
+       kernel...thread.cxx (1998-10-27).
+
+1998-10-21  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * src/uit_func.cxx: 
+       Provide weakly named dummies for task[1-4], which are the defaults
+       referred to by the task array, so that the uITRON system can be
+       initialized even when no uITRON tasks have been provided (so long
+       as no other changes to the task init configury have been made)
+       This does not pollute the namespace, for these are weak symbols.
+       Changing them to cyg_uitron_task... would be possible, but it
+       carries the false implication that those are cygnus names, when
+       they are really entirely up to the user.
+
+       * tests/test[123456789].c: 
+       * tests/testcxx.cxx: 
+       * tests/testcx[23456789].cxx: 
+       Undo the previous change: remove dummies for task[1-4] when we
+       decide not to test anything, they will be provided with weak names
+       regardles in src/uit_func.cxx.
+
+1998-10-20  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/test[123456789].c: 
+       * tests/testcxx.cxx: 
+       * tests/testcx[23456789].cxx: 
+       Provide dummies for task[1-4] when we decide not to test anything,
+       to encourage correct linking.
+
+1998-10-16  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testcx*.cxx (cyg_start): 
+       [all the C++ tests]
+       changed cyg_start to externC so that it truly does override the
+       default one; this is needed for handling the "I cannot test in
+       this configuration" failures.  Of course the C ones were C to
+       start with.
+       
+1998-10-16  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/test[123456789].c: 
+       * tests/testcxx.cxx: 
+       * tests/testcx[23456789].cxx: 
+       All tests are now much more self-configuring wrt turning off
+       if there are no uITRON objects of the right type to manipulate.
+       The huge (50-line) #if statement is arranged the way it is so that
+       clauses checking on each feature can be pasted in and out easily.
+       So yes, the "&& 1" at the end has a purpose.
+       
+       Here for the record is a table of feature versus test-used-in:
+       tsk  :: 1 2 3 4 5 6 7 8 9
+       sem  ::   2 3   5 6 7 8
+       flg  ::   2     5 6 7
+       mbx  ::   2     5 6 7
+       mpl  ::   2     5   7   9
+       mpf  ::   2     5   7   9
+       alm  ::       4
+       cyc  ::       4
+
+
+1998-10-16  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/test9.c: 
+       * tests/testcx9.cxx: 
+       New tests, test create and delete of memory pools
+
+1998-10-15  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: 
+       Add configury for create/delete of memory pools.
+       Tidy up naming of initializer macros to use for non-existent
+       (initially) uITRON objects.
+       Improve comments in CDL-- info fields.
+       
+       * include/uit_func.h: 
+       Add prototypes for cre/del_mpf/mpl().
+
+       * include/uit_func.inl: 
+       Implement cre/del_mpf/mpl().
+
+       * src/uit_objs.cxx: 
+       Support CYG_UIT_MEMPOOLFIXED_NOEXS/CYG_UIT_MEMPOOLVAR_NOEXS(...)
+       mempool construction macros for non-existent (initially) mempools.
+       Rename _NONE construction macros to _NOEXS which will make a lot
+       more sense to uITRON folks.
+
+1998-10-14  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: 
+       Add configury for create/delete of tasks.
+       
+       * include/uit_func.h: 
+       Add prototypes for cre/del_tsk(); correct comment in exd_tsk().
+       
+       * include/uit_func.inl: 
+       Implement cre/del_tsk() and complete exd_tsk().
+       Improve NULL/NADR checking on other cre/del calls.
+
+       * src/uit_func.cxx (cyg_uitron_start): 
+       Deal better with start tasks stuff, for task create/delete.
+
+       * src/uit_objs.cxx: 
+       Support CYG_UIT_TASK_NONE(...) task constructor for those tasks
+       which do not initially exist
+
+       * tests/PKGconf.mak:
+       Add new tests test8.c, testcx[678].cxx to the build.
+
+       * tests/test6.c:
+       Tidy comments, untabify.
+       
+       * tests/test7.c:
+       Tidy comments, untabify, test creation with NADR record pointer.
+       No impact from the new cre/del_tsk() functionality on test7, since
+       a task may only be deleted when it is dormant, so deletion is NOT
+       another way out of a waiting state.
+       
+       * tests/test8.c:
+       New test, tests cre_tsk() and del_tsk() and exd_tsk() ie. the
+       creation and deletion of tasks.
+
+       * tests/testcx6.cxx:
+       * tests/testcx7.cxx:
+       * tests/testcx8.cxx:
+       New tests, C++ versions of tests 6, 7, and 8.
+
+1998-10-09  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/test7.c: 
+       Test interactions with deleting objects (as applicable) and
+       killing, signalling and the like.  Also test killing the task
+       after other treatments more generically.
+
+       * tests/test6.c (task1): 
+       Change "N/A:" to "N/A" in the exit message when we didn't actually
+       do any testing due to create/delete being disabled for all object
+       types.
+
+1998-10-08  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       In general, these changes are to support create/delete of uITRON
+       objects; this requires that an object can be destroyed whilst
+       there are threads waiting on it, and that they shall be awoken
+       with a specific return code E_DLT.  The implementation uses an
+       array of pointers in addition to the array of objects: ptrs[N]
+       should either be NULL or &objs[N] in this version.  That
+       restriction is not checked, in order that in future, true dynamic
+       allocation can be used, and ptrs[N] could point anywhere.  The
+       implications of this are mainly in the area of getting the
+       addresses of objects, via the ptr array or from the object array?
+       The config of whether there is a ptr array is per object type.
+
+       * include/pkgconf/uitron.h: 
+       Configury of the existence or not of create/delete for object
+       type: initially only SEMAS, MBOXES, FLAGS.
+       Configury of the number of objects created initially, if cre/del
+       are enabled.
+
+       * tests/test6.c:
+       * tests/test7.c:
+       * tests/PKGconf.mak:
+       Two new test programs (duh!): test6 tests create and delete of
+       SEMAS, MBOXES, FLAGS explicitly, for bad params handling, ability
+       to use after deletion and recreation &c &c.  test7 tests the
+       semantics of sleeping on some synchronization primitive, permed
+       with suspension, signalling, killing, releasing and so forth.
+       Both will migrate into C++ versions also in future.
+
+       * include/uit_func.h:
+       Enable cre/del_{mbx,flg,sem} prototypes.
+
+       * include/uit_func.inl:
+       Implement cre/del_{mbx,flg,sem} depending on configury, and handle
+       the pointer arrays generally in other client routines.
+
+       * include/uit_objs.hxx:
+       Define the pointer arrays for access to created objects.
+
+       * include/uit_type.h:
+       Enable definitions of the structures used in create calls.
+       
+       * src/uit_func.cxx:
+       Initialization code for the pointer arrays, akin to the task
+       startup code.
+
+       * src/uit_objs.cxx:
+       Instantiate the pointer arrays themselves.
+
+
+1998-09-25  Bart Veer  <bartv@cygnus.co.uk>
+
+       * include/pkgconf/uitron.h:
+       PR 17482: added #ifdef protection. If CYGPKG_UITRON_MEMPOOLFIXED
+       is not defined then the contained option
+       CYGNUM_UITRON_MEMPOOLFIXED may not be defined either. Ditto for
+       CYGNUM_UITRON_MEMPOOLVAR which suffers from the same problem.
+       And ditto for CYGPKG_UITRON_SEMAS
+
+1998-09-20  Mark Galassi  <rosalia@cygnus.com>
+
+       * include/pkgconf/uitron.h: added one or two CDL doc strings.
+
+Tue Sep 15 19:12:28 1998  David Moore  <dsm@keema.cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: Cleaned up comments.
+
+1998-09-12  Mark Galassi  <rosalia@cygnus.com>
+small changes to the descriptive information in the uITRON CDL
+
+1998-09-12  Mark Galassi  <rosalia@cygnus.com>
+
+       * include/pkgconf/uitron.h: small editing of the description
+       fields: renamed things like <name> to NAME, so that it does not
+       confuse SGML when incorporated into the documentation.
+       Also added various "doc" fields to the CFG_DATA comments.
+
+Wed Sep  9 18:36:15 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.inl: 
+       * include/uit_objs.hxx: 
+       * src/uit_objs.cxx: 
+       Condition features on CYGPKG_UITRON_SEMAS [for example] as well as
+       0 < CYG_UITRON_NUM( SEMAS ) so that we get warning free
+       compilation with no semas enabled.  Ditto for flags, mboxes,
+       mempools fixed and variable, alarms and cyclics.
+       
+       * include/pkgconf/uitron.h: 
+       Add a couple of requires statements from cyclics and alarms on the
+       kernel clock.
+       Also change some grammar after review.
+       Add an option (actually a pair, makes it better documentation IMO)
+       to require strict semantics from the kernel setup.
+       Add an option to control the optional sema initializer; it was
+       omitted since the editor way of configury used a #if 0.
+       
+Fri Sep  4 17:54:29 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: 
+       Remove redundant and now unnecessary defs of CYGPKG_UITRON.
+
+Wed Sep  2 19:06:17 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.inl: 
+       Memory pools and message boxes and flags
+       and cnt_sem2-type semaphores now all have absolute timeouts
+       instead of relative ones in the timely wait functions.
+       We add in the current time here first.
+
+Wed Sep  2 16:45:40 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/pkgconf/uitron.h (CYGDAT_UITRON_TASK_INITIALIZERS): 
+       Use the new kernel thread initializer with priority and thread
+       name in it.
+
+       * include/uit_func.inl: 
+       * include/uit_objs.hxx: 
+       * src/uit_func.cxx (cyg_uitron_start): 
+       * src/uit_objs.cxx: 
+       Our tasks are now Cyg_Threads rather than a derived class.
+       Original priorities of tasks are held in an array.  An accessor
+       macro is used for the off-by-one nature of uitron IDs.  The array
+       of original priorities is set up in cyg_uitron_start(), and
+       created in uit_objs.cxx.
+       
+Wed Sep  2 15:15:26 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: 
+       Comment more strongly in the 'description' that the number of
+       initializers better match the number of things specified.
+
+Tue Sep  1 19:00:02 1998  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/uit_objs.hxx: 
+       Do not include <cyg/kernel/kernel.h>; it is deprecated.
+       Instead, include only kernel headers that are needed.
+
+       * include/uit_func.inl (ref_sys): 
+       Use new kernel function Cyg_Interrupt::interrupts_enabled()
+       instead of a state variable.  Tidy up associated code.
+       Include kernel headers that are needed because they were not
+       included in uit_objs.hxx for tidiness.
+
+       * src/uit_func.cxx: 
+       Elide state variable that used to be used for tracking interrupt
+       enabledness state.
+
+       * tests/testcx5.cxx (task1): 
+       * tests/test5.c (task1): 
+       Test interrupt enable and disable stuff, and status reporting.
+
+Tue Sep  1 15:12:29 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.inl (ref_mpf): 
+       Change comment "ECC" to "eCos".
+
+1998-08-28  Bart Veer  <bartv@cygnus.co.uk>
+
+       * include/uit_func.inl:
+       * tests/test1.c, tests/test2.c, tests/test3.c, tests/test4.c,
+       tests/test5.c, tests/testcxx.cxx, tests/testcx2.cxx,
+       tests/testcx3.cxx, tests/testcx4.cxx, tests/testcx5.cxx:
+
+       Updated for new kernel configuration option symbol names
+
+
+Fri Aug 28 09:21:55 1998  Jonathan Larmour  <jlarmour@cygnus.co.uk>
+
+       * src/uit_func.cxx (cyg_uitron_start): 
+       Remove call to Cyg_Scheduler::start() and adjust comments to
+       explain where to call it from
+
+       * tests/test1.c, tests/test2.c, tests/test3.c, tests/test4.c, 
+         tests/test5.c, tests/testcxx.cxx, tests/testcx2.cxx, 
+         tests/testcx3.cxx, tests/testcx4.cxx, tests/testcx5.cxx:
+       Change the normal entry point at the top to be cyg_package_start()
+       under the new startup scheme. This overrides the default package
+       configuration and ensure cyg_uitron_start() gets called.
+       Change the "default" entry point at the bottom (when the test is
+       N/A for some reason) to cyg_start() under the new startup scheme.
+       
+Wed Aug 26 18:20:47 1998  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: 
+       Initial version of cdl control statements for config options.
+       All very groovy, and looking good IMO.
+       A few FIX-MEs remain, no big deal.
+
+Mon Aug 24 19:05:52 1998  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: 
+       Change the names of config options to helpful, positive sense, and
+       tidy some of the names for inclusion in the GUI tool.  Clean up
+       the namespace too.
+       
+       * include/uit_func.h: 
+       * include/uit_func.inl: 
+       * src/uit_func.cxx: 
+       * src/uit_objs.cxx: 
+       Configure according to new option names and object construction
+       macros.  Simple changes but widespread.
+
+       * tests/test[12345].c: 
+       * tests/testcx[x2345].cxx: 
+       Configure according to new option names.
+       Make it main( void ) to avoid a warning.
+
+Fri Aug 21 18:45:16 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * tests/testcx4.cxx (task1): 
+       * tests/test4.c (task1): 
+       * include/uit_func.inl (def_alm): 
+       Tidy the alarm and timer funcs in the course of fixing a kernel
+       bug actually.  Test the functionality affected by the kernel
+       change a bit more.
+       
+Thu Aug 20 14:33:36 1998  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/uit_func.inl (ref_alm): 
+       Elide an unused variable following the previous change.
+
+Mon Aug 17 15:45:07 1998  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       * include/pkgconf/uitron.h: 
+       Add the config option CYGSEM_UITRON_PARAMS_CHECK_NADR_ONLY.
+       
+       * tests/testcxx.cxx: 
+       * tests/testcx2.cxx: 
+       * tests/testcx4.cxx: 
+       Avoid testing with NULL as a bad parameter when only NADR is
+       checked.  (NADR does not cast to any-pointer in C++ so we don't
+       test it in these programs)  Check for NADR various places as well
+       as NULL.
+       
+       * tests/test1.c (task1): 
+       * tests/test2.c (task1): 
+       * tests/test4.c (task1): 
+       Avoid testing with NULL as a bad parameter when only NADR is
+       checked.  Check for NADR various places as well as NULL, and test
+       NADR as a bad param as well as NULL.
+
+
+Mon Aug 17 14:45:30 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.inl:
+       PR# 16536: Check for dormant tasks various places; E_OBJ
+       must be returned.  All this error checking rather bloats the code,
+       unfortunately.
+       
+       * tests/testcxx.cxx: 
+       * tests/test1.c: 
+       Test the new checks above.
+
+Fri Aug 14 17:41:35 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * include/uit_func.inl ([t]wai/pol_flg): 
+       Check for zero in a wait-for-flag operation; such a wait can never
+       be awakened, and so should return E_PAR.
+
+       * tests/testcx2.cxx (task1): 
+       * tests/test2.c (task1): 
+       Test the above new checking.
+
+Fri Jul 24 17:12:54 1998  Hugo Tyson  <hmt@masala.cygnus.co.uk>
+
+       PR#15865
+       * include/uit_func.inl: return a bool (strictly 1 or 0) for wtsk
+       rather than -1 or zero as the spec implies.
+       ref_flg() ref_sem() only affected.
+
+Fri Jul 24 13:26:51 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       PR#16531
+       * include/uit_func.inl: return E_OBJ when (force)resuming a
+       non-suspended task.
+       * tests/test1.c: test for that error code.
+       * tests/testcxx.cxx: test for that error code.
+
+Fri Jul 24 13:02:46 1998  Hugo Tyson  <hmt@cygnus.co.uk>
+
+       * Changelog: Initial ChangeLog entry.
+
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/compat/uitron/v2_0/cdl/flags.cdl b/packages/compat/uitron/v2_0/cdl/flags.cdl
new file mode 100644 (file)
index 0000000..d7d6b40
--- /dev/null
@@ -0,0 +1,82 @@
+# ====================================================================
+#
+#      flags.cdl
+#
+#      uITRON flags related configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  hmt
+# Contributors:
+# Date:           1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGNUM_UITRON_FLAGS {
+    display       "Number of eventflags"
+    flavor        data
+    legal_values  1 to 65535
+    default_value 5
+    description   "
+        The number of uITRON eventflag objects present in the system.
+        Valid eventflag object IDs will range from 1 to this value."
+}
+cdl_component CYGPKG_UITRON_FLAGS_CREATE_DELETE {
+    display       "Support create and delete"
+    flavor        bool
+    default_value 1
+    description   "
+        Support eventflag create and delete operations (cre_flg, del_flg).
+        Otherwise all eventflags are created, up to the number specified above."
+
+    cdl_option CYGNUM_UITRON_FLAGS_INITIALLY {
+        display       "Number of eventflags created initially"
+        flavor        data
+        legal_values  0 to 65535
+        default_value 5
+        description   "
+            The number of uITRON eventflags initially created.
+            This number should not be more than the number
+            of eventflags in the system, though setting it to a large
+            value to mean 'all' is acceptable.
+            Initially, only eventflags numbered 1 to this number exist;
+            higher numbered ones must be created before use."
+    }
+}
diff --git a/packages/compat/uitron/v2_0/cdl/mboxes.cdl b/packages/compat/uitron/v2_0/cdl/mboxes.cdl
new file mode 100644 (file)
index 0000000..74d3f59
--- /dev/null
@@ -0,0 +1,82 @@
+# ====================================================================
+#
+#      mboxes.cdl
+#
+#      uITRON mbox related configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  hmt
+# Contributors:
+# Date:           1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGNUM_UITRON_MBOXES {
+    display       "Number of mailboxes"
+    flavor        data
+    legal_values  1 to 65535
+    default_value 4
+    description   "
+       The number of uITRON mailboxes present in the system.
+       Valid mailbox object IDs will range from 1 to this value."
+}
+cdl_component CYGPKG_UITRON_MBOXES_CREATE_DELETE {
+    display       "Support create and delete"
+    flavor        bool
+    default_value 1
+    description   "
+       Support mailbox create and delete operations (cre_mbx, del_mbx).
+       Otherwise all mailboxes are created, up to the number specified above."
+
+    cdl_option CYGNUM_UITRON_MBOXES_INITIALLY {
+       display       "Number of mailboxes created initially"
+       flavor        data
+       legal_values  0 to 65535
+       default_value 4
+       description   "
+           The number of uITRON mailboxes initially created.
+           This number should not be more than the number
+           of mailboxes in the system, though setting it to a large
+           value to mean 'all' is acceptable.
+           Initially, only mailboxes numbered 1 to this number exist;
+           higher numbered ones must be created before use."
+    }
+}
diff --git a/packages/compat/uitron/v2_0/cdl/mempoolfixed.cdl b/packages/compat/uitron/v2_0/cdl/mempoolfixed.cdl
new file mode 100644 (file)
index 0000000..30d6ec2
--- /dev/null
@@ -0,0 +1,138 @@
+# ====================================================================
+#
+#      mempoolfixed.cdl
+#
+#      uITRON fixed memory pool related configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  hmt
+# Contributors:
+# Date:           1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGNUM_UITRON_MEMPOOLFIXED {
+    display       "Number of fixed-size memorypools"
+    flavor        data
+    legal_values  1 to 65535
+    default_value 3
+    description   "
+        The number of uITRON Fixed-Size
+        Memorypools present in the system.
+        Valid Fixed-Size Memorypool IDs will range
+        from 1 to this value."
+}
+cdl_component CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE {
+    display       "Support create and delete"
+    flavor        bool
+    default_value 1
+    active_if     (0 < CYGNUM_UITRON_MEMPOOLFIXED)
+    description   "
+        Support fixed-size memory pool
+        create and delete operations
+        (cre_mpf, del_mpf).
+        Otherwise all fixed mempools are created,
+        up to the number specified above."
+
+    cdl_option CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY {
+        display       "Number of fixed mempools created initially"
+        flavor        data
+        legal_values  0 to 65535
+        default_value 3
+        description   "
+            The number of fixed mempools initially created.
+            This number should not be more than the number
+            of fixed mempools in the system, though setting
+            it to a large value to mean 'all' is acceptable.
+            Initially, only fixed mempools numbered from
+            1 to this number exist;
+            higher numbered ones must be created before use.
+            Whilst all mempools must be initialized to tell
+            the system what memory to use for each pool,
+            it is only useful to initialize the blocksize of
+            fixed mempools up to this number;
+            the blocksize for higher numbered ones
+            will be defined when they are created."
+    }
+}
+cdl_option CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS {
+    display       "Externs for initialization"
+    flavor        data
+    default_value {"static char fpool1[ 2000 ], \\\n\
+                                fpool2[ 2000 ], \\\n\
+                                fpool3[ 2000 ];"}
+    description   "
+        Fixed mempool initializers may refer to external
+        objects such as memory for the pool to manage.
+        Use this option to define or declare any external
+        objects needed by the pool's static initializer below.
+        Example: create some memory for a mempool using
+        'static char fpool1\[2000\];'
+        to set up a chunk of memory of 2000 bytes.
+        Note: this option is invoked in the 'outermost' context
+        of C++ source, where global/static objects are created;
+        it should contain valid, self-contained, C++ source."
+}
+cdl_option CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS {
+    display       "Static initializers"
+    flavor        data
+    default_value {"CYG_UIT_MEMPOOLFIXED( fpool1, 2000,  20 ), \\\n\
+                    CYG_UIT_MEMPOOLFIXED( fpool2, 2000, 100 ), \\\n\
+                    CYG_UIT_MEMPOOLFIXED( fpool3, 2000, 500 ),"}
+    description   "
+        Fixed block memory pools should be statically
+        initialized: enter a list of initializers
+        separated by commas, one per line.
+        An initializer is
+        'CYG_UIT_MEMPOOLFIXED(ADDR,SIZE,BLOCK)'
+        where addr is the address of memory to manage,
+        size is the total size of that memory, and
+        block is the block size for allocation by the pool.
+        If create and delete operations are supported,
+        initializers of the form
+        'CYG_UIT_MEMPOOLFIXED_NOEXS(ADDR,SIZE)' should be
+        used for pools which are not initially created, to tell
+        the system what memory to use for each pool.
+        Note: this option is invoked in the context of a
+        C++ array initializer, between curly brackets.
+        Ensure that the number of initializers here exactly
+        matches the total number of fixed pools specified."
+}
diff --git a/packages/compat/uitron/v2_0/cdl/mempoolvar.cdl b/packages/compat/uitron/v2_0/cdl/mempoolvar.cdl
new file mode 100644 (file)
index 0000000..5945613
--- /dev/null
@@ -0,0 +1,129 @@
+# ====================================================================
+#
+#      mempoolvar.cdl
+#
+#      uITRON variable memory pool related configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  hmt
+# Contributors:
+# Date:           1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGNUM_UITRON_MEMPOOLVAR {
+    display       "Number of variable-size memory pools"
+    flavor        data
+    legal_values  1 to 65535
+    default_value 3
+    description   "
+       The number of uITRON Variable-Size Memorypools present in the system.
+       Valid Variable-Size Memorypool IDs will range from 1 to this value."
+}
+cdl_component CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE {
+    display       "Support create and delete"
+    flavor        bool
+    default_value 1
+    active_if     (0 < CYGNUM_UITRON_MEMPOOLVAR)
+    description   "
+       Support variable-size memory pool create and delete operations
+       (cre_mpl, del_mpl). Otherwise all variable-size mempools are created,
+       up to the number specified above."
+
+    cdl_option CYGNUM_UITRON_MEMPOOLVAR_INITIALLY {
+       display       "Number of variable-size mempools created initially"
+       flavor        data
+       legal_values  0 to 65535
+       default_value 3
+       description   "
+           The number of variable-size mempools initially created.
+           This number should not be more than the number
+           of variable mempools in the system, though setting
+           it to a large value to mean 'all' is acceptable.
+           Initially, only variable mempools numbered from
+           1 to this number exist;
+           higher numbered ones must be created before use.
+           All mempools must be initialized to tell
+           the system what memory to use for each pool."
+    }
+}
+cdl_option CYGDAT_UITRON_MEMPOOLVAR_EXTERNS {
+    display       "Externs for initialization"
+    flavor        data
+    default_value {"static char vpool1[ 2000 ], \\\n\
+                               vpool2[ 2000 ], \\\n\
+                               vpool3[ 2000 ];"}
+    description   "
+       Variable mempool initializers may refer to external
+       objects such as memory for the pool to manage.
+       Use this option to define or declare any external
+       objects needed by the pool's static initializer below.
+       Example: create some memory for a mempool using
+       'static char vpool1\[2000\];'
+       to set up a chunk of memory of 2000 bytes.
+       Note: this option is invoked in the 'outermost' context
+       of C++ source, where global/static objects are created;
+       it should contain valid, self-contained, C++ source."
+}
+cdl_option CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS {
+    display       "Static initializers"
+    flavor        data
+    default_value {"CYG_UIT_MEMPOOLVAR( vpool1, 2000 ), \\\n\
+                   CYG_UIT_MEMPOOLVAR( vpool2, 2000 ), \\\n\
+                   CYG_UIT_MEMPOOLVAR( vpool3, 2000 ),"}
+    description   "
+       Variable block memory pools should be statically
+       initialized: enter a list of initializers
+       separated by commas, one per line.
+       An initializer is
+       'CYG_UIT_MEMPOOLVAR(ADDR,SIZE)'
+       where addr is the address of memory to manage, and
+       size is the total size of that memory.
+       If create and delete operations are supported,
+       initializers of the form
+       'CYG_UIT_MEMPOOLVAR_NOEXS(ADDR,SIZE)' should be
+       used for pools which are not initially created, to tell
+       the system what memory to use for each pool.
+       Note: this option is invoked in the context of a
+       C++ array initializer, between curly brackets.
+       Ensure that the number of initializers here exactly
+       matches the total number of variable pools specified."
+}
diff --git a/packages/compat/uitron/v2_0/cdl/semas.cdl b/packages/compat/uitron/v2_0/cdl/semas.cdl
new file mode 100644 (file)
index 0000000..9e0fb0f
--- /dev/null
@@ -0,0 +1,115 @@
+# ====================================================================
+#
+#      semas.cdl
+#
+#      uITRON semaphore related configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  hmt
+# Contributors:
+# Date:           1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGNUM_UITRON_SEMAS {
+    display       "Number of semaphores"
+    flavor        data
+    legal_values  1 to 65535
+    default_value 3
+    description   "
+        The number of uITRON semaphores present in the system.
+        Valid semaphore object IDs will range from 1 to this value."
+}
+cdl_component CYGPKG_UITRON_SEMAS_CREATE_DELETE {
+    display       "Support create and delete"
+    flavor        bool
+    default_value 1
+    description   "
+        Support semaphore create and delete operations (cre_sem, del_sem).
+        Otherwise all semaphores are created, up to the number specified 
+        above."
+
+    cdl_option CYGNUM_UITRON_SEMAS_INITIALLY {
+        display       "Number of semaphores created initially"
+        flavor        data
+        legal_values  0 to 65535
+        default_value 3
+        description   "
+            The number of uITRON semaphores initially created.
+            This number should not be more than the number
+            of semaphores in the system, though setting it to a large
+            value to mean 'all' is acceptable.
+            Initially, only semaphores numbered 1 to this number exist;
+            higher numbered ones must be created before use.
+            It is only useful to initialize semaphores up to this number;
+            higher numbered ones must be created in order to use them,
+            and so they will be re-initialized."
+    }
+}
+cdl_component CYGPKG_UITRON_SEMAS_ARE_INITIALIZED {
+    display       "Initialize semaphore counts"
+    flavor        bool
+    default_value 0
+    description   "
+        Initialize semaphores to specific count values.
+        Otherwise semaphores are initialized with the count
+        set to zero."
+
+    cdl_option CYGDAT_UITRON_SEMA_INITIALIZERS {
+        display       "Static initializers"
+        parent        CYGPKG_UITRON_SEMAS_ARE_INITIALIZED
+        flavor        data
+        default_value {"CYG_UIT_SEMA(  0 ),\
+                        CYG_UIT_SEMA(  0 ),\
+                        CYG_UIT_SEMA(  0 )"}
+        description   "
+            A list of initializers separated by commas,
+            one per line.
+            An initializer is 'CYG_UIT_SEMA(INITIAL-COUNT)'
+            or 'CYG_UIT_SEMA_NOEXS' for slots above the number
+            initially to be created, when create and delete
+            operations are supported.
+            Note: this option is invoked in the context of a
+            C++ array initializer, between curly brackets.
+            Ensure that the number of initializers here exactly
+            matches the total number of semaphores specified."
+    }
+}
diff --git a/packages/compat/uitron/v2_0/cdl/tasks.cdl b/packages/compat/uitron/v2_0/cdl/tasks.cdl
new file mode 100644 (file)
index 0000000..fd965ca
--- /dev/null
@@ -0,0 +1,164 @@
+# ====================================================================
+#
+#      tasks.cdl
+#
+#      uITRON task related configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  hmt
+# Contributors:
+# Date:           1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGNUM_UITRON_TASKS {
+    display       "Number of tasks"
+    flavor        data
+    legal_values  1 to 65535
+    default_value 4
+    description   "
+        The number of uITRON tasks present in the system.
+        Valid task object IDs will range from 1 to this value."
+}
+cdl_option CYGNUM_UITRON_START_TASKS {
+    display       "Start tasks"
+    flavor        data
+    legal_values  0 to 65535
+    default_value 1
+    description   "
+        The number of uITRON tasks to start automatically.
+        Tasks from 1 to this value will be started
+        at the beginning of application execution.
+        A value of zero here means to start them all.
+        Tasks started in this way have a start code of
+        zero, as if they were started by sta_tsk(i,0).
+        If create and delete operations are supported,
+        this number should be no greater than the number
+        of tasks created initially."
+}
+cdl_component CYGPKG_UITRON_TASKS_CREATE_DELETE {
+    display       "Support create and delete"
+    flavor        bool
+    default_value 1
+    description   "
+        Support task create and delete operations (cre_tsk, del_tsk).
+        Otherwise all tasks are created, up to the number specified above."
+
+    cdl_option CYGNUM_UITRON_TASKS_INITIALLY {
+        display       "Number of tasks created initially"
+        flavor        data
+        legal_values  1 to 65535
+        default_value 4
+        description   "
+            The number of uITRON tasks initially created.
+            This number should not be more than the number
+            of tasks in the system, though setting it to a large
+            value to mean 'all' is acceptable.
+            Initially, only tasks numbered 1 to this number exist;
+            higher numbered ones must be created before use."
+    }
+}
+cdl_option CYGNUM_UITRON_STACK_SIZE {
+    display       "Default stack size"
+    flavor        data
+    legal_values  128 to 0x7FFFFFFF
+    default_value 2048
+    description   "
+        Define a default stack size for uITRON tasks,
+        for use in the initialization options below.
+        This will be overridden where it is used if the
+        architectural HAL requires a minimum stack size
+        to handle interrupts correctly."
+}
+cdl_option CYGDAT_UITRON_TASK_EXTERNS {
+    display       "Externs for initialization"
+    flavor        data
+    default_value {"extern \"C\" void task1( unsigned int ); \\\n\
+                    extern \"C\" void task2( unsigned int ); \\\n\
+                    extern \"C\" void task3( unsigned int ); \\\n\
+                    extern \"C\" void task4( unsigned int ); \\\n\
+                    static char stack1[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ], \\\n\
+                    stack2[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ], \\\n\
+                    stack3[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ], \\\n\
+                    stack4[ MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ];"}
+    description   "
+        Task initializers may refer to external objects
+        such as memory for stack or functions to call.
+        Use this option to define or declare any external
+        objects needed by the task static initializer below.
+        Example: create some memory for a stack using
+        'static char stack1\[CYGNUM_UITRON_STACK_SIZE\];'
+        to set up a chunk of memory of the default stack size.
+        Note: this option is invoked in the 'outermost' context
+        of C++ source, where global/static objects are created;
+        it should contain valid, self-contained, C++ source."
+}
+cdl_option CYGDAT_UITRON_TASK_INITIALIZERS {
+    display       "Static initializers"
+    flavor        data
+    default_value {"CYG_UIT_TASK( \"t1\", 1, task1, &stack1, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ), \\\n\
+                    CYG_UIT_TASK( \"t2\", 2, task2, &stack2, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ), \\\n\
+                    CYG_UIT_TASK( \"t3\", 3, task3, &stack3, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ), \\\n\
+                    CYG_UIT_TASK( \"t4\", 4, task4, &stack4, MAX(CYGNUM_UITRON_STACK_SIZE, CYGNUM_HAL_STACK_SIZE_MINIMUM) ),"}
+    description   "
+        Tasks must be statically
+        initialized: enter a list of initializers
+        separated by commas, one per line.
+        An initializer is
+        'CYG_UIT_TASK(NAME,PRIO,FUNC,STACK,SIZE)'
+        where name is a quoted string to name the task,
+        prio is the initial priority of the task,
+        func is the name of the entry point,
+        stack is the address of the task's stack,
+        and size is the size of the task's stack.
+        When create and delete operations are supported,
+        'CYG_UIT_TASK_NOEXS(NAME,STACK,SIZE)' should be
+        used for tasks which are not initially created,
+        in order to tell the system what memory to use
+        for stacks when these tasks are created later on.
+        Using 'CYGNUM_UITRON_STACK_SIZE' for size
+        is recommended, to use the option defined above,
+        so long as that truly is the size of your stack(s).
+        Note: this option is invoked in the context of a
+        C++ array initializer, between curly brackets.
+        Ensure that the number of initializers here exactly
+        matches the number of tasks specified."
+}
diff --git a/packages/compat/uitron/v2_0/cdl/uitron.cdl b/packages/compat/uitron/v2_0/cdl/uitron.cdl
new file mode 100644 (file)
index 0000000..e142800
--- /dev/null
@@ -0,0 +1,437 @@
+# ====================================================================
+#
+#      uitron.cdl
+#
+#      uITRON configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      bartv
+# Original data:  hmt
+# Contributors:
+# Date:           1999-06-13
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_UITRON {
+    display       "uITRON compatibility layer"
+    include_dir   cyg/compat/uitron
+    doc           ref/compat-uitron.html
+    requires      CYGPKG_KERNEL
+    description   "
+        eCos supports a uITRON Compatibility Layer, providing
+        full Level S (Standard) compliance with Version 3.02 of
+        the uITRON Standard, plus many Level E (Extended) features.
+        uITRON is the premier Japanese embedded RTOS standard."
+
+    compile       uit_func.cxx uit_ifnc.cxx uit_objs.cxx
+
+    # ------------------------------------------------------------------------
+    #                       Conformance check
+    # ------------------------------------------------------------------------
+    cdl_interface CYGINT_UITRON_CONFORMANCE {
+        requires 1 == CYGINT_UITRON_CONFORMANCE
+    }
+
+    cdl_option CYGIMP_UITRON_STRICT_CONFORMANCE {
+        display       "Check strict uITRON standards conformance"
+        default_value 0
+        requires      CYGVAR_KERNEL_COUNTERS_CLOCK
+        requires      CYGSEM_KERNEL_SCHED_MLQUEUE
+        requires      !CYGSEM_KERNEL_SCHED_TIMESLICE
+        requires      CYGFUN_KERNEL_THREADS_TIMER
+       implements    CYGINT_UITRON_CONFORMANCE
+        description   "
+            Require the rest of the system configuration
+            to match the needs of strict uITRON standards conformance.
+            This option can only be set if the rest of the system is
+            configured correctly for uITRON semantics, for example
+            there must be a realtime clock, a suitable scheduler, and no
+            timeslicing.
+            Of course a system without this selected can be completely
+            conformant; this is here to help you check."
+    }
+    cdl_option CYGIMP_UITRON_LOOSE_CONFORMANCE {
+        display       "System configuration overrides uITRON"
+        default_value 1
+        implements    CYGINT_UITRON_CONFORMANCE
+        description   "
+            Do not require the rest of the system configuration
+            to match the needs of strict uITRON standards conformance.
+            For example a bitmap scheduler, or timeslicing, can be used
+            with the uITRON functions, but such an environment is not
+            strictly conformant with the uITRON specification.
+            Of course a system with this selected can be completely
+            conformant; but it is up to you to configure it correctly."
+    }
+
+    # ------------------------------------------------------------------------
+    #                       uITRON FUNCTION CALLS
+    # ------------------------------------------------------------------------
+    cdl_option CYGIMP_UITRON_INLINE_FUNCS {
+        display       "Inline functions"
+        default_value 0
+        description   "
+            If compiling your application with a C++ compiler,
+            uITRON functions can be inline: set this to make it so.
+            Inlining functions often increases execution speed,
+            though possibly at the cost of a larger executable,
+            depending on what functions are used.
+            Do NOT set this if compiling your application
+            in plain C."
+    }
+
+    cdl_option CYGIMP_UITRON_CPP_OUTLINE_FUNCS {
+        display       "C++ function names"
+        default_value 0
+        description   "
+            If compiling your application with a C++ compiler,
+            uITRON functions can be given C++ style mangled names:
+            set this to make it so.
+            This option may make debugging your program easier,
+            depending on your development environment.
+            Do NOT set this if compiling your application
+            in plain C."
+    }
+
+    cdl_option CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS {
+        display       "Return error codes for bad params"
+        default_value 1
+        description   "
+            When an application is fully debugged there is no need
+            to check for bad parameters on every system call, for those
+            parameters which are typically pointers or constants.
+            Removing the checking code saves space
+            and improves performance: set this to make it so.
+            When this option is set, the correctness of parameters
+            is asserted using CYG_ASSERT() which compiles to
+            nothing in a non-debug configuration."
+    }
+
+    cdl_option CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR {
+        display       "NULL is a good pointer"
+        default_value 0
+        description   "
+            uITRON deliberately defines the constant NADR (-1) for
+            use as an invalid memory address.
+            The value -1 is chosen to allow working in microcontrollers
+            which have real memory at address zero, the traditional 'C'
+            NULL pointer.
+            By default, uITRON functions check for both NULL and NADR as
+            bad addresses: set this option to prevent checking for
+            NULL and allow pointers to address zero to be used."
+    }
+
+    # ------------------------------------------------------------------------
+    #                      uITRON KERNEL OBJECTS
+    # ------------------------------------------------------------------------
+    cdl_component CYGPKG_UITRON_SEMAS {
+        display       "Semaphores"
+        flavor        bool
+        default_value 1
+        description   "
+            uITRON Semaphore objects are used with functions
+            named xxx_sem(); they support traditional semaphore
+            semantics."
+
+        script        semas.cdl
+    }
+
+    cdl_component CYGPKG_UITRON_MBOXES {
+        display       "Mailboxes"
+        flavor        bool
+        default_value 1
+        description   "
+            uITRON Mailbox objects are used with functions
+            named xxx_msg() and xxx_mbx(); they support
+            passing addresses (of 'messages') between tasks
+            in a safe manner."
+
+        script        mboxes.cdl
+    }
+
+    cdl_component CYGPKG_UITRON_FLAGS {
+        display       "Eventflags"
+        flavor        bool
+        default_value 1
+        description   "
+            uITRON Eventflag objects are used with functions
+            named xxx_flg(); they support communication between
+            tasks by means of setting and clearing bits in a word
+            or flag value.
+            Waiting for all or any of a set of bits is supported."
+
+        script        flags.cdl
+    }
+
+    # ------------------------------------------------------------------------
+    #                            uITRON TASKS
+    # ------------------------------------------------------------------------
+    cdl_component CYGPKG_UITRON_TASKS {
+        display      "Tasks"
+        flavor        none
+        description   "
+            uITRON Tasks are the basic blocks of multi-tasking
+            in the uITRON world; they are threads or lightweight
+            processes, sharing the address space and the CPU.
+            They communicate using the primitives outlined above.
+            Each has a stack, an entry point (a C or C++ function),
+            and (where appropriate) a scheduling priority."
+
+        script        tasks.cdl
+    }
+
+    # ------------------------------------------------------------------------
+    # Memory Pools, both fixed and variable block
+    # ------------------------------------------------------------------------
+    cdl_component CYGPKG_UITRON_MEMPOOLFIXED {
+        display       "Fixed-size memorypools"
+        flavor        bool
+        default_value 1
+        requires      CYGPKG_MEMALLOC
+        description   "
+            uITRON supports memory pools for dynamic, task-safe
+            memory allocation.
+            Two kinds are supported, fixed-size and variable-size.
+            There may be multiple of each
+            type of pool, each with differing characteristics.
+            This option controls whether there are any fixed-size
+            memorypools in the system.
+            A fixed-size memorypool allocates blocks of memory of
+            its preset fixed size and none other."
+
+        script        mempoolfixed.cdl
+    }
+
+    cdl_component CYGPKG_UITRON_MEMPOOLVAR {
+        display       "Variable-size memorypools"
+        flavor        bool
+        default_value 1
+        requires      CYGPKG_MEMALLOC
+        description   "
+            uITRON supports memory pools for dynamic, task-safe
+            memory allocation.
+            Two kinds are supported, fixed-size and variable-size.
+            There may be multiple of each
+            type of pool, each with differing characteristics.
+            This option controls whether there are any variable-size
+            memorypools in the system.
+            A variable-size memorypool allocates blocks of memory of
+            any size requested, resources permitting."
+
+        script        mempoolvar.cdl
+    }
+
+    # ------------------------------------------------------------------------
+    # One-shot Alarm and Cyclic Alarm handlers:
+    # ------------------------------------------------------------------------
+
+    cdl_option CYGSEM_UITRON_TIME_IS_MILLISECONDS {
+       display       "uITRON time unit is mS"
+        flavor        bool
+        default_value 0
+       active_if     CYGVAR_KERNEL_COUNTERS_CLOCK
+        description   "
+           Setting this option enables a conversion feature so that
+           time parameters to uITRON APIs are converted from milliSeconds
+           to whatever the eCos kernel real-time clock's units are,
+            or vice versa.
+           If this option is not set, time parameters are expressed in
+           kernel clock ticks."
+    }
+
+    cdl_component CYGPKG_UITRON_ALARMS {
+        display       "Alarm handlers"
+        flavor        bool
+        default_value 1
+        requires      CYGVAR_KERNEL_COUNTERS_CLOCK
+        description   "
+            uITRON Alarm Handlers are used with functions
+            named def_alm() and ref_alm(); they support
+            simple timing, with a function callback
+            at the end of the timed period."
+
+
+        cdl_option CYGNUM_UITRON_ALARMS {
+            display       "Number of alarm handlers"
+            flavor        data
+            legal_values  1 to 65535
+            default_value 3
+            description   "
+                The number of uITRON alarm
+                handlers present in the system.
+                Valid alarm handler numbers will range
+                from 1 to this value."
+        }
+    }
+
+    cdl_component CYGPKG_UITRON_CYCLICS {
+        display       "Cyclic handlers"
+        flavor        bool
+        default_value 1
+        requires      CYGVAR_KERNEL_COUNTERS_CLOCK
+        description   "
+            uITRON Cyclic Handlers are used with functions
+            named xxx_cyc(); they support timing
+            with a periodic function callback that
+            can be dynamically turned on or off, and
+            resynchronized with external events."
+
+        cdl_option CYGNUM_UITRON_CYCLICS {
+            display       "Number cyclic handlers"
+            flavor        data
+            legal_values  1 to 65535
+            default_value 3
+            description   "
+                The number of uITRON cyclics
+                handlers present in the system.
+                Valid cyclic handler numbers will range
+                from 1 to this value."
+        }
+    }
+
+    # ------------------------------------------------------------------------
+    # Interrupt-safe functions [ixxx_yyy()]:
+    # ------------------------------------------------------------------------
+    cdl_component CYGPKG_UITRON_INTERRUPT_FUNCTIONS {
+        display                "Interrupt-safe functions"
+       flavor          none
+       description "The uITRON system provides some functions which may
+                safely be used within interrupt handlers.  In eCos, this
+                means within ISRs, providing that the corresponding DSR is
+                associated with that interrupt.  These functions are
+                typically named ixxx_yyy(), according to the uITRON
+                specification, for example isig_sem() corresponds to normal
+                function sig_sem()."
+
+        cdl_option CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION {
+           display          "Execute in ISR if safe"
+           parent           CYGPKG_UITRON_INTERRUPT_FUNCTIONS
+           flavor           bool
+            default_value    1
+           description      "
+                    These functions of necessity maintain a queue of
+                    operations requested for deferred execution.  However,
+                    during an interrupt, it may be safe to perform scheduling
+                    operations.  If this option is set, the interrupt-safe
+                    functions will have effect there and then if it is indeed
+                    safe, rather than queueing a request to perform the
+                    operation in the DSR."
+       }
+       cdl_option CYGNUM_UITRON_ISR_ACTION_QUEUESIZE {
+           display          "Deferred operation queue size"
+           parent           CYGPKG_UITRON_INTERRUPT_FUNCTIONS
+           flavor           data
+           legal_values     4 8 16 32 64 128 256
+            default_value    32
+           description "These functions of necessity maintain a queue of
+                    operations requested for deferred execution.  This option
+                    controls the queue size.  It must be a power of two for
+                    implementation reasons."
+       }
+    }
+
+    # ------------------------------------------------------------------------
+    #                      uITRON VERSION INFORMATION
+    # ------------------------------------------------------------------------
+    cdl_component CYGPKG_UITRON_VERSION {
+        display       "Version information"
+        flavor        none
+        description   "
+            The get_ver() uITRON system call returns
+            several version related values describing
+            the vendor, product and CPU in question
+            as well as the version of the uITRON
+            standard supported.
+            These values may be specified here."
+
+        script        version.cdl
+    }
+
+    define_proc {
+        puts $::cdl_header "/***** proc output start *****/"
+        puts $::cdl_header "#include <pkgconf/system.h>"
+        puts $::cdl_header "#include <pkgconf/kernel.h>"
+        puts $::cdl_header "/*****  proc output end  *****/"
+    }
+
+    cdl_component CYGPKG_UITRON_OPTIONS {
+        display "uITRON build options"
+        flavor  none
+        description   "
+           Package specific build options including control over
+           compiler flags used only in building this package,
+           and details of which tests are built."
+
+        cdl_option CYGPKG_UITRON_CFLAGS_ADD {
+            display "Additional compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the uITRON compatibility layer. These flags are used in addition
+                to the set of global flags."
+        }
+
+        cdl_option CYGPKG_UITRON_CFLAGS_REMOVE {
+            display "Suppressed compiler flags"
+            flavor  data
+            no_define
+            default_value { "" }
+            description   "
+                This option modifies the set of compiler flags for
+                building the uITRON compatibility layer. These flags are removed from
+                the set of global flags if present."
+        }
+
+        cdl_option CYGPKG_UITRON_TESTS {
+            display "uITRON tests"
+            flavor  data
+            no_define
+            calculated {
+                "tests/testcxx tests/testcx2 tests/testcx3 tests/testcx4 tests/testcx5 tests/testcx6 tests/testcx7 tests/testcx8 tests/testcx9"
+                . ((!CYGIMP_UITRON_INLINE_FUNCS && !CYGIMP_UITRON_CPP_OUTLINE_FUNCS) ?
+                " tests/test1 tests/test2 tests/test3 tests/test4 tests/test5 tests/test6 tests/test7 tests/test8 tests/test9 tests/testintr" : "")
+            }
+            description   "
+                This option specifies the set of tests for the uITRON compatibility layer."
+        }
+    }
+}
diff --git a/packages/compat/uitron/v2_0/cdl/version.cdl b/packages/compat/uitron/v2_0/cdl/version.cdl
new file mode 100644 (file)
index 0000000..9ddd388
--- /dev/null
@@ -0,0 +1,167 @@
+# ====================================================================
+#
+#      verion.cdl
+#
+#      uITRON version related configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  hmt
+# Contributors:
+# Date:           1999-07-07
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_option CYGNUM_UITRON_VER_MAKER {
+    display       "OS maker"
+    flavor        data
+    legal_values  0 to 0xFFFF
+    default_value 0
+    description   "
+        This value is returned in the 'maker'
+        field of the T_VER structure in
+        response to a get_ver() system call."
+}
+cdl_option CYGNUM_UITRON_VER_ID     {
+    display       "OS identification"
+    flavor        data
+    legal_values  0 to 0xFFFF
+    default_value 0
+    description   "
+        This value is returned in the 'id'
+        field of the T_VER structure in
+        response to a get_ver() system call."
+}
+cdl_option CYGNUM_UITRON_VER_SPVER  {
+    display       "ITRON specification"
+    flavor        data
+    legal_values  0 to 0xFFFF
+    default_value 0x5302
+    description   "
+        This value is returned in the 'spver'
+        field of the T_VER structure in
+        response to a get_ver() system call.
+        Do NOT change this value."
+}
+cdl_option CYGNUM_UITRON_VER_PRVER  {
+    display       "OS product version"
+    flavor        data
+    legal_values  0 to 0xFFFF
+    default_value 0x0100
+    description   "
+        This value is returned in the 'prver'
+        field of the T_VER structure in
+        response to a get_ver() system call."
+}
+# PRNO fields in own folder
+cdl_component CYGPKG_UITRON_VERSION_PRNO {
+    display       "Product info"
+    flavor        none
+    description   "
+        The get_ver() uITRON system call returns
+        several version related values describing
+        the vendor, product and CPU in question
+        as well as the version of the uITRON
+        standard supported.
+        These values may be specified here."
+
+    cdl_option CYGNUM_UITRON_VER_PRNO_0 {
+        display       "Field 0"
+        flavor        data
+        legal_values  0 to 0xFFFF
+        default_value 0
+        description   "
+            This value is returned in the 'prno\[0\]'
+            field of the T_VER structure in
+            response to a get_ver() system call."
+    }
+    cdl_option CYGNUM_UITRON_VER_PRNO_1 {
+        display       "Field 1"
+        flavor        data
+        legal_values  0 to 0xFFFF
+        default_value 0
+        description   "
+            This value is returned in the 'prno\[1\]'
+            field of the T_VER structure in
+            response to a get_ver() system call."
+    }
+    cdl_option CYGNUM_UITRON_VER_PRNO_2 {
+        display       "Field 2"
+        flavor        data
+        legal_values  0 to 0xFFFF
+        default_value 0
+        description   "
+            This value is returned in the 'prno\[2\]'
+            field of the T_VER structure in
+            response to a get_ver() system call."
+    }
+    cdl_option CYGNUM_UITRON_VER_PRNO_3 {
+        display       "Field 3"
+        flavor        data
+        legal_values  0 to 0xFFFF
+        default_value 0
+        description   "
+            This value is returned in the 'prno\[3\]'
+            field of the T_VER structure in
+            response to a get_ver() system call."
+    }
+}
+
+cdl_option CYGNUM_UITRON_VER_CPU    {
+    display       "CPU information"
+    flavor        data
+    legal_values  0 to 0xFFFF
+    default_value 0
+    description   "
+        This value is returned in the 'cpu'
+        field of the T_VER structure in
+        response to a get_ver() system call."
+}
+cdl_option CYGNUM_UITRON_VER_VAR    {
+    display       "System variant"
+    flavor        data
+    legal_values  0 to 0xFFFF
+    default_value 0x8000
+    description   "
+        This value is returned in the 'var'
+        field of the T_VER structure in
+        response to a get_ver() system call.
+        Do NOT change this value."
+}
diff --git a/packages/compat/uitron/v2_0/doc/uitron.sgml b/packages/compat/uitron/v2_0/doc/uitron.sgml
new file mode 100644 (file)
index 0000000..716b8da
--- /dev/null
@@ -0,0 +1,1385 @@
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     uitron.sgml                                                 -->
+<!--                                                                 -->
+<!--     uITRON Compatibility                                        -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.  -->
+<!-- This material may be distributed only subject to the terms      -->
+<!-- and conditions set forth in the Open Publication License, v1.0  -->
+<!-- or later (the latest version is presently available at          -->
+<!-- http://www.opencontent.org/openpub/)                            -->
+<!-- Distribution of the work or derivative of the work in any       -->
+<!-- standard (paper) book form is prohibited unless prior           -->
+<!-- permission obtained from the copyright holder                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->      
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN####                                       -->
+<!--                                                                 -->
+<!-- ####DESCRIPTIONEND####                                          -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<part id="compat-uitron">
+  <title>&micro;ITRON</title>
+<CHAPTER id="compat-uitron-microitron-api">
+<TITLE><!-- <xref> -->&micro;ITRON API</TITLE>
+<SECT1 id="compat-uitron-introduction">
+<TITLE><!-- <index></index> -->Introduction to &micro;ITRON</TITLE>
+<PARA>The <!-- <index></index> -->&micro;ITRON specification
+defines a highly flexible operating system architecture designed
+specifically for application in embedded systems. The specification addresses
+features which are common to the majority of processor architectures and
+deliberately avoids virtualization which would adversely impact
+real-time performance. The &micro;ITRON specification
+may be implemented on many hardware platforms and provides significant
+advantages by reducing the effort involved in understanding and
+porting application software to new processor architectures. </PARA>
+<PARA>Several revisions of the &micro;ITRON specification exist.
+       In this release, <EMPHASIS>eCos</EMPHASIS> supports the
+       &micro;ITRON version 3.02 specification, with complete
+       &ldquo;Standard functionality&rdquo; (level S), plus many
+       &ldquo;Extended&rdquo; (level E) functions. The definitive
+       reference on &micro;ITRON is Dr. Sakamura&rsquo;s book:
+         <CITETITLE>&micro;ITRON 3.0, An Open and Portable Real-Time Operating
+         System for Embedded Systems</CITETITLE>. 
+       The book can be purchased from the IEEE Press, and
+       an ASCII version of the standard can be found online at
+<ulink url="http://www.itron.gr.jp/">http://www.itron.gr.jp/</ulink>.
+The old address 
+<ulink url="http://tron.um.u-tokyo.ac.jp/TRON/ITRON/">
+http://tron.um.u-tokyo.ac.jp/TRON/ITRON/</ulink>
+still exists as a mirror site. </PARA>
+</SECT1>
+<SECT1 id="compat-uitron-over-ecos">
+<TITLE><!-- <index></index> -->&micro;ITRON and <EMPHASIS>eCos</EMPHASIS></TITLE>
+<PARA>The <EMPHASIS>eCos</EMPHASIS> kernel implements the functionality
+used by the &micro;ITRON compatibility subsystem.
+The configuration of the kernel influences the behavior of &micro;ITRON
+programs.</PARA>
+<PARA>In particular, the default configuration has time slicing
+(also known as round-robin scheduling) switched on; this means that
+a task can be moved from <varname>RUN</varname> state
+to <varname>READY</varname> state at any time, in
+order that one of its peers may run. This is not strictly conformant
+to the &micro;ITRON specification, which
+states that timeslicing may be implemented by periodically issuing
+a <literal>rot_rdq(0)</literal> call from
+within a periodic task or cyclic handler; otherwise it is expected
+that a task runs until it is pre-empted in consequence of synchronization
+or communication calls it makes, or the effects of an interrupt
+or other external event on a higher priority task cause that task
+to become <varname>READY</varname>. To disable timeslicing
+functionality in the kernel and &micro;ITRON
+compatibility environment, please disable the 
+<LITERAL>CYGSEM_KERNEL_SCHED_TIMESLICE</LITERAL>
+configuration option in the kernel package. A description of kernel
+scheduling is in <xref linkend="kernel-overview">. </PARA>
+<PARA>For another example, the semantics of task queueing when waiting
+on a synchronization object depend solely on the way the underlying
+kernel is configured. As discussed above, the multi-level queue
+scheduler is the only one which is &micro;ITRON
+compliant, and it queues waiting tasks in FIFO order. Future releases
+of that scheduler might be configurable to support priority ordering
+of task queues. Other schedulers might be different again: for example
+the bitmap scheduler can be used with the &micro;ITRON
+compatibility layer, even though it only allows one task at each
+priority and as such is not &micro;ITRON
+compliant, but it supports only priority ordering of task queues.
+So which queueing scheme is supported is not really a property of
+the &micro;ITRON compatibility layer; it
+depends on the kernel. </PARA>
+<PARA>In this version of the &micro;ITRON
+compatibility layer, the calls to disable and enable scheduling
+and interrupts (<FUNCTION>dis_dsp()</FUNCTION>,
+<FUNCTION>ena_dsp()</FUNCTION>, <FUNCTION>loc_cpu()</FUNCTION>
+and <FUNCTION>unl_cpu()</FUNCTION>)
+call underlying kernel functions; in particular, the <FUNCTION>xxx_dsp()</FUNCTION> functions
+lock the scheduler entirely, which prevents dispatching of DSRs; functions
+implemented by DSRs include clock counters and alarm timers. Thus time &ldquo;stops&rdquo; while
+dispatching is disabled with <FUNCTION>dis_dsp()</FUNCTION>. </PARA>
+<PARA>Like all parts of the <EMPHASIS>eCos</EMPHASIS> system, the
+detailed semantics of the &micro;ITRON layer
+are dependent on its configuration and the configuration of other components
+that it uses. The &micro;ITRON configuration
+options are all defined in the file <filename>pkgconf/uitron.h</filename>,
+and can be set using the configuration tool or editing the
+<filename>.ecc</filename>
+file in your build directory by hand. </PARA>
+<PARA>An important configuration option for the &micro;ITRON
+compatibility layer is &ldquo;Option: Return Error Codes for Bad Params&rdquo;
+(
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+), which allows a lot of the error
+checking code in the &micro;ITRON compatibility layer to
+be removed. Of course this leaves a program open to undetected errors,
+so it should only be used once an application is fully debugged and
+tested. Its benefits include reduced code size and faster execution.
+However, it affects the API significantly, in that with this option
+enabled, bad calls do not return errors, but cause an assert
+failure (if that is itself enabled) or malfunction internally. There
+is discussion in more detail about this in each section below.</PARA>
+<PARA>We now give a brief description of the &micro;ITRON
+functions which are implemented in this release. Note that all C
+and C&plus;&plus; source files should have the following <literal>#include</literal> statement: </PARA>
+<PROGRAMLISTING>#include &lt;cyg/compat/uitron/uit_func.h&gt;</PROGRAMLISTING>
+</SECT1>
+<SECT1 id="compat-uitron-task-management-functions">
+<TITLE><!-- <index></index> -->Task Management Functions</TITLE>
+<PARA>The following functions are fully supported in this release: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>sta_tsk</FUNCTION>( 
+  ID <EMPHASIS>tskid,</EMPHASIS>
+  INT <EMPHASIS>stacd</EMPHASIS> )</programlisting>
+       <programlisting>
+void <FUNCTION>ext_tsk</FUNCTION>( void )</programlisting>
+       <programlisting>
+void <FUNCTION>exd_tsk</FUNCTION>( void )</programlisting>
+       <programlisting>
+ER <FUNCTION>dis_dsp</FUNCTION>( void )</programlisting>
+       <programlisting>
+ER <FUNCTION>ena_dsp</FUNCTION>( void )</programlisting>
+       <programlisting>
+ER <FUNCTION>chg_pri</FUNCTION>( 
+  ID <EMPHASIS>tskid,</EMPHASIS>
+  PRI <EMPHASIS>tskpri</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>rot_rdq</FUNCTION>( 
+  PRI <EMPHASIS>tskpri</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>get_tid</FUNCTION>( 
+  ID *<EMPHASIS>p_tskid</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>ref_tsk</FUNCTION>( 
+  T_RTSK *<EMPHASIS>pk_rtsk,</EMPHASIS>
+  ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>ter_tsk</FUNCTION>( 
+  ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>rel_wai</FUNCTION>( 
+  ID <EMPHASIS>tskid</EMPHASIS> )</PROGRAMLISTING>
+<PARA>The following two functions are supported in this release,
+when enabled with the configuration option 
+<LITERAL>CYGPKG_UITRON_TASKS_CREATE_DELETE</LITERAL>
+with some restrictions:</PARA>
+<PROGRAMLISTING>ER <FUNCTION>cre_tsk</FUNCTION>( 
+  ID <EMPHASIS>tskid,</EMPHASIS>
+  T_CTSK *<EMPHASIS>pk_ctsk</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>del_tsk</FUNCTION>( 
+  ID <EMPHASIS>tskid</EMPHASIS> )</PROGRAMLISTING>
+<PARA>These functions are restricted as follows:</PARA>
+<PARA>Because of the static initialization facilities provided for
+system objects, a task is allocated stack space statically in the
+configuration. So while tasks can be created and deleted, the same
+stack space is used for that task (task ID number) each time. Thus
+the stack size (pk_ctsk-&gt;stksz) requested in <FUNCTION>cre_tsk()</FUNCTION> is
+checked for being less than that which was statically allocated,
+and otherwise ignored. This ensures that the new task will have
+enough stack to run. For this reason <FUNCTION>del_tsk()</FUNCTION> does
+not in any sense free the memory that was in use for the task's
+stack. </PARA>
+<PARA>The task attributes (pk_ctsk-&gt;tskatr) are
+ignored; current versions of <EMPHASIS>eCos</EMPHASIS> do not need
+to know whether a task is written in assembler or C/C&plus;&plus; so
+long as the procedure call standard appropriate to the CPU is followed.</PARA>
+<PARA>Extended information (pk_ctsk-&gt;exinf) is
+         ignored.</PARA>
+<SECT2>
+<TITLE>Error checking</TITLE>
+<PARA>For all these calls, an invalid task id (tskid) (less than
+1 or greater than the number of configured tasks) only returns E_ID
+when bad params return errors (
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+is enabled, see above).</PARA>
+<PARA>Similarly, the following conditions are only checked for,
+and only return errors if 
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+is enabled:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>pk_crtk in 
+<FUNCTION>cre_tsk()</FUNCTION>
+ is a valid pointer, otherwise return E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>ter_tsk()</FUNCTION>
+ or 
+<FUNCTION>rel_wai()</FUNCTION>
+ on the calling task returns E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>the CPU is not locked already in 
+<FUNCTION>dis_dsp()</FUNCTION>
+ and 
+<FUNCTION>ena_dsp()</FUNCTION>
+; returns E_CTX</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>priority level in 
+<FUNCTION>chg_pri()</FUNCTION>
+ and 
+<FUNCTION>rot_rdq()</FUNCTION>
+ is checked for validity, E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>return value pointer in 
+<FUNCTION>get_tid()</FUNCTION>
+ and 
+<FUNCTION>ref_tsk()</FUNCTION>
+ is a valid pointer, or E_PAR</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+<PARA>The following conditions are checked for, and return
+           error codes if appropriate, regardless of the setting of
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>When create and delete functions 
+<FUNCTION>cre_tsk()</FUNCTION>
+ and 
+<FUNCTION>del_tsk()</FUNCTION>
+ are supported, all calls which use a valid task ID number check
+that the task exists; if not, E_NOEXS is returned</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>When supported, 
+<FUNCTION>cre_tsk()</FUNCTION>
+: the task must not already exist; otherwise E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>When supported, 
+<FUNCTION>cre_tsk()</FUNCTION>
+: the requested stack size must not be larger than that statically
+configured for the task; see the configuration options
+&ldquo;Static initializers&rdquo;, and &ldquo;Default stack size&rdquo;.
+Else E_NOMEM</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>When supported, 
+<FUNCTION>del_tsk()</FUNCTION>
+: the underlying 
+<EMPHASIS>eCos</EMPHASIS>
+ thread must not be running - this would imply either a bug or some
+program bypassing the 
+&micro;ITRON compatibility layer and manipulating the thread directly.
+E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>sta_tsk()</FUNCTION>
+: the task must be dormant, else E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>ter_tsk()</FUNCTION>
+: the task must not be dormant, else E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>chg_pri()</FUNCTION>
+: the task must not be dormant, else E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>rel_wai()</FUNCTION>
+: the task must be in 
+<varname>WAIT</varname> or <varname>WAIT-SUSPEND</varname>
+ state, else E_OBJ</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</SECT2>
+</SECT1>
+<SECT1 id="compat-uitron-task-dependent-synch-functions">
+<TITLE><!-- <index></index> -->Task-Dependent Synchronization Functions</TITLE>
+<PARA>These functions are fully supported in this release: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>sus_tsk</FUNCTION>( 
+    ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>rsm_tsk</FUNCTION>( 
+    ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>frsm_tsk</FUNCTION>( 
+    ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
+<programlisting>
+ER <FUNCTION>slp_tsk</FUNCTION>( void )</programlisting>
+       <programlisting>
+ER <FUNCTION>tslp_tsk</FUNCTION>( 
+    TMO <EMPHASIS>tmout</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>wup_tsk</FUNCTION>( 
+    ID <EMPHASIS>tskid</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>can_wup</FUNCTION>( 
+    INT *<EMPHASIS>p_wupcnt,</EMPHASIS>    ID <EMPHASIS>tskid</EMPHASIS> )</PROGRAMLISTING>
+<SECT2>
+<TITLE>Error checking</TITLE>
+<PARA>The following conditions are only checked for, and only return
+errors if 
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+is enabled (see the configuration option &ldquo;Return Error Codes for Bad
+Params&rdquo;):</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>invalid tskid; less than 1 or greater than 
+<LITERAL>CYGNUM_UITRON_TASKS</LITERAL>
+returns E_ID</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>wup_tsk()</FUNCTION>
+, 
+<FUNCTION>sus_tsk()</FUNCTION>
+, 
+<FUNCTION>rsm_tsk()</FUNCTION>
+, 
+<FUNCTION>frsm_tsk()</FUNCTION>
+ on the calling task returns E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>dispatching is enabled in 
+<FUNCTION>tslp_tsk()</FUNCTION>
+ and 
+<FUNCTION>slp_tsk()</FUNCTION>
+, or E_CTX</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>tmout must be positive, otherwise E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>return value pointer in 
+<FUNCTION>can_wup()</FUNCTION>
+ is a valid pointer, or E_PAR</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+<PARA>The following conditions are checked for, and can
+           return error codes, regardless of the setting of
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>:
+</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>When create and delete functions 
+<FUNCTION>cre_tsk()</FUNCTION>
+ and 
+<FUNCTION>del_tsk()</FUNCTION>
+ are supported, all calls which use a valid task ID number check
+that the task exists; if not, E_NOEXS is returned</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>sus_tsk()</FUNCTION>
+: the task must not be dormant, else E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>frsm/rsm_tsk()</FUNCTION>
+: the task must be suspended, else E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>tslp/slp_tsk()</FUNCTION>
+: return codes E_TMOUT, E_RLWAI and E_DLT
+are returned depending on the reason for terminating the sleep</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>wup_tsk()</FUNCTION>
+ and 
+<FUNCTION>can_wup()</FUNCTION>
+: the task must not be dormant, or E_OBJ is returned</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</SECT2>
+</SECT1>
+<SECT1 id="compat-uitron-sync-and-comm-functions">
+<TITLE><!-- <index></index> -->          Synchronization and Communication Functions</TITLE>
+<PARA>These functions are fully supported in this release: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>sig_sem</FUNCTION>( 
+    ID <EMPHASIS>semid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>wai_sem</FUNCTION>( 
+    ID <EMPHASIS>semid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>preq_sem</FUNCTION>( 
+    ID <EMPHASIS>semid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>twai_sem</FUNCTION>( 
+    ID <EMPHASIS>semid,</EMPHASIS>    TMO <EMPHASIS>tmout</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ref_sem</FUNCTION>( 
+    T_RSEM *<EMPHASIS>pk_rsem ,</EMPHASIS>    ID <EMPHASIS>semid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>set_flg</FUNCTION>( 
+    ID <EMPHASIS>flgid,</EMPHASIS>    UINT <EMPHASIS>setptn</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>clr_flg</FUNCTION>( 
+    ID <EMPHASIS>flgid,</EMPHASIS>    UINT <EMPHASIS>clrptn</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>wai_flg</FUNCTION>( 
+    UINT *<EMPHASIS>p_flgptn,</EMPHASIS>    ID <EMPHASIS>flgid ,</EMPHASIS>
+    UINT <EMPHASIS>waiptn ,</EMPHASIS>    UINT <EMPHASIS>wfmode</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>pol_flg</FUNCTION>( 
+    UINT *<EMPHASIS>p_flgptn,</EMPHASIS>    ID <EMPHASIS>flgid ,</EMPHASIS>
+    UINT <EMPHASIS>waiptn ,</EMPHASIS>    UINT <EMPHASIS>wfmode</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>twai_flg</FUNCTION>( 
+    UINT *<EMPHASIS>p_flgptn</EMPHASIS>    ID <EMPHASIS>flgid ,</EMPHASIS>
+    UINT <EMPHASIS>waiptn ,</EMPHASIS>    UINT <EMPHASIS>wfmode,</EMPHASIS>    TMO <EMPHASIS>tmout</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ref_flg</FUNCTION>( 
+    T_RFLG *<EMPHASIS>pk_rflg,</EMPHASIS>    ID <EMPHASIS>flgid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>snd_msg</FUNCTION>( 
+    ID <EMPHASIS>mbxid,</EMPHASIS>    T_MSG <EMPHASIS>*pk_msg</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>rcv_msg</FUNCTION>( 
+    T_MSG **<EMPHASIS>ppk_msg,</EMPHASIS>    ID <EMPHASIS>mbxid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>prcv_msg</FUNCTION>( 
+    T_MSG **<EMPHASIS>ppk_msg,</EMPHASIS>    ID <EMPHASIS>mbxid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>trcv_msg</FUNCTION>( 
+    T_MSG **<EMPHASIS>ppk_msg,</EMPHASIS>    ID <EMPHASIS>mbxid ,</EMPHASIS>    TMO <EMPHASIS>tmout</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ref_mbx</FUNCTION>( 
+    T_RMBX *<EMPHASIS>pk_rmbx,</EMPHASIS>    ID <EMPHASIS>mbxid</EMPHASIS> )</PROGRAMLISTING>
+<PARA>The following functions are supported in this release (with
+some restrictions) if enabled with the appropriate configuration
+option for the object type (for example 
+<LITERAL>CYGPKG_UITRON_SEMAS_CREATE_DELETE</LITERAL>):
+</PARA>
+<PROGRAMLISTING>ER <FUNCTION>cre_sem</FUNCTION>( 
+    ID <EMPHASIS>semid,</EMPHASIS>    T_CSEM *<EMPHASIS>pk_csem</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>del_sem</FUNCTION>( 
+    ID <EMPHASIS>semid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>cre_flg</FUNCTION>( 
+    ID <EMPHASIS>flgid,</EMPHASIS>    T_CFLG *<EMPHASIS>pk_cflg</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>del_flg</FUNCTION>( 
+    ID <EMPHASIS>flgid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>cre_mbx</FUNCTION>( 
+    ID <EMPHASIS>mbxid,</EMPHASIS>    T_CMBX *<EMPHASIS>pk_cmbx</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>del_mbx</FUNCTION>( 
+    ID <EMPHASIS>mbxid</EMPHASIS> )</PROGRAMLISTING>
+<PARA>In general the queueing order when waiting on a synchronization
+object depends on the underlying kernel configuration. The multi-level
+queue scheduler is required for strict &micro;ITRON
+conformance and it queues tasks in FIFO order, so requests to create
+an object with priority queueing of tasks (<literal>pk_cxxx-&gt;xxxatr = TA_TPRI</literal>)
+are rejected with E_RSATR. Additional undefined bits in
+the attributes fields must be zero. </PARA>
+<PARA>In general, extended information (pk_cxxx-&gt;exinf)
+is ignored. </PARA>
+<PARA>For semaphores, the initial semaphore count (pk_csem-&gt;isemcnt)
+is supported; the new semaphore's count is set. The maximum
+count is not supported, and is not in fact defined in type pk_csem. </PARA>
+<PARA>For flags, multiple tasks are allowed to wait. Because single
+task waiting is a subset of this, the W bit (TA_WMUL) of
+the flag attributes is ignored; all other bits must be zero. The
+initial flag value is supported. </PARA>
+<PARA>For mailboxes, the buffer count is defined statically by kernel
+configuration option 
+<LITERAL>CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE</LITERAL>;
+therefore the buffer count field is not supported and is not in
+fact defined in type pk_cmbx. Queueing of messages is FIFO
+ordered only, so TA_MPRI (in pk_cmbx-&gt;mbxatr)
+is not supported. </PARA>
+<SECT2>
+<TITLE>Error checking</TITLE>
+<PARA>The following conditions are only checked for, and only return
+errors if 
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+is enabled:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>invalid object id; less than 1 or greater than 
+<LITERAL>CYGNUM_UITRON_TASKS/SEMAS/MBOXES</LITERAL>
+as appropriate returns E_ID</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>dispatching is enabled in any call which can sleep, or
+E_CTX</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>tmout must be positive, otherwise E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>pk_cxxx pointers in 
+<FUNCTION>cre_xxx()</FUNCTION>
+ must be valid pointers, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>return value pointer in 
+<FUNCTION>ref_xxx()</FUNCTION>
+ is valid pointer, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>flag wait pattern must be non-zero, and mode must be valid,
+or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>return value pointer in flag wait calls is a valid pointer,
+or E_PAR</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+<PARA>The following conditions are checked for, and can return error
+codes, regardless of the setting of
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>When create and delete functions 
+<FUNCTION>cre_xxx()</FUNCTION>
+ and 
+<FUNCTION>del_xxx()</FUNCTION>
+ are supported, all calls which use a valid object ID number check
+that the object exists. If not, E_NOEXS is returned.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In create functions 
+<FUNCTION>cre_xxx()</FUNCTION>
+, when supported, if the object already exists, then E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In any call which can sleep, such as 
+<FUNCTION>twai_sem()</FUNCTION>
+: return codes E_TMOUT, E_RLWAI, E_DLT
+or of course E_OK are returned depending on the reason
+for terminating the sleep</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In polling functions such as 
+<FUNCTION>preq_sem()</FUNCTION>
+return codes E_TMOUT or E_OK are returned depending
+on the state of the synchronization object</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In creation functions, the attributes must be compatible
+with the selected underlying kernel configuration: in 
+<FUNCTION>cre_sem()</FUNCTION>
+ <literal>pk_csem-&gt;sematr</literal>
+ must be equal to 
+<literal>TA_TFIFO</literal>
+ else E_RSATR.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In 
+<FUNCTION>cre_flg()</FUNCTION>
+ <literal>pk_cflg-&gt;flgatr</literal>
+ must be either 
+<varname>TA_WMUL</varname>
+ or 
+<varname>TA_WSGL</varname>
+ else <varname>E_RSATR</varname>.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In 
+<FUNCTION>cre_mbx()</FUNCTION>
+<LITERAL>pk_cmbx-&gt;mbxatr</LITERAL>
+ must be 
+<LITERAL>TA_TFIFO &plus; TA_MFIFO</LITERAL>
+ else E_RSATR.</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</SECT2>
+</SECT1>
+<SECT1 id="compat-uitron-extended-sync-comm-functions">
+<TITLE><!-- <index></index> -->Extended Synchronization and Communication Functions</TITLE>
+<PARA>None of these functions are supported in this release. </PARA>
+</SECT1>
+<SECT1 id="compat-uitron-interrupt-management-functions">
+<TITLE><!-- <index></index> -->Interrupt management functions</TITLE>
+<PARA>These functions are fully supported in this release:</PARA>
+<PROGRAMLISTING>void   <FUNCTION> ret_int</FUNCTION>( void )
+</programlisting>
+<programlisting>
+ER <FUNCTION>loc_cpu</FUNCTION>( void )
+</programlisting>
+<programlisting>
+ER <FUNCTION>unl_cpu</FUNCTION>( void )
+</programlisting>
+<programlisting>
+ER <FUNCTION>dis_int</FUNCTION>( 
+    UINT <EMPHASIS>eintno</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ena_int</FUNCTION>( 
+    UINT <EMPHASIS>eintno</EMPHASIS> )
+</programlisting>
+<programlisting>
+void   <FUNCTION>ret_wup</FUNCTION>( 
+    ID <EMPHASIS>tskid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>iwup_tsk</FUNCTION>( 
+    ID <EMPHASIS>tskid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>isig_sem</FUNCTION>( 
+    ID <EMPHASIS>semid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>iset_flg</FUNCTION>( 
+    ID <EMPHASIS>flgid ,</EMPHASIS>
+    UID<EMPHASIS> setptn</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>isend_msg</FUNCTION>( 
+    ID <EMPHASIS>mbxid ,</EMPHASIS>
+    T_MSG<EMPHASIS> *pk_msg</EMPHASIS> )</PROGRAMLISTING>
+<PARA>Note that <FUNCTION>ret_int()</FUNCTION> and
+the <FUNCTION>ret_wup()</FUNCTION> are  implemented
+as macros, containing a &ldquo;return&rdquo; statement.</PARA>
+<PARA>Also note that <FUNCTION>ret_wup()</FUNCTION> and
+the <FUNCTION>ixxx_yyy()</FUNCTION> style functions
+will only work when called from an ISR whose associated DSR is <FUNCTION>cyg_uitron_dsr()</FUNCTION>,
+as specified in include file <filename>&lt;cyg/compat/uitron/uit_ifnc.h&gt;</filename>,
+which defines the <FUNCTION>ixxx_yyy()</FUNCTION> style
+functions also.</PARA>
+<PARA>If you are writing interrupt handlers more in the
+<EMPHASIS>eCos</EMPHASIS> style, with separate ISR and DSR routines both of
+your own devising, do not use these special functions from a DSR: use plain
+<FUNCTION>xxx_yyy()</FUNCTION> style functions (with no &lsquo;i&rsquo; prefix)
+instead, and do not call any &micro;ITRON functions from the ISR at
+all.</PARA>
+<PARA>The following functions are not supported in this release: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>def_int</FUNCTION>( 
+    UINT <EMPHASIS>dintno,</EMPHASIS>
+  T_DINT *<EMPHASIS>pk_dint</EMPHASIS> )</programlisting>
+       <programlisting>
+ER <FUNCTION>chg_iXX</FUNCTION>( 
+    UINT <EMPHASIS>iXXXX</EMPHASIS> )
+  </programlisting>
+       <programlisting>
+ER <FUNCTION>ref_iXX</FUNCTION>( 
+    UINT * <EMPHASIS>p_iXXXX</EMPHASIS> )</PROGRAMLISTING>
+<PARA>These unsupported functions are all Level C (CPU dependent).
+Equivalent functionality is available via other <EMPHASIS>eCos</EMPHASIS>-specific
+APIs. </PARA>
+<SECT2>
+<TITLE>Error checking</TITLE>
+<PARA>The following conditions are only checked for, and only return
+errors if 
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+is enabled:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA><FUNCTION>loc/unl_cpu()</FUNCTION>
+: these must only be called in a 
+&micro;ITRON task context, else E_CTX.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA><FUNCTION>dis/ena_int()</FUNCTION>
+: the interrupt number must be in range as specified by the platform
+HAL in qustion, else E_PAR.</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</SECT2>
+</SECT1>
+<SECT1 id="compat-uitron-memory-pool-mgmt-functions">
+<TITLE><!-- <index></index> -->          Memory pool Management Functions</TITLE>
+<PARA>These functions are fully supported in this release: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>get_blf</FUNCTION>( 
+    VP *<EMPHASIS>p_blf,</EMPHASIS>    ID <EMPHASIS>mpfid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>pget_blf</FUNCTION>( 
+    VP *<EMPHASIS>p_blf,</EMPHASIS>    ID <EMPHASIS>mpfid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>tget_blf</FUNCTION>( 
+    VP *<EMPHASIS>p_blf,</EMPHASIS>    ID <EMPHASIS>mpfid,</EMPHASIS>    TMO <EMPHASIS>tmout</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>rel_blf</FUNCTION>( 
+    ID <EMPHASIS>mpfid,</EMPHASIS>    VP <EMPHASIS>blf</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ref_mpf</FUNCTION>( 
+    T_RMPF *<EMPHASIS>pk_rmpf,</EMPHASIS>    ID <EMPHASIS>mpfid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>get_blk</FUNCTION>( 
+    VP *<EMPHASIS>p_blk,</EMPHASIS>    ID <EMPHASIS>mplid,</EMPHASIS>    INT <EMPHASIS>blksz</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>pget_blk</FUNCTION>( 
+    VP *<EMPHASIS>p_blk,</EMPHASIS>    ID <EMPHASIS>mplid,</EMPHASIS>    INT <EMPHASIS>blksz</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>tget_blk</FUNCTION>( 
+    VP *<EMPHASIS>p_blk,</EMPHASIS>    ID <EMPHASIS>mplid,</EMPHASIS>    INT <EMPHASIS>blksz,</EMPHASIS>    TMO <EMPHASIS>tmout</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>rel_blk</FUNCTION>( 
+    ID <EMPHASIS>mplid,</EMPHASIS>    VP <EMPHASIS>blk</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ref_mpl</FUNCTION>( 
+    T_RMPL *<EMPHASIS>pk_rmpl,</EMPHASIS>    ID <EMPHASIS>mplid )
+</EMPHASIS></programlisting>
+
+<PARA>Note that of the memory provided for a particular pool to
+manage in the static initialization of the memory pool objects,
+some memory will be used to manage the pool itself. Therefore the
+number of blocks * the blocksize will be less than the total
+memory size. </PARA>
+<PARA>The following functions are supported in this release, when
+enabled with 
+<LITERAL>CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE</LITERAL>
+or 
+<LITERAL>CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE</LITERAL>
+as appropriate, with some restrictions: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>cre_mpl</FUNCTION>( 
+    ID <EMPHASIS>mplid,</EMPHASIS>    T_CMPL *<EMPHASIS>pk_cmpl</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>del_mpl</FUNCTION>( 
+    ID <EMPHASIS>mplid</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>cre_mpf</FUNCTION>( 
+    ID <EMPHASIS>mpfid,</EMPHASIS>    T_CMPF *<EMPHASIS>pk_cmpf</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>del_mpf</FUNCTION>( 
+    ID <EMPHASIS>mpfid</EMPHASIS> )</PROGRAMLISTING>
+<PARA>Because of the static initialization facilities provided for
+system objects, a memory pool is allocated a region of memory to
+manage statically in the configuration. So while memory pools can
+be created and deleted, the same area of memory is used for that
+memory pool (memory pool ID number) each time. The requested variable pool
+size (pk_cmpl-&gt;mplsz) or the number of fixed-size
+blocks (pk_cmpf-&gt;mpfcnt) times the block size
+(pk_cmpf-&gt;blfsz) are checked for fitting within
+the statically allocated memory area, so if a create call succeeds,
+the resulting pool will be at least as large as that requested.
+For this reason <FUNCTION>del_mpl()</FUNCTION> and <FUNCTION>del_mpf()</FUNCTION> do
+not in any sense free the memory that was managed by the deleted
+pool for use by other pools; it may only be managed by a pool of
+the same object id. </PARA>
+<PARA>For both fixed and variable memory pools, the queueing order
+when waiting on a synchronization object depends on the underlying
+kernel configuration. The multi-level queue scheduler is required
+for strict &micro;ITRON conformance and
+it queues tasks in FIFO order, so requests to create an object with
+priority queueing of tasks (pk_cxxx-&gt;xxxatr = TA_TPRI)
+are rejected with E_RSATR. Additional undefined bits in
+the attributes fields must be zero. </PARA>
+<PARA>In general, extended information (pk_cxxx-&gt;exinf)
+is ignored. </PARA>
+<SECT2>
+<TITLE>Error checking</TITLE>
+<PARA>The following conditions are only checked for, and only return
+errors if 
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+is enabled:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>invalid object id; less than 1 or greater than 
+<LITERAL>CYGNUM_UITRON_MEMPOOLVAR/MEMPOOLFIXED</LITERAL>
+as appropriate returns E_ID</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>dispatching is enabled in any call which can sleep, or
+E_CTX</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>tmout must be positive, otherwise E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>pk_cxxx pointers in 
+<FUNCTION>cre_xxx()</FUNCTION>
+ must be valid pointers, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>return value pointer in 
+<FUNCTION>ref_xxx()</FUNCTION>
+ is a valid pointer, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>return value pointers in get block routines is a valid
+pointer, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>blocksize request in get variable block routines is greater
+than zero, or E_PAR</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+<PARA>The following conditions are checked for, and can return error
+codes, regardless of the setting of 
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>:
+</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>When create and delete functions 
+<FUNCTION>cre_xxx()</FUNCTION>
+ and 
+<FUNCTION>del_xxx()</FUNCTION>
+ are supported, all calls which use a valid object ID number check
+that the object exists. If not, E_NOEXS is returned.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>When create functions 
+<FUNCTION>cre_xxx()</FUNCTION>
+ are supported, if the object already exists, then E_OBJ</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In any call which can sleep, such as 
+<FUNCTION>get_blk()</FUNCTION>
+: return codes E_TMOUT, E_RLWAI, E_DLT
+or of course E_OK are returned depending on the reason
+for terminating the sleep</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In polling functions such as 
+<FUNCTION>pget_blk()</FUNCTION>
+return codes E_TMOUT or E_OK are returned depending
+on the state of the synchronization object</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In creation functions, the attributes must be compatible
+with the selected underlying kernel configuration: in 
+<FUNCTION>cre_mpl()</FUNCTION>
+<LITERAL>pk_cmpl-&gt;mplatr</LITERAL>
+ must be equal to 
+<LITERAL>TA_TFIFO</LITERAL>
+ else E_RSATR.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In 
+<FUNCTION>cre_mpf()</FUNCTION>
+<LITERAL>pk_cmpf-&gt;mpfatr</LITERAL>
+ must be equal to 
+<LITERAL>TA_TFIFO</LITERAL>
+ else E_RSATR.</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In creation functions, the requested size of the memory
+pool must not be larger than that statically configured for the
+pool else E_RSATR; see the configuration option
+&ldquo;Option: Static initializers&rdquo;.
+ In 
+<FUNCTION>cre_mpl()</FUNCTION>
+<LITERAL>pk_cmpl-&gt;mplsz</LITERAL>
+ is the field of interest</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In 
+<FUNCTION>cre_mpf()</FUNCTION>
+ the product of 
+<LITERAL>pk_cmpf-&gt;blfsz</LITERAL>
+ and 
+<LITERAL>pk_cmpf-&gt;mpfcnt</LITERAL>
+ must be smaller than the memory statically configured for the pool
+else E_RSATR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In functions which return memory to the pool 
+<FUNCTION>rel_blk()</FUNCTION>
+ and 
+<FUNCTION>rel_blf()</FUNCTION>
+, if the free fails, for example because the memory did not come
+from that pool originally, then E_PAR is returned</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</SECT2>
+</SECT1>
+<SECT1 id="compat-uitron-time-mgmt-functions">
+<TITLE><!-- <index></index> -->Time Management Functions</TITLE>
+<PARA>These functions are fully supported in this release: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>set_tim</FUNCTION>( 
+    SYSTIME *<EMPHASIS>pk_tim</EMPHASIS> )</PROGRAMLISTING>
+<CAUTION>
+<PARA>     Setting the time may cause erroneous operation of the
+           kernel, for example a task performing a wait with a
+           time-out may never awaken.</PARA>
+</CAUTION>
+<PROGRAMLISTING>ER <FUNCTION>get_tim</FUNCTION>( 
+    SYSTIME *<EMPHASIS>pk_tim</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>dly_tsk</FUNCTION>( 
+    DLYTIME <EMPHASIS>dlytim</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>def_cyc</FUNCTION>( 
+    HNO <EMPHASIS>cycno,</EMPHASIS>    T_DCYC *<EMPHASIS>pk_dcyc</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>act_cyc</FUNCTION>( 
+    HNO <EMPHASIS>cycno,</EMPHASIS>    UINT <EMPHASIS>cycact</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ref_cyc</FUNCTION>( 
+    T_RCYC *<EMPHASIS>pk_rcyc,</EMPHASIS>    HNO <EMPHASIS>cycno</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>def_alm</FUNCTION>( 
+    HNO <EMPHASIS>almno,</EMPHASIS>    T_DALM *<EMPHASIS>pk_dalm</EMPHASIS> )
+</programlisting>
+<programlisting>
+ER <FUNCTION>ref_alm</FUNCTION>( 
+    T_RALM *<EMPHASIS>pk_ralm,</EMPHASIS>    HNO <EMPHASIS>almno</EMPHASIS> )
+</programlisting>
+<programlisting>
+void <FUNCTION>ret_tmr</FUNCTION>( void )</programlisting>
+       <sect2>
+         <title>Error checking</title>
+<PARA>The following conditions are only checked for, and only return
+errors if 
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+is enabled:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>invalid handler number; less than 1 or greater than 
+<LITERAL>CYGNUM_UITRON_CYCLICS/ALARMS</LITERAL>
+as appropriate, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>dispatching is enabled in 
+<FUNCTION>dly_tsk()</FUNCTION>
+, or E_CTX</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>dlytim must be positive or zero, otherwise E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>return value pointer in 
+<FUNCTION>ref_xxx()</FUNCTION>
+ is a valid pointer, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>params within pk_dalm and pk_dcyc must
+be valid, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>cycact in 
+<FUNCTION>act_cyc()</FUNCTION>
+ must be valid, or E_PAR</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>handler must be defined in 
+<FUNCTION>ref_xxx()</FUNCTION>
+ and 
+<FUNCTION>act_cyc()</FUNCTION>
+, or E_NOEXS</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>parameter pointer must be a good pointer in 
+<FUNCTION>get_tim()</FUNCTION>
+ and 
+<FUNCTION>set_tim()</FUNCTION>
+, otherwise E_PAR is returned</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+<PARA>The following conditions are checked for, and can return
+         error codes, regardless of the setting of
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+:</PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA><FUNCTION>dly_tsk()</FUNCTION>
+: return code E_RLWAI is returned depending on the reason
+for terminating the sleep</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</sect2>
+</SECT1>
+<SECT1 id="compat-uitron-system-mgmt-functions">
+<TITLE><!-- <index></index> -->          System Management Functions</TITLE>
+<PARA>These functions are fully supported in this release:
+       </PARA>
+<PROGRAMLISTING>ER <FUNCTION>get_ver</FUNCTION>( 
+    T_VER *<EMPHASIS>pk_ver</EMPHASIS> )
+</PROGRAMLISTING>
+<PROGRAMLISTING>ER <FUNCTION>ref_sys</FUNCTION>( 
+    T_RSYS *<EMPHASIS>pk_rsys</EMPHASIS> )
+</PROGRAMLISTING>
+<PROGRAMLISTING>ER <FUNCTION>ref_cfg</FUNCTION>( 
+    T_RCFG *<EMPHASIS>pk_rcfg</EMPHASIS> )
+</PROGRAMLISTING>
+<PARA>Note that the information returned by each of these calls
+may be configured to match the user's own versioning system,
+and the values supplied by the default configuration may be inappropriate. </PARA>
+<PARA>These functions are not supported in this release: </PARA>
+<PROGRAMLISTING>ER <FUNCTION>def_svc</FUNCTION>( 
+    FN <EMPHASIS>s_fncd,</EMPHASIS>
+    T_DSVC *<EMPHASIS>pk_dsvc</EMPHASIS> )
+</PROGRAMLISTING>
+<PROGRAMLISTING>ER <FUNCTION>def_exc</FUNCTION>( 
+    UINT <EMPHASIS>exckind,</EMPHASIS>
+    T_DEXC *<EMPHASIS>pk_dexc</EMPHASIS> )
+</PROGRAMLISTING>
+<SECT2>
+<TITLE>Error checking</TITLE>
+<PARA>The following conditions are only checked for, and
+           only return errors if
+           
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+ is enabled: </PARA>
+<ITEMIZEDLIST>
+<LISTITEM>
+<PARA>return value pointer in all calls is a valid
+             pointer, or E_PAR</PARA>
+</LISTITEM>
+</ITEMIZEDLIST>
+</SECT2>
+</SECT1>
+<SECT1 id="compat-uitron-network-support-functions">
+<TITLE><!-- <index></index> -->          Network Support Functions</TITLE>
+<PARA>None of these functions are supported in this release.
+       </PARA>
+</SECT1>
+<SECT1 id="compat-uitron-configuration-faq">
+<TITLE><!-- <index></index> -->&micro;ITRON Configuration FAQ</TITLE>
+<PARA><EMPHASIS>Q: How are &micro;ITRON objects created?</EMPHASIS>
+</PARA>
+<PARA>
+For each type of uITRON object (tasks, semaphores, flags, mboxes, mpf, mpl)
+these two quantities are controlled by configuration:
+</PARA>
+<ITEMIZEDLIST>
+<LISTITEM><PARA>
+The <EMPHASIS>maximum</EMPHASIS> number of this type of object.
+</PARA></LISTITEM>
+<LISTITEM><PARA>
+The number of these objects which exist <EMPHASIS>initially</EMPHASIS>.
+</PARA></LISTITEM>
+</ITEMIZEDLIST>
+<PARA>
+This is assuming that for the relevant object type,
+<EMPHASIS>create</EMPHASIS> and <EMPHASIS>delete</EMPHASIS>
+operations are enabled; enabled is the default.  For example, the option
+<LITERAL>CYGPKG_UITRON_MBOXES_CREATE_DELETE</LITERAL>
+controls whether the functions
+<FUNCTION>cre_mbx()</FUNCTION>
+and
+<FUNCTION>del_mbx()</FUNCTION>
+exist in the API.  If not, then the maximum number of
+mboxes is the same as the initial number of mboxes, and so on for all
+&micro;ITRON object types.
+</PARA>
+<PARA>
+Mboxes have no initialization, so there are only a few, simple
+configuration options:
+</PARA>
+<ITEMIZEDLIST>
+<LISTITEM><PARA>
+<LITERAL>CYGNUM_UITRON_MBOXES</LITERAL>
+is the total number of mboxes that you can have in the
+system.  By default this is 4, so you can use mboxes 1,2,3 and 4.  You
+cannot create mboxes outside this range; trying to
+<FUNCTION>cre_mbx(5,...)</FUNCTION>
+will return an error.
+</PARA></LISTITEM>
+<LISTITEM><PARA>
+<LITERAL>CYGNUM_UITRON_MBOXES_INITIALLY</LITERAL>
+is the number of mboxes created
+automatically for you, during startup.  By default this is 4, so all 4
+mboxes exist already, and an attempt to create one of these
+eg. <FUNCTION>cre_mbx(3,...)</FUNCTION>
+will return an error because the mbox in quesion already
+exists.  You can delete a pre-existing mbox, and then re-create it.
+</PARA></LISTITEM>
+</ITEMIZEDLIST>
+<PARA>
+If you change 
+<LITERAL>CYGNUM_UITRON_MBOXES_INITIALLY</LITERAL>,
+for example to 0, no mboxes
+are created automatically for you during startup.  Any attempt to use an
+mbox without creating it will return E_NOEXS because the mbox does not
+exist.  You can create an mbox, say <FUNCTION>cre_mbx(3,...)</FUNCTION>
+and then use it, say
+<FUNCTION>snd_msg(3,&amp;foo)</FUNCTION>, and all will be well.
+</PARA>
+<PARA><EMPHASIS>Q: How are &micro;ITRON objects initialized?</EMPHASIS>
+</PARA>
+<PARA>
+Some object types have optional initialization.  Semaphores are an
+example.  You could have 
+<LITERAL>CYGNUM_UITRON_SEMAS</LITERAL>=10 and
+<LITERAL>CYGNUM_UITRON_SEMAS_INITIALLY</LITERAL>=5
+which means you can use semaphores 1-5
+straight off, but you must create semaphores 6-10 before you can use them.
+If you decide not to initialize semaphores, semaphores 1-5 will have an
+initial count of zero.  If you decide to initialize them, you must supply
+a dummy initializer for semaphores 6-10 also.  For example,
+in terms of the configuration output in
+<filename>pkgconf/uitron.h</filename>:
+</PARA>
+<PROGRAMLISTING>
+   #define CYGDAT_UITRON_SEMA_INITIALIZERS \
+        CYG_UIT_SEMA(  1 ),     \
+        CYG_UIT_SEMA(  0 ),     \
+        CYG_UIT_SEMA(  0 ),     \
+        CYG_UIT_SEMA( 99 ),     \
+        CYG_UIT_SEMA(  1 ),     \
+        CYG_UIT_SEMA_NOEXS,     \
+        CYG_UIT_SEMA_NOEXS,     \
+        CYG_UIT_SEMA_NOEXS,     \
+        CYG_UIT_SEMA_NOEXS,     \
+        CYG_UIT_SEMA_NOEXS
+</PROGRAMLISTING>
+<PARA>
+Semaphore 1 will have initial count 1, semaphores 2 and 3 will be zero,
+number 4 will be 99 initially, 5 will be one and numbers 6 though 10 do not
+exist initially.
+</PARA>
+<PARA>
+Aside: this is how the definition of the symbol would appear in the
+configuration header file <filename>pkgconf/uitron.h</filename> &mdash;
+unfortunately editing such a long, multi-line definition is somewhat
+cumbersome in the GUI config tool in current releases.  The macros
+<LITERAL>CYG_UIT_SEMA()</LITERAL>
+&mdash; to create a semaphore initializer &mdash; and
+<LITERAL>CYG_UIT_SEMA_NOEXS</LITERAL>
+&mdash; to invoke a dummy initializer &mdash;
+are provided in in the environment to help with this.  Similar macros are
+provided for other object types.  The resulting #define symbol is used in
+the context of a C++ array initializer, such as:
+<PROGRAMLISTING>
+Cyg_Counting_Semaphore2 cyg_uitron_SEMAS[ CYGNUM_UITRON_SEMAS ] = {
+       CYGDAT_UITRON_SEMA_INITIALIZERS
+};
+</PROGRAMLISTING>
+which is eventually macro-processed to give
+<PROGRAMLISTING>
+Cyg_Counting_Semaphore2 cyg_uitron_SEMAS[ 10 ] = {
+       Cyg_Counting_Semaphore2( ( 1 ) ), 
+       Cyg_Counting_Semaphore2( ( 0 ) ), 
+       Cyg_Counting_Semaphore2( ( 0 ) ), 
+       Cyg_Counting_Semaphore2( ( 99 ) ), 
+       Cyg_Counting_Semaphore2( ( 1 ) ), 
+       Cyg_Counting_Semaphore2(0), 
+       Cyg_Counting_Semaphore2(0), 
+       Cyg_Counting_Semaphore2(0), 
+       Cyg_Counting_Semaphore2(0), 
+       Cyg_Counting_Semaphore2(0), 
+};
+</PROGRAMLISTING>
+so you can see how it is necessary to include the dummy entries in that
+definition, otherwise the resulting code will not compile correctly.
+</PARA>
+<PARA>
+If you choose 
+<LITERAL>CYGNUM_UITRON_SEMAS_INITIALLY</LITERAL>=0
+it is meaningless to initialize them, for they must be created and so
+initialized then, before use.
+</PARA>
+<PARA><EMPHASIS>Q: What about &micro;ITRON tasks?</EMPHASIS>
+</PARA>
+<PARA>
+Some object types require initialization.  Tasks are an example of this.
+You must provide a task with a priority, a function to enter when the task
+starts, a name (for debugging purposes), and some memory to use for the stack.
+For example (again in terms of the resulting
+definitions in <filename>pkgconf/uitron.h</filename>):
+</PARA>
+<PROGRAMLISTING>
+#define CYGNUM_UITRON_TASKS 4           // valid task ids are 1,2,3,4
+#define CYGNUM_UITRON_TASKS_INITIALLY 4 // they all exist at start
+
+#define CYGDAT_UITRON_TASK_EXTERNS             \
+extern "C" void startup( unsigned int );       \
+extern "C" void worktask( unsigned int );      \
+extern "C" void lowtask( unsigned int );        \
+static char stack1[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack2[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack3[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack4[ CYGNUM_UITRON_STACK_SIZE ];
+
+#define CYGDAT_UITRON_TASK_INITIALIZERS \
+ CYG_UIT_TASK("main task", 8, startup,  &amp;stack1, sizeof( stack1 )), \
+ CYG_UIT_TASK("worker 2" , 9, worktask, &amp;stack2, sizeof( stack2 )), \
+ CYG_UIT_TASK("worker 3" , 9, worktask, &amp;stack3, sizeof( stack3 )), \
+ CYG_UIT_TASK("low task" ,20, lowtask,  &amp;stack4, sizeof( stack4 )), \
+
+</PROGRAMLISTING>
+<PARA>
+So this example has all four tasks statically configured to exist, ready to
+run, from the start of time.  The &ldquo;main task&rdquo; runs a routine
+called <FUNCTION>startup()</FUNCTION> at priority 8.  Two
+&ldquo;worker&rdquo; tasks run both a priority 9, and a &ldquo;low
+priority&rdquo; task runs at priority 20 to do useful non-urgent background
+work.
+</PARA>
+<screen>
+Task ID | Exists at | Function | Priority | Stack   | Stack
+ number |  startup  |  entry   |          | address | size
+--------+-----------+----------+----------+---------+----------
+   1    |    Yes    |  startup |    8     | &amp;stack1 | CYGNUM...
+   2    |    Yes    | worktask |    9    | &amp;stack2 | CYGNUM...
+   3    |    Yes    | worktask |    9    | &amp;stack3 | CYGNUM...
+   4    |    Yes    |  lowtask |   20    | &amp;stack4 | CYGNUM...
+--------+-----------+----------+----------+---------+----------
+</screen>
+<PARA><EMPHASIS>Q: How can I create &micro;ITRON tasks in the program?</EMPHASIS>
+</PARA>
+<PARA>
+You must provide free slots in the task table in which to create new tasks,
+by configuring the number of tasks existing initially to be smaller than
+the total.
+For a task ID which does not initially exist, it will be told what routine
+to call, and what priority it is, when the task is created.  But you must
+still set aside memory for the task to use for its stack, and give it a
+name during initialization.  For example:
+</PARA>
+
+<PROGRAMLISTING>
+#define CYGNUM_UITRON_TASKS 4           // valid task ids are 1-4
+#define CYGNUM_UITRON_TASKS_INITIALLY 1 // only task #1 exists
+
+#define CYGDAT_UITRON_TASK_EXTERNS \
+extern "C" void startup( unsigned int ); \
+static char stack1[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack2[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack3[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack4[ CYGNUM_UITRON_STACK_SIZE ];
+
+#define CYGDAT_UITRON_TASK_INITIALIZERS \
+   CYG_UIT_TASK( "main", 8, startup, &amp;stack1, sizeof( stack1 ) ), \
+   CYG_UIT_TASK_NOEXS( "slave",      &amp;stack2, sizeof( stack2 ) ), \
+   CYG_UIT_TASK_NOEXS( "slave2",     &amp;stack3, sizeof( stack3 ) ), \
+   CYG_UIT_TASK_NOEXS( "slave3",     &amp;stack4, sizeof( stack4 ) ), \
+
+</PROGRAMLISTING>
+<PARA>
+So tasks numbered 2,3 and 4 have been given their stacks during startup,
+though they do not yet exist in terms of <FUNCTION>cre_tsk()</FUNCTION> and
+<FUNCTION>del_tsk()</FUNCTION> so you can create tasks 2&ndash;4 at
+runtime.
+</PARA>
+<screen>
+Task ID | Exists at | Function | Priority | Stack   | Stack
+ number |  startup  |  entry   |          | address | size
+--------+-----------+----------+----------+---------+----------
+   1    |    Yes    |  startup |    8     | &amp;stack1 | CYGNUM...
+   2    |    No     |   N/A    |   N/A    | &amp;stack2 | CYGNUM...
+   3    |    No     |   N/A    |   N/A    | &amp;stack3 | CYGNUM...
+   4    |    No     |   N/A    |   N/A    | &amp;stack4 | CYGNUM...
+--------+-----------+----------+----------+---------+----------
+</screen>
+<PARA>
+(you must have at least one task at startup in order that the system can
+ actually run; this is not so for other uITRON object types)
+</PARA>
+<PARA><EMPHASIS>Q: Can I have different stack sizes for &micro;ITRON tasks?</EMPHASIS>
+</PARA>
+<PARA>
+Simply set aside different amounts of memory for each task to use for its
+stack.  Going back to a typical default setting for the &micro;ITRON tasks,
+the definitions in <filename>pkgconf/uitron.h</filename> might look like this:
+</PARA>
+<PROGRAMLISTING>
+#define CYGDAT_UITRON_TASK_EXTERNS \
+extern "C" void task1( unsigned int ); \
+extern "C" void task2( unsigned int ); \
+extern "C" void task3( unsigned int ); \
+extern "C" void task4( unsigned int ); \
+static char stack1[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack2[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack3[ CYGNUM_UITRON_STACK_SIZE ], \
+            stack4[ CYGNUM_UITRON_STACK_SIZE ];
+  
+#define CYGDAT_UITRON_TASK_INITIALIZERS \
+  CYG_UIT_TASK( "t1", 1, task1, &amp;stack1, CYGNUM_UITRON_STACK_SIZE ), \
+  CYG_UIT_TASK( "t2", 2, task2, &amp;stack2, CYGNUM_UITRON_STACK_SIZE ), \
+  CYG_UIT_TASK( "t3", 3, task3, &amp;stack3, CYGNUM_UITRON_STACK_SIZE ), \
+  CYG_UIT_TASK( "t4", 4, task4, &amp;stack4, CYGNUM_UITRON_STACK_SIZE )
+
+</PROGRAMLISTING>
+<PARA>
+Note that 
+<LITERAL>CYGNUM_UITRON_STACK_SIZE</LITERAL>
+is used to control the size of the stack
+objects themselves, and to tell the system what size stack is being provided.
+</PARA>
+<PARA>
+Suppose instead stack sizes of 2000, 1000, 800 and 800 were required:
+this could be achieved by using the GUI config tool to edit these
+options, or editting the <filename>.ecc</filename> file to get these
+results in <filename>pkgconf/uitron.h</filename>:
+</PARA>
+<PROGRAMLISTING>
+#define CYGDAT_UITRON_TASK_EXTERNS \
+extern "C" void task1( unsigned int ); \
+extern "C" void task2( unsigned int ); \
+extern "C" void task3( unsigned int ); \
+extern "C" void task4( unsigned int ); \
+static char stack1[ 2000 ], \
+            stack2[ 1000 ], \
+            stack3[  800 ], \
+            stack4[  800 ];
+#define CYGDAT_UITRON_TASK_INITIALIZERS \
+      CYG_UIT_TASK( "t1", 1, task1, &amp;stack1, sizeof( stack1 ) ), \
+      CYG_UIT_TASK( "t2", 2, task2, &amp;stack2, sizeof( stack2 ) ), \
+      CYG_UIT_TASK( "t3", 3, task3, &amp;stack3, sizeof( stack3 ) ), \
+      CYG_UIT_TASK( "t4", 4, task4, &amp;stack4, sizeof( stack4 ) )
+</PROGRAMLISTING>
+<PARA>
+Note that the sizeof() operator has been used to tell the system what size
+stacks are provided, rather than quoting a number (which is difficult for
+maintenance) or the symbol 
+<LITERAL>CYGNUM_UITRON_STACK_SIZE</LITERAL>
+(which is wrong).
+</PARA>
+<PARA>
+We recommend using (if available in your release) the stacksize symbols
+provided in the architectural HAL for your target, called
+<LITERAL>CYGNUM_HAL_STACK_SIZE_TYPICAL</LITERAL>
+and 
+<LITERAL>CYGNUM_HAL_STACK_SIZE_MINIMUM</LITERAL>.
+So a better (more portable) version of the above might be:
+</PARA>
+<PROGRAMLISTING>
+#define CYGDAT_UITRON_TASK_EXTERNS \
+extern "C" void task1( unsigned int ); \
+extern "C" void task2( unsigned int ); \
+extern "C" void task3( unsigned int ); \
+extern "C" void task4( unsigned int ); \
+static char stack1[ CYGNUM_HAL_STACK_SIZE_TYPICAL + 1200 ], \
+            stack2[ CYGNUM_HAL_STACK_SIZE_TYPICAL +  200 ], \
+            stack3[ CYGNUM_HAL_STACK_SIZE_TYPICAL        ], \
+            stack4[ CYGNUM_HAL_STACK_SIZE_TYPICAL        ];
+
+#define CYGDAT_UITRON_TASK_INITIALIZERS \
+      CYG_UIT_TASK( "t1", 1, task1, &amp;stack1, sizeof( stack1 ) ), \
+      CYG_UIT_TASK( "t2", 2, task2, &amp;stack2, sizeof( stack2 ) ), \
+      CYG_UIT_TASK( "t3", 3, task3, &amp;stack3, sizeof( stack3 ) ), \
+      CYG_UIT_TASK( "t4", 4, task4, &amp;stack4, sizeof( stack4 ) )
+</PROGRAMLISTING>
+</SECT1>
+</CHAPTER>
+</part>
diff --git a/packages/compat/uitron/v2_0/include/uit_func.h b/packages/compat/uitron/v2_0/include/uit_func.h
new file mode 100644 (file)
index 0000000..f399a93
--- /dev/null
@@ -0,0 +1,402 @@
+#ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_H
+#define CYGONCE_COMPAT_UITRON_UIT_FUNC_H
+//===========================================================================
+//
+//      uit_func.h
+//
+//      uITRON compatibility functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON compatibility functions
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+// ------------------------------------------------------------------------
+// Source Code Organization
+//
+// First, see pkgconf/uitron.h for details of applicable configuration
+// options.
+//
+// This file uit_func.h provides prototypes for the uITRON API.  All the
+// uITRON functions are listed here.  The prototypes are configurable
+// either to have C or C++ linkage, and if being compiled in a C++
+// environment, to be inline.
+//
+// The function prototypes are all in terms of uITRON type definitions from
+// uit_type.h, which is included at the head of uit_func.h.
+//
+// The implementations of the uITRON functions are in uit_func.inl, which
+// is either included at the end of uit_func.h (if functions are inline) or
+// in uit_func.cxx (if outline).
+// 
+// uit_func.cxx provides some startup functions plus, if the uITRON
+// functions are out of line, uit_func.inl is included to instantiate those
+// functions.
+// 
+// uITRON system objects (tasks, semaphores...) are described in
+// uit_obj.hxx.  This is a C++ file and is used by the implementation of
+// the uITRON functions.
+// 
+// The uITRON system objects are instantiated in uit_obj.cxx, which uses
+// uit_obj.hxx to define the objects, and the configuration file
+// pkgconf/uitron.h to construct them as required.
+//
+// The include graph from an application, which should only include
+// uit_func.h, is similar to the following:
+//
+// 
+// [inline uITRON functions:]
+//
+//    <your_app.c>
+//    .       uit_func.h                       ; prototypes for funcs
+//    .       .       pkgconf/uitron.h         ; configuration info
+//    .       .       uit_type.h               ; typedefs for func args
+//    .       (function prototypes)
+//    .       .       uit_func.inl             ; full function bodies
+//    .       .       .       uit_objs.hxx     ; defs of uITRON data
+//    .       .       (function implementations)
+//    
+//
+// [out-of-line uITRON functions:]
+//
+//    <your_app.c>
+//    .       uit_func.h                       ; prototypes for funcs
+//    .       .       pkgconf/uitron.h         ; configuration info
+//    .       .       uit_type.h               ; typedefs for func args
+//    .       (function prototypes)
+//    
+//
+// [other uITRON compilation units:]
+//
+//    uit_func.cxx                             ; out-of-line functions
+//    .       pkgconf/uitron.h                 ; configuration info
+//    .       uit_func.h                       ; prototypes for funcs
+//    .       .       uit_type.h               ; typedefs for func args
+//    .       (function prototypes)
+//    .       .       uit_func.inl             ; full function bodies
+//    .       .       .       uit_objs.hxx     ; defs of uITRON data
+//    .       .       (function implementations)
+// 
+//
+//    uit_objs.cxx                             ; static uITRON data objects
+//    .       pkgconf/uitron.h                 ; configuration info
+//    .       uit_objs.hxx                     ; defs of uITRON data
+//    (static uITRON system objects)
+//
+// 
+// The various include files are protected against multiple inclusion and
+// so may be safely re-included as convenient.
+// 
+// ------------------------------------------------------------------------
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+
+#ifdef CYGPKG_UITRON
+
+#include <cyg/infra/cyg_type.h>         // types; cyg_int32, CYG_ADDRWORD
+
+#include <cyg/compat/uitron/uit_type.h> // uITRON types; ER ID TMO T_MSG
+
+// ------------------------------------------------------------------------
+// Object operations:
+//
+// The functions can be inlined in C compiled by C++, or C++ of course,
+// and also outlined in extern "C" functions, eg. for taking the address
+// of, or for use by a pure C program, or of course outlined in C++ for
+// Code size reasons.
+//
+//
+// Summary:
+//
+// IF compiling in C
+// THEN functions must be C linkage and out of line:
+//      do NOT specify CYGIMP_UITRON_INLINE_FUNCS nor
+//                     CYGIMP_UITRON_CPP_OUTLINE_FUNCS.
+// IF compiling in C++
+// THEN functions can be inline: specify CYGIMP_UITRON_INLINE_FUNCS
+//   OR by default, functions are out of line:
+//       outline functions can have C++ linkage:
+//                 specify CYGIMP_UITRON_CPP_OUTLINE_FUNCS
+//       OR by default, outline functions have C linkage.
+
+
+#ifdef __cplusplus
+// C++ environment; functions can be inline or not as we please.
+// If not inline they might as well be "C" linkage for sharing with
+// any pure "C" code present.
+
+#ifdef CYGIMP_UITRON_INLINE_FUNCS
+
+#define CYG_UIT_FUNC_EXTERN_BEGIN
+#define CYG_UIT_FUNC_EXTERN_END
+#define CYG_UIT_FUNC_INLINE             inline
+#ifndef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+#define CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+#endif
+
+#else
+
+#ifdef CYGIMP_UITRON_CPP_OUTLINE_FUNCS
+#define CYG_UIT_FUNC_EXTERN_BEGIN       extern "C++" {
+#define CYG_UIT_FUNC_EXTERN_END         }
+#else
+#define CYG_UIT_FUNC_EXTERN_BEGIN       extern "C" {
+#define CYG_UIT_FUNC_EXTERN_END         }
+#endif
+
+#define CYG_UIT_FUNC_INLINE
+#endif
+
+#else // !__cplusplus
+// Vanilla "C" environment; external "C" linkage, no inline functions
+
+#ifdef CYGIMP_UITRON_INLINE_FUNCS
+#error "Cannot inline uITRON functions in pure C environment"
+#endif
+#ifdef CYGIMP_UITRON_CPP_OUTLINE_FUNCS
+#error "Cannot use C++ linkage of outline fns in pure C environment"
+#endif
+
+#define CYG_UIT_FUNC_EXTERN_BEGIN
+#define CYG_UIT_FUNC_EXTERN_END
+#define CYG_UIT_FUNC_INLINE             
+
+#endif // !__cplusplus
+
+// ========================================================================
+//         u I T R O N   F U N C T I O N S
+// The function declarations themselves:
+
+CYG_UIT_FUNC_EXTERN_BEGIN
+
+// this routine is outside the uITRON specification; call it from main() to
+// start the uITRON tasks and scheduler.  It does not return.
+
+#ifdef CYGNUM_UITRON_START_TASKS
+void cyg_uitron_start( void );
+#endif
+
+// ******************************************************
+// ***    6.5 C Language Interfaces                   ***
+// ******************************************************
+
+// - Task Management Functions
+
+ER      cre_tsk ( ID tskid, T_CTSK *pk_ctsk );
+ER      del_tsk ( ID tskid );
+ER      sta_tsk ( ID tskid, INT stacd );
+void    ext_tsk ( void );
+void    exd_tsk ( void );
+ER      ter_tsk ( ID tskid );
+
+ER      dis_dsp ( void );
+ER      ena_dsp ( void );
+ER      chg_pri ( ID tskid, PRI tskpri );
+ER      rot_rdq ( PRI tskpri );
+ER      rel_wai ( ID tskid );
+ER      get_tid ( ID *p_tskid );
+ER      ref_tsk ( T_RTSK *pk_rtsk, ID tskid );
+        
+// - Task-Dependent Synchronization Functions
+        
+ER      sus_tsk ( ID tskid );
+ER      rsm_tsk ( ID tskid );
+ER      frsm_tsk ( ID tskid );
+ER      slp_tsk ( void );
+ER      tslp_tsk ( TMO tmout );
+ER      wup_tsk ( ID tskid );
+ER      can_wup ( INT *p_wupcnt, ID tskid );
+        
+// - Synchronization and Communication Functions
+        
+ER      cre_sem ( ID semid, T_CSEM *pk_csem );
+ER      del_sem ( ID semid );
+ER      sig_sem ( ID semid );
+ER      wai_sem ( ID semid );
+ER      preq_sem ( ID semid );
+ER      twai_sem ( ID semid, TMO tmout );
+ER      ref_sem ( T_RSEM *pk_rsem, ID semid );
+
+ER      cre_flg ( ID flgid, T_CFLG *pk_cflg );
+ER      del_flg ( ID flgid );
+ER      set_flg ( ID flgid, UINT setptn );
+ER      clr_flg ( ID flgid, UINT clrptn );
+ER      wai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode );
+ER      pol_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode );
+ER      twai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode,
+              TMO tmout );
+ER      ref_flg ( T_RFLG *pk_rflg, ID flgid );
+
+ER      cre_mbx ( ID mbxid, T_CMBX* pk_cmbx );
+ER      del_mbx ( ID mbxid );
+ER      snd_msg ( ID mbxid, T_MSG *pk_msg );
+ER      rcv_msg ( T_MSG **ppk_msg, ID mbxid );
+ER      prcv_msg ( T_MSG **ppk_msg, ID mbxid );
+ER      trcv_msg ( T_MSG **ppk_msg, ID mbxid, TMO tmout );
+ER      ref_mbx ( T_RMBX *pk_rmbx, ID mbxid );
+        
+// - Extended Synchronization and Communication Functions
+        
+#if 0 // NOT SUPPORTED
+ER      cre_mbf ( ID mbfid, T_CMBF *pk_cmbf );
+ER      del_mbf ( ID mbfid );
+ER      snd_mbf ( ID mbfid, VP msg, INT msgsz );
+ER      psnd_mbf ( ID mbfid, VP msg, INT msgsz );
+ER      tsnd_mbf ( ID mbfid, VP msg, INT msgsz, TMO tmout );
+ER      rcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
+ER      prcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
+ER      trcv_mbf ( VP msg, INT *p_msgsz, ID mbfid, TMO tmout );
+ER      ref_mbf ( T_RMBF *pk_rmbf, ID mbfid );
+ER      cre_por ( ID porid, T_CPOR *pk_cpor );
+ER      del_por ( ID porid );
+ER      cal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
+              cmsgsz );
+ER      pcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
+              cmsgsz );
+ER      tcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
+              cmsgsz, TMO tmout );
+ER      acp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
+              acpptn );
+ER      pacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
+              acpptn );
+ER      tacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
+              acpptn, TMO tmout );
+ER      fwd_por ( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz
+              );
+ER      rpl_rdv ( RNO rdvno, VP msg, INT rmsgsz );
+ER      ref_por ( T_RPOR *pk_rpor, ID porid );
+#endif
+        
+// - Interrupt Management Functions
+        
+#if 0 // NOT SUPPORTED
+ER      def_int ( UINT dintno, T_DINT *pk_dint );
+void    ret_wup ( ID tskid );
+#endif
+#if 0
+void    ret_int ( void );
+#endif
+#define ret_int() return
+ER      loc_cpu ( void );
+ER      unl_cpu ( void );
+
+ER      dis_int ( UINT eintno );
+ER      ena_int ( UINT eintno );
+
+#if 0 // NOT SUPPORTED
+ER      chg_iXX ( UINT iXXXX );
+ER      ref_iXX ( UINT *p_iXXXX );
+#endif
+        
+// - Memorypool Management Functions
+        
+ER      cre_mpl ( ID mplid, T_CMPL *pk_cmpl );
+ER      del_mpl ( ID mplid );
+ER      get_blk ( VP *p_blk, ID mplid, INT blksz );
+ER      pget_blk ( VP *p_blk, ID mplid, INT blksz );
+ER      tget_blk ( VP *p_blk, ID mplid, INT blksz, TMO tmout );
+ER      rel_blk ( ID mplid, VP blk );
+ER      ref_mpl ( T_RMPL *pk_rmpl, ID mplid );
+
+ER      cre_mpf ( ID mpfid, T_CMPF *pk_cmpf );
+ER      del_mpf ( ID mpfid );
+ER      get_blf ( VP *p_blf, ID mpfid );
+ER      pget_blf ( VP *p_blf, ID mpfid );
+ER      tget_blf ( VP *p_blf, ID mpfid, TMO tmout );
+ER      rel_blf ( ID mpfid, VP blf );
+ER      ref_mpf ( T_RMPF *pk_rmpf, ID mpfid );
+        
+// - Time Management Functions
+        
+ER      set_tim ( SYSTIME *pk_tim );
+ER      get_tim ( SYSTIME *pk_tim );
+ER      dly_tsk ( DLYTIME dlytim );
+ER      def_cyc ( HNO cycno, T_DCYC *pk_dcyc );
+ER      act_cyc ( HNO cycno, UINT cycact );
+ER      ref_cyc ( T_RCYC *pk_rcyc, HNO cycno );
+ER      def_alm ( HNO almno, T_DALM *pk_dalm );
+ER      ref_alm ( T_RALM *pk_ralm, HNO almno );
+#if 0
+void    ret_tmr ( void );
+#endif
+#define ret_tmr() return
+        
+// - System Management Functions
+        
+ER      get_ver ( T_VER *pk_ver );
+ER      ref_sys ( T_RSYS *pk_rsys );
+ER      ref_cfg ( T_RCFG *pk_rcfg );
+#if 0 // NOT SUPPORTED
+ER      def_svc ( FN s_fncd, T_DSVC *pk_dsvc );
+ER      def_exc ( UINT exckind, T_DEXC *pk_dexc );
+#endif
+        
+// - Network Support Functions
+        
+#if 0 // NOT SUPPORTED
+ER      nrea_dat ( INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr,
+               INT datsz );
+ER      nwri_dat ( INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr,
+               INT datsz );
+ER      nget_nod ( NODE *p_node );
+ER      nget_ver ( T_VER *pk_ver, NODE node );
+#endif
+
+CYG_UIT_FUNC_EXTERN_END
+
+// ========================================================================
+
+#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+// functions are inline OR we are in the outline implementation, so define
+// the functions as inlines or plain functions depending on the value of
+// CYG_UIT_FUNC_INLINE from above.
+#include <cyg/compat/uitron/uit_func.inl>
+#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+// ------------------------------------------------------------------------
+#endif // CYGPKG_UITRON
+
+#endif // CYGONCE_COMPAT_UITRON_UIT_FUNC_H
+// EOF uit_func.h
diff --git a/packages/compat/uitron/v2_0/include/uit_func.inl b/packages/compat/uitron/v2_0/include/uit_func.inl
new file mode 100644 (file)
index 0000000..e4413a7
--- /dev/null
@@ -0,0 +1,1950 @@
+#ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
+#define CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
+//===========================================================================
+//
+//      uit_func.inl
+//
+//      uITRON compatibility functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON compatibility functions
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#ifdef CYGPKG_UITRON
+
+#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+#include <cyg/compat/uitron/uit_objs.hxx> // uITRON setup CYGNUM_UITRON_SEMAS
+
+// kernel facilities only needed here
+#include <cyg/kernel/intr.hxx>
+#include <cyg/kernel/sched.hxx>
+
+// and the implementations of other kernel facilities
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/clock.inl>
+
+
+// ------------------------------------------------------------------------
+// The variable where dis_dsp/ena_dsp state is held:
+extern cyg_uint32 cyg_uitron_dis_dsp_old_priority;
+
+// ------------------------------------------------------------------------
+// Parameter checking; either check the expression and return an error code
+// if not true, or assert the truth with a made-up message.
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+// default: uitron error codes are returned
+#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START           \
+    if ( ! (_true_) ) return (_error_);                                 \
+CYG_MACRO_END
+#else
+// ...but they are asserted if asserts are on
+#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START           \
+    CYG_ASSERT( (_true_), "CYG_UIT_PARAMCHECK fail: " #_true_ );        \
+CYG_MACRO_END
+#endif // else !CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+
+// ------------------------------------------------------------------------
+// CYG_UITRON_CHECK_AND_GETP
+// 
+// Macro to rangecheck and do the addressing of a static uitron system
+// object; _which_ sort of object is given, and token pasting is used
+// horribly to get the static array, limits and the like.
+//
+// Usage:
+//   INT snd_msg( ID mbxid, ... ) {
+//      Cyg_Mbox *p;
+//      CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+//      p->...(...);
+
+// internal: plain assignment to the object pointer, from static array
+#define CYG_UIT_SPTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START           \
+        (_ptr_) =  CYG_UITRON_OBJS( _which_ ) + ((_idx_) - 1);          \
+CYG_MACRO_END
+
+// internal: plain assignment to the object pointer, from pointer array
+// with error checking.
+#define CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START       \
+        (_ptr_) =  CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ];         \
+        if ( NULL == (_ptr_) ) return E_NOEXS;                          \
+CYG_MACRO_END
+
+#define CYG_UITRON_CHECK_AND_GETP_DIRECT( _which_, _idx_, _ptr_ )       \
+CYG_MACRO_START                                                         \
+    CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \
+    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \
+    CYG_UIT_SPTR( _which_, _idx_, _ptr_ );                              \
+CYG_MACRO_END
+
+#define CYG_UITRON_CHECK_AND_GETP_INDIRECT( _which_, _idx_, _ptr_ )     \
+CYG_MACRO_START                                                         \
+    CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \
+    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \
+    CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ );                          \
+CYG_MACRO_END
+
+// As above but for handler numbers which return E_PAR when out of range
+#define CYG_UITRON_CHECK_AND_GETHDLR( _which_, _num_, _ptr_ )           \
+CYG_MACRO_START                                                         \
+    CYG_UIT_PARAMCHECK( 0 < (_num_), E_PAR );                           \
+    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_num_), E_PAR );  \
+    CYG_UIT_SPTR( _which_, _num_, _ptr_ );                              \
+CYG_MACRO_END
+
+// And a macro to check that creation of an object is OK
+#define CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( _which_, _idx_ )            \
+CYG_MACRO_START                                                         \
+    CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \
+    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \
+    Cyg_Scheduler::lock();                                              \
+    if ( NULL != CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ] ) {        \
+        Cyg_Scheduler::unlock();                                        \
+        return E_OBJ;                                                   \
+    }                                                                   \
+CYG_MACRO_END
+
+// define a magic new operator in order to call constructors
+#define CYG_UITRON_NEWFUNCTION( _class_ )                               \
+inline void *operator new(size_t size, _class_ *ptr)                    \
+{                                                                       \
+    CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );                           \
+    return ptr;                                                         \
+}
+
+// now configury to support selectable create/delete support ie. an
+// array of pointers to the objects themselves.
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ )                 \
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( TASKS, _idx_, _ptr_ )
+#else
+#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ )                 \
+    CYG_UITRON_CHECK_AND_GETP_DIRECT( TASKS, _idx_, _ptr_ )
+#endif
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ )                 \
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( SEMAS, _idx_, _ptr_ )
+#else
+#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ )                 \
+    CYG_UITRON_CHECK_AND_GETP_DIRECT( SEMAS, _idx_, _ptr_ )
+#endif
+
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ )                \
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MBOXES, _idx_, _ptr_ )
+#else
+#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ )                \
+    CYG_UITRON_CHECK_AND_GETP_DIRECT( MBOXES, _idx_, _ptr_ )
+#endif
+
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ )                 \
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( FLAGS, _idx_, _ptr_ )
+#else
+#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ )                 \
+    CYG_UITRON_CHECK_AND_GETP_DIRECT( FLAGS, _idx_, _ptr_ )
+#endif
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ )          \
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
+#else
+#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ )          \
+    CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
+#endif
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ )            \
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLVAR, _idx_, _ptr_ )
+#else
+#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ )            \
+    CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLVAR, _idx_, _ptr_ )
+#endif
+
+// ------------------------------------------------------------------------
+// Common error checking macros
+
+#if !defined( CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS ) && \
+    !defined( CYGDBG_USE_ASSERTS )
+// if not checking and not asserted, these are removed to avoid usused
+// variable warnings.
+#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ )     CYG_EMPTY_STATEMENT
+#define CYG_UITRON_CHECK_TASK_CONTEXT()                  CYG_EMPTY_STATEMENT
+#define CYG_UITRON_CHECK_DISPATCH_ENABLED()              CYG_EMPTY_STATEMENT
+#define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( _tmout_ ) CYG_EMPTY_STATEMENT
+
+#else
+// the default:
+// Check a task is actually a uITRON task
+#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_MACRO_START    \
+    CYG_UIT_PARAMCHECK(                                                 \
+        (&cyg_uitron_TASKS[0] <= (_self_)) &&                           \
+        ((_self_) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]),            \
+                                  E_CTX );                              \
+CYG_MACRO_END
+
+#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_MACRO_START                 \
+    Cyg_Thread *self = Cyg_Thread::self();                              \
+    CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );                         \
+CYG_MACRO_END
+
+// Check dispatching is enabled for calls which might wait
+#define CYG_UITRON_CHECK_DISPATCH_ENABLED()  CYG_MACRO_START            \
+    CYG_UIT_PARAMCHECK( 0 == cyg_uitron_dis_dsp_old_priority, E_CTX );  \
+CYG_MACRO_END
+
+#define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO(_tmout_)  CYG_MACRO_START \
+    CYG_UIT_PARAMCHECK( -1 <= (_tmout_), E_PAR );                       \
+    if ( TMO_POL != (_tmout_) )                                         \
+        CYG_UITRON_CHECK_DISPATCH_ENABLED();                            \
+CYG_MACRO_END
+
+#endif
+
+#ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+#define CYG_UIT_PARAMCHECK_PTR( _p_ )   CYG_MACRO_START                 \
+        CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR );                     \
+CYG_MACRO_END
+#else // do check for NULL
+#define CYG_UIT_PARAMCHECK_PTR( _p_ )   CYG_MACRO_START                 \
+        CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR );                     \
+        CYG_UIT_PARAMCHECK( NULL != (_p_), E_PAR );                     \
+CYG_MACRO_END
+#endif // !CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+
+// ------------------------------------------------------------------------
+// CYG_UITRON_FAIL_RETURN
+//
+// After a call which waits, it might return with success, or due to a
+// timeout or a release wait (a forced escape from the waiting condition).
+// This macro examines context and finds out which, then executes a return
+// with the correct uITRON condition code.
+
+#define CYG_UITRON_FAIL_RETURN_SELF( _self_ ) CYG_MACRO_START           \
+    Cyg_Thread::cyg_reason reason = (_self_)->get_wake_reason();        \
+    if ( Cyg_Thread::TIMEOUT  == reason )                               \
+        return E_TMOUT;                                                 \
+    if ( Cyg_Thread::BREAK    == reason )                               \
+        return E_RLWAI;                                                 \
+    if ( Cyg_Thread::DESTRUCT == reason )                               \
+        return E_DLT;                                                   \
+    return E_SYS; /* if no plausible reason was found */                \
+CYG_MACRO_END
+
+#define CYG_UITRON_FAIL_RETURN() CYG_MACRO_START                        \
+    Cyg_Thread *self = Cyg_Thread::self();                              \
+    CYG_UITRON_FAIL_RETURN_SELF( self );                                \
+CYG_MACRO_END
+
+// ------------------------------------------------------------------------
+// Interrupts disabled?
+#define CYG_UITRON_CHECK_CPU_UNLOC()                                    \
+    CYG_UIT_PARAMCHECK( (Cyg_Interrupt::interrupts_enabled()), E_CTX )
+
+// ------------------------------------------------------------------------
+// Timing: is it in eCos clock ticks or milliSeconds (or something else?)
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+
+#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
+extern Cyg_Clock::converter uit_clock_to_system;
+extern Cyg_Clock::converter uit_clock_from_system;
+
+#define CYG_UITRON_TIME_UIT_TO_SYS32( t ) \
+Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_to_system )
+
+#define CYG_UITRON_TIME_SYS_TO_UIT32( t ) \
+Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_from_system )
+
+// long (cyg_uint64) versions:
+#define CYG_UITRON_TIME_UIT_TO_SYS64( t ) \
+Cyg_Clock::convert( (t), &uit_clock_to_system )
+
+#define CYG_UITRON_TIME_SYS_TO_UIT64( t ) \
+Cyg_Clock::convert( (t), &uit_clock_from_system )
+
+#else // Time is whatever the system clock is doing:
+
+// Straight through - int (cyg_int32) argument versions:
+#define CYG_UITRON_TIME_UIT_TO_SYS32( t )  ( t )
+#define CYG_UITRON_TIME_SYS_TO_UIT32( t )  ( t )
+// long (cyg_uint64) versions:
+#define CYG_UITRON_TIME_UIT_TO_SYS64( t )  ( t )
+#define CYG_UITRON_TIME_SYS_TO_UIT64( t )  ( t )
+#endif
+
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK - otherwise these should not be used.
+
+// ------------------------------------------------------------------------
+// the function definitions themselves:
+
+// ******************************************************
+// ***    6.5 C Language Interfaces                   ***
+// ******************************************************
+
+// - Task Management Functions
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+CYG_UITRON_NEWFUNCTION( Cyg_Thread )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_tsk ( ID tskid, T_CTSK *pk_ctsk )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_ctsk );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( TASKS, tskid );
+
+    Cyg_Thread *p = &(CYG_UITRON_OBJS( TASKS )[ tskid - 1 ]);
+    cyg_uint32 state = p->get_state();
+    if ( 0 == (state & Cyg_Thread::EXITED) )
+        ret = E_OBJ; // how did it get to be running?
+    else if ( ((INT)p->get_stack_size()) < pk_ctsk->stksz )
+        ret = E_NOMEM; // more stack requested than available
+    else {
+        CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] =
+            new( p ) Cyg_Thread(
+                (CYG_ADDRWORD)      pk_ctsk->itskpri,
+                (cyg_thread_entry *)pk_ctsk->task,
+                (CYG_ADDRWORD)      0,
+                // preserve the original name and stack:
+#ifdef CYGVAR_KERNEL_THREADS_NAME
+                p->get_name(),
+#else
+                NULL,
+#endif
+                p->get_stack_base(),
+                p->get_stack_size() );
+        // but ensure the task state is dormant:
+        // (it is not constructed dormant, but suspended)
+        p->kill();
+#ifdef CYGIMP_THREAD_PRIORITY
+        // and record the initial priority outside the task too.
+        CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) = pk_ctsk->itskpri;
+#endif
+    }
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_tsk ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_NOEXS;
+    }
+    cyg_uint32 state = p->get_state();
+    if ( state & Cyg_Thread::EXITED )
+        // just disconnect the pointer from its object
+        CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
+    else
+        ret = E_OBJ;
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+#endif // CYGPKG_UITRON_TASKS_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+sta_tsk ( ID tskid, INT stacd )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    
+    Cyg_Scheduler::lock();
+    cyg_uint32 state = p->get_state();
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+    // there is a race condition with deleting the task
+    // so test it now that we have the scheduler locked
+    if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] )
+        ret = E_NOEXS;
+    else // NOTE dangling else to the next line:
+#endif
+    if ( state & Cyg_Thread::EXITED ) {
+        p->reinitialize();
+#ifdef CYGIMP_THREAD_PRIORITY
+        p->set_priority( CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) );
+#endif
+        p->set_entry_data( (CYG_ADDRWORD)stacd );
+        p->force_resume();
+    }
+    else
+        ret = E_OBJ;
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+void
+ext_tsk ( void )
+{    
+    Cyg_Thread::exit();
+}
+
+CYG_UIT_FUNC_INLINE
+void
+exd_tsk ( void )
+{
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+    Cyg_Thread *p;
+
+    Cyg_Scheduler::lock();
+    p = Cyg_Thread::self();
+    ID tskid = (p - (&cyg_uitron_TASKS[0])) + 1;    
+    // just disconnect the pointer from its object
+    CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
+    // Any associated storage management, and possibly calling the task
+    // destructor, is for future versions.
+#else
+    // do nothing - deletion not supported so just exit...
+#endif
+    Cyg_Thread::exit();
+    // does not return, does unlock the scheduler for us
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ter_tsk ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
+    Cyg_Scheduler::lock();
+    if ( (0 != (Cyg_Thread::EXITED & p->get_state())) ||
+         (Cyg_Thread::EXIT == p->get_wake_reason()) )
+        // already dormant
+        ret = E_OBJ;
+    else {
+        p->force_resume(); // let it run
+        p->kill(); // and set prio high so it runs RIGHT NOW!!
+#ifdef CYGIMP_THREAD_PRIORITY
+#if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES != 0
+        // see if we are already at prio 0:
+        if ( 0 == cyg_uitron_dis_dsp_old_priority )
+            // then dispatch is enabled, we are not at prio 0
+#endif
+            p->set_priority( (cyg_priority) 0 );
+        // if we do not do this, then we are not running a strictly
+        // uITRON compatible scheduler - so just hope for the best.
+#endif
+    }
+    Cyg_Scheduler::unlock();
+#ifdef CYGIMP_THREAD_PRIORITY
+#if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES == 0
+    if ( (E_OK == ret) && (0 != cyg_uitron_dis_dsp_old_priority) ) {
+        // then dispatching is disabled, so our prio is 0 too
+        Cyg_Thread::yield(); // so let the dying thread run;
+        Cyg_Thread::yield(); // no cost here of making sure.
+    }
+#endif
+#endif
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+dis_dsp ( void )
+{
+    CYG_UITRON_CHECK_TASK_CONTEXT();
+    CYG_UITRON_CHECK_CPU_UNLOC();
+    Cyg_Scheduler::lock();
+    // Prevent preemption by going up to prio 0
+    if ( 0 == cyg_uitron_dis_dsp_old_priority ) {
+#ifdef CYGIMP_THREAD_PRIORITY
+        Cyg_Thread *p = Cyg_Thread::self();
+        cyg_uitron_dis_dsp_old_priority = p->get_priority();
+        p->set_priority( 0 );
+#else
+        cyg_uitron_dis_dsp_old_priority = 1;
+#endif
+    }
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ena_dsp ( void )
+{
+    CYG_UITRON_CHECK_TASK_CONTEXT();
+    CYG_UITRON_CHECK_CPU_UNLOC();
+    Cyg_Scheduler::lock();
+    // Enable dispatching (if disabled) and maybe switch threads
+    if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
+        // We had prevented preemption by going up to prio 0
+#ifdef CYGIMP_THREAD_PRIORITY
+        Cyg_Thread *p = Cyg_Thread::self();
+        p->set_priority( cyg_uitron_dis_dsp_old_priority );
+        p->to_queue_head(); // to ensure we continue to run
+                            // if nobody higher pri
+#endif
+        cyg_uitron_dis_dsp_old_priority = 0;
+    }
+    Cyg_Scheduler::unlock();
+    CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards!
+    return E_OK;
+}
+
+
+CYG_UIT_FUNC_INLINE
+ER
+chg_pri ( ID tskid, PRI tskpri )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    if ( 0 == tskid ) {
+        p = Cyg_Thread::self();
+        CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
+    }
+    else
+        CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+
+#ifdef CYGIMP_THREAD_PRIORITY
+    if ( 0 == tskpri )
+        // then use the initial priority [Level X]
+        tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
+#endif
+    CYG_UIT_PARAMCHECK( 0 < tskpri, E_PAR );
+#ifdef CYGIMP_THREAD_PRIORITY
+#if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
+    CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
+                        tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
+#else    
+    CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
+                        tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
+#endif
+    // Handle changing our own prio specially, if dispatch disabled:
+    if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
+        // our actual prio is 0 now and must remain so:
+        if ( Cyg_Thread::self() == p ) {  // by whichever route p was set
+            // set the priority we will return to when dispatch is enabled:
+            cyg_uitron_dis_dsp_old_priority = (cyg_uint32)tskpri;
+            return E_OK;
+        }
+    }
+    Cyg_Scheduler::lock();
+    if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
+         (Cyg_Thread::EXIT == p->get_wake_reason()) )
+        ret = E_OBJ; // task is dormant
+    else
+        p->set_priority( (cyg_priority)tskpri );
+    Cyg_Scheduler::unlock();
+#endif // CYGIMP_THREAD_PRIORITY got priorities at all?
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+rot_rdq ( PRI tskpri )
+{
+    // zero means our level; easiet way is to yield() the CPU.
+    if ( 0 == tskpri ) {
+        Cyg_Thread::yield();
+        return E_OK;
+    }
+#ifdef CYGIMP_THREAD_PRIORITY
+#if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
+    CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
+                        tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
+#else    
+    CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
+                        tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
+#endif
+    Cyg_Thread::rotate_queue( tskpri );
+#endif // CYGIMP_THREAD_PRIORITY got priorities at all?
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+rel_wai ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
+    Cyg_Scheduler::lock();              // get an atomic view of the task
+    if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
+         (Cyg_Thread::EXIT == p->get_wake_reason()) )
+        ret = E_OBJ;                    // task is dormant
+    else {
+        p->release();
+        // return E_OBJ if the thread was not sleeping
+        if ( Cyg_Thread::BREAK != p->get_wake_reason() )
+            ret = E_OBJ;
+    }
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+get_tid ( ID *p_tskid )
+{
+    Cyg_Thread *self = Cyg_Thread::self();
+    CYG_UIT_PARAMCHECK_PTR( p_tskid );
+    if ( (&cyg_uitron_TASKS[0] <= (self)) &&
+        ((self) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]) &&
+        (0 == Cyg_Scheduler::get_sched_lock()) )
+        // then I am a uITRON task and not in an interrupt or DSR
+        *p_tskid = (self - (&cyg_uitron_TASKS[0])) + 1;
+    else
+        *p_tskid = 0; // Otherwise, non-task portion
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_tsk ( T_RTSK *pk_rtsk, ID tskid )
+{
+    Cyg_Thread *p;
+    if ( 0 == tskid ) {
+        p = Cyg_Thread::self();
+        CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
+        tskid = (p - (&cyg_uitron_TASKS[0])) + 1; // it gets used below
+    }
+    else
+        CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+
+    CYG_UIT_PARAMCHECK_PTR( pk_rtsk );
+    pk_rtsk->exinf  = NADR;
+    Cyg_Scheduler::lock();              // get an atomic view of the task
+    cyg_uint32 state = p->get_state();
+    if ( (state & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
+         (Cyg_Thread::EXIT == p->get_wake_reason()) )
+        pk_rtsk->tskstat = TTS_DMT;
+    else if ( state == Cyg_Thread::RUNNING )
+        // If it's us, it's running, else it's ready
+        pk_rtsk->tskstat = (Cyg_Thread::self() == p)
+            ? TTS_RUN                   // RUN state (we are it)
+            : TTS_RDY;                  // READY state
+    else if ( state & Cyg_Thread::SUSPENDED )
+        pk_rtsk->tskstat =
+            (state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
+            ? TTS_WAS                   // WAIT-SUSPEND state
+            : TTS_SUS;                  // SUSPEND state
+    else
+        pk_rtsk->tskstat =
+            (state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
+            ? TTS_WAI                   // WAIT state
+            : 0;                        // Not sure what's happening here!
+#ifdef CYGIMP_THREAD_PRIORITY
+    if ( TTS_DMT == pk_rtsk->tskstat )
+        pk_rtsk->tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
+    else if ( (TTS_RUN == pk_rtsk->tskstat) && 
+              (0 != cyg_uitron_dis_dsp_old_priority) )
+        // then we are it and dispatching is disabled, so
+        // report our "real" priority - it is 0 in the kernel at the moment
+        pk_rtsk->tskpri = cyg_uitron_dis_dsp_old_priority;
+    else
+        pk_rtsk->tskpri = p->get_priority();
+#else
+    pk_rtsk->tskpri = -1;  // Not applicable
+#endif
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+        
+// - Task-Dependent Synchronization Functions
+        
+CYG_UIT_FUNC_INLINE
+ER
+sus_tsk ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
+    Cyg_Scheduler::lock();              // get an atomic view of the task
+    if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
+         (Cyg_Thread::EXIT == p->get_wake_reason()) )
+        ret = E_OBJ;                    // task is dormant
+    else
+        p->suspend();
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+rsm_tsk ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
+    Cyg_Scheduler::lock();              // get an atomic view of the task
+    cyg_uint32 state = p->get_state();
+    if ( 0 == (Cyg_Thread::SUSPENDED & state) )
+        ret = E_OBJ;                    // thread is not suspended
+    else
+        p->resume();
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+frsm_tsk ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
+    Cyg_Scheduler::lock();              // get an atomic view of the task
+    cyg_uint32 state = p->get_state();
+    if ( 0 == (Cyg_Thread::SUSPENDED & state) )
+        ret = E_OBJ;                    // thread is not suspended
+    else
+        p->force_resume();
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+slp_tsk ( void )
+{
+    Cyg_Thread *self = Cyg_Thread::self();
+    CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    // do this now for the case when no sleeping actually occurs
+    self->set_wake_reason( Cyg_Thread::DONE );
+    Cyg_Thread::counted_sleep();
+    if ( Cyg_Thread::DONE != self->get_wake_reason() )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+tslp_tsk ( TMO tmout )
+{
+    Cyg_Thread *self = Cyg_Thread::self();
+    CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
+    CYG_UIT_PARAMCHECK( -1 <= tmout, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    // do this now for the case when no sleeping actually occurs
+    self->set_wake_reason( Cyg_Thread::DONE );
+    // note that TMO_POL is not treated specially, though it
+    // happens to work almost as a poll (some sleeping may occur)
+    if ( TMO_FEVR == tmout )
+        Cyg_Thread::counted_sleep();
+    else
+        Cyg_Thread::counted_sleep(
+            (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
+    if ( Cyg_Thread::DONE != self->get_wake_reason() )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+wup_tsk ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
+    Cyg_Scheduler::lock();              // get an atomic view of the task
+    if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
+         (Cyg_Thread::EXIT == p->get_wake_reason()) )
+        ret = E_OBJ;                    // task is dormant
+    else
+        p->counted_wake();
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+can_wup ( INT *p_wupcnt, ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    if ( 0 == tskid ) {
+        p = Cyg_Thread::self();
+        CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
+    }
+    else
+        CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_wupcnt );
+    Cyg_Scheduler::lock();              // get an atomic view of the task
+    if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
+         (Cyg_Thread::EXIT == p->get_wake_reason()) )
+        ret = E_OBJ;                    // task is dormant
+    else {
+        cyg_uint32 result = p->cancel_counted_wake();
+        *p_wupcnt = result;
+    }
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+        
+// - Synchronization and Communication Functions
+        
+#ifdef CYGPKG_UITRON_SEMAS
+#if 0 < CYG_UITRON_NUM( SEMAS )
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Counting_Semaphore2 )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_sem ( ID semid, T_CSEM *pk_csem )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_csem );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( SEMAS, semid );
+    if ( TA_TFIFO != pk_csem->sematr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] =
+            new( &(CYG_UITRON_OBJS( SEMAS )[ semid - 1 ]) )
+            Cyg_Counting_Semaphore2( (cyg_count32)pk_csem->isemcnt );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_sem ( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_NOEXS;
+    }
+    CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] = NULL;
+    p->~Cyg_Counting_Semaphore2();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+sig_sem( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    p->post();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+wai_sem( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    cyg_bool result = p->wait();
+    if ( !result )
+        CYG_UITRON_FAIL_RETURN();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+preq_sem ( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    cyg_bool result = p->trywait();
+    if ( !result )
+        return E_TMOUT;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+twai_sem ( ID semid, TMO tmout )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    cyg_bool result;
+    if ( TMO_FEVR == tmout )
+        result = p->wait();
+    else if ( TMO_POL == tmout )
+        result = p->trywait();
+    else
+        result = p->wait(
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    return E_OK;
+
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_sem ( T_RSEM *pk_rsem, ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rsem );
+    pk_rsem->exinf  = NADR;
+    pk_rsem->wtsk   = p->waiting();
+    pk_rsem->semcnt = p->peek();
+    return E_OK;
+}
+
+#endif // 0 < CYG_UITRON_NUM( SEMAS )
+#endif // CYGPKG_UITRON_SEMAS
+
+#ifdef CYGPKG_UITRON_FLAGS
+#if 0 < CYG_UITRON_NUM( FLAGS )
+
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Flag )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_flg ( ID flgid, T_CFLG *pk_cflg )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cflg );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( FLAGS, flgid );
+    if ( 0 != ((~(TA_WMUL | TA_WSGL)) & pk_cflg->flgatr) )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] =
+            new( &(CYG_UITRON_OBJS( FLAGS )[ flgid - 1 ]) )
+            Cyg_Flag( (Cyg_FlagValue) pk_cflg->iflgptn );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_flg ( ID flgid )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_NOEXS;
+    }
+    CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] = NULL;
+    p->~Cyg_Flag();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+set_flg ( ID flgid, UINT setptn )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    p->setbits( setptn );
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+clr_flg ( ID flgid, UINT clrptn )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    p->maskbits( clrptn );
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+wai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_flgptn );
+    CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    // check we can use the wfmode value unchanged
+    CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
+    CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
+    CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
+
+    UINT result = p->wait( waiptn, wfmode );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    *p_flgptn  = result;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+pol_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_flgptn );
+    CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
+    // check we can use the wfmode value unchanged
+    CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
+    CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
+    CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
+
+    UINT result = p->poll( waiptn, wfmode );
+    if ( ! result )
+        return E_TMOUT;
+    *p_flgptn  = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+twai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode,
+              TMO tmout )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_flgptn );
+    CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // check we can use the wfmode value unchanged
+    CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
+    CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
+    CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
+
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    UINT result;
+    if ( TMO_FEVR == tmout )
+        result = p->wait( waiptn, wfmode );
+    else if ( TMO_POL == tmout )
+        result = p->poll( waiptn, wfmode );
+    else
+        result = p->wait( waiptn, wfmode,
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    *p_flgptn  = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_flg ( T_RFLG *pk_rflg, ID flgid )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rflg );
+    pk_rflg->exinf  = NADR;
+    pk_rflg->wtsk   = p->waiting();
+    pk_rflg->flgptn = p->peek();
+    return E_OK;
+}
+
+#endif // 0 < CYG_UITRON_NUM( FLAGS )
+#endif // CYGPKG_UITRON_FLAGS
+
+#ifdef CYGPKG_UITRON_MBOXES
+#if 0 < CYG_UITRON_NUM( MBOXES )
+
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+CYG_UITRON_NEWFUNCTION( Cyg_Mbox )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_mbx ( ID mbxid, T_CMBX* pk_cmbx )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cmbx );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MBOXES, mbxid );
+    if ( ((ATR)(TA_TFIFO + TA_MFIFO)) != pk_cmbx->mbxatr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] =
+            new( &(CYG_UITRON_OBJS( MBOXES )[ mbxid - 1 ]) )
+            Cyg_Mbox();
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_mbx ( ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_NOEXS;
+    }
+    CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] = NULL;
+    p->~Cyg_Mbox();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
+
+// This bit of unpleasantness is to allow uITRON programs to send a NULL
+// message - if permitted by the parameter checking.
+// 
+// NULL is used internally to mean no message; but -1 is fine.  So we send
+// a NULL as a NADR and if we see a NULL coming back, change it to a NADR.
+//
+// One hopes that often this will be optimized out, since the one or both
+// of these being true has been detected and errored out just above.
+
+#ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+// represent a NULL as NADR internally
+#define CYG_UIT_TMSG_FIXUP_IN( _p_ )    CYG_MACRO_START                 \
+    if ( NULL == (_p_) )                                                \
+        (_p_) = (T_MSG *)NADR;                                          \
+CYG_MACRO_END
+
+// we get a NADR back sometimes, meaning NULL
+#define CYG_UIT_TMSG_FIXUP_OUT( _p_ )   CYG_MACRO_START                 \
+    if ( NADR == (_p_) )                                                \
+        (_p_) = (T_MSG *)NULL;                                          \
+CYG_MACRO_END
+
+#else
+// NULL is checked for and makes an error
+#define CYG_UIT_TMSG_FIXUP_IN( _p_ )    CYG_EMPTY_STATEMENT
+#define CYG_UIT_TMSG_FIXUP_OUT( _p_ )   CYG_EMPTY_STATEMENT
+#endif
+
+// and sometimes either in status enquiries
+#define CYG_UIT_TMSG_FIXUP_ALL( _p_ )   CYG_MACRO_START                 \
+    if ( NULL == (_p_) )                                                \
+        (_p_) = (T_MSG *)NADR;                                          \
+    else if ( NADR == (_p_) )                                           \
+        (_p_) = (T_MSG *)NULL;                                          \
+CYG_MACRO_END
+
+CYG_UIT_FUNC_INLINE
+ER
+snd_msg ( ID mbxid, T_MSG *pk_msg )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_msg );
+    CYG_UIT_TMSG_FIXUP_IN( pk_msg );
+    cyg_bool result = p->tryput( (void *)pk_msg );
+    if ( ! result )
+        return E_QOVR;
+    return E_OK;
+}
+
+
+CYG_UIT_FUNC_INLINE
+ER
+rcv_msg ( T_MSG **ppk_msg, ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( ppk_msg );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    T_MSG *result = (T_MSG *)p->get();
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    CYG_UIT_TMSG_FIXUP_OUT( result );
+    *ppk_msg = result;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+prcv_msg ( T_MSG **ppk_msg, ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( ppk_msg );
+    T_MSG *result = (T_MSG *)p->tryget();
+    if ( ! result )
+        return E_TMOUT;
+    CYG_UIT_TMSG_FIXUP_OUT( result );
+    *ppk_msg = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+trcv_msg ( T_MSG **ppk_msg, ID mbxid, TMO tmout )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( ppk_msg );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    T_MSG *result;
+    if ( TMO_FEVR == tmout )
+        result = (T_MSG *)p->get();
+    else if ( TMO_POL == tmout )
+        result = (T_MSG *)p->tryget();
+    else
+        result = (T_MSG *)p->get(
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    CYG_UIT_TMSG_FIXUP_OUT( result );
+    *ppk_msg = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_mbx ( T_RMBX *pk_rmbx, ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rmbx );
+    pk_rmbx->exinf  = NADR;
+    pk_rmbx->wtsk   = p->waiting_to_get();
+    pk_rmbx->pk_msg = (T_MSG *)p->peek_item();
+    CYG_UIT_TMSG_FIXUP_ALL( pk_rmbx->pk_msg );
+    return E_OK;
+}
+
+#undef CYG_UIT_TMSG_FIXUP_IN
+#undef CYG_UIT_TMSG_FIXUP_OUT
+#undef CYG_UIT_TMSG_FIXUP_ALL
+        
+#endif // 0 < CYG_UITRON_NUM( MBOXES )
+#endif // CYGPKG_UITRON_MBOXES
+
+// - Extended Synchronization and Communication Functions
+        
+#if 0 // NOT SUPPORTED
+ER      cre_mbf ( ID mbfid, T_CMBF *pk_cmbf );
+ER      del_mbf ( ID mbfid );
+ER      snd_mbf ( ID mbfid, VP msg, INT msgsz );
+ER      psnd_mbf ( ID mbfid, VP msg, INT msgsz );
+ER      tsnd_mbf ( ID mbfid, VP msg, INT msgsz, TMO tmout );
+ER      rcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
+ER      prcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
+ER      trcv_mbf ( VP msg, INT *p_msgsz, ID mbfid, TMO tmout );
+ER      ref_mbf ( T_RMBF *pk_rmbf, ID mbfid );
+ER      cre_por ( ID porid, T_CPOR *pk_cpor );
+ER      del_por ( ID porid );
+ER      cal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
+              cmsgsz );
+ER      pcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
+              cmsgsz );
+ER      tcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
+              cmsgsz, TMO tmout );
+ER      acp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
+              acpptn );
+ER      pacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
+              acpptn );
+ER      tacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
+              acpptn, TMO tmout );
+ER      fwd_por ( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz
+              );
+ER      rpl_rdv ( RNO rdvno, VP msg, INT rmsgsz );
+ER      ref_por ( T_RPOR *pk_rpor, ID porid );
+#endif
+        
+// - Interrupt Management Functions
+        
+#if 0 // NOT SUPPORTED
+ER      def_int ( UINT dintno, T_DINT *pk_dint );
+void    ret_wup ( ID tskid );
+#endif
+
+CYG_UIT_FUNC_INLINE
+ER
+loc_cpu ( void )
+{
+    CYG_UITRON_CHECK_TASK_CONTEXT();
+    Cyg_Scheduler::lock();
+    // Prevent preemption by going up to prio 0
+    if ( 0 == cyg_uitron_dis_dsp_old_priority ) {
+#ifdef CYGIMP_THREAD_PRIORITY
+        Cyg_Thread *p = Cyg_Thread::self();
+        cyg_uitron_dis_dsp_old_priority = p->get_priority();
+        p->set_priority( 0 );
+#else
+        cyg_uitron_dis_dsp_old_priority = 1;
+#endif
+    }
+    Cyg_Interrupt::disable_interrupts();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+unl_cpu ( void )
+{
+    CYG_UITRON_CHECK_TASK_CONTEXT();
+    Cyg_Scheduler::lock();
+    // Enable dispatching (if disabled) and maybe switch threads
+    if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
+        // We had prevented preemption by going up to prio 0
+#ifdef CYGIMP_THREAD_PRIORITY
+        Cyg_Thread *p = Cyg_Thread::self();
+        p->set_priority( cyg_uitron_dis_dsp_old_priority );
+#endif
+        cyg_uitron_dis_dsp_old_priority = 0;
+    }
+    Cyg_Interrupt::enable_interrupts();
+    Cyg_Scheduler::unlock();
+    CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards!
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+dis_int ( UINT eintno )
+{
+    CYG_INTERRUPT_STATE old_ints;
+    
+#if 0 < CYGNUM_HAL_ISR_MIN
+    CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MIN <= eintno, E_PAR );
+#endif
+    CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MAX >= eintno, E_PAR );
+    HAL_DISABLE_INTERRUPTS(old_ints);
+    HAL_INTERRUPT_MASK( eintno );
+    HAL_RESTORE_INTERRUPTS(old_ints);
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ena_int ( UINT eintno )
+{
+    CYG_INTERRUPT_STATE old_ints;
+
+#if 0 < CYGNUM_HAL_ISR_MIN
+    CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MIN <= eintno, E_PAR );
+#endif
+    CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MAX >= eintno, E_PAR );
+    HAL_DISABLE_INTERRUPTS(old_ints);
+    HAL_INTERRUPT_UNMASK( eintno );
+    HAL_RESTORE_INTERRUPTS(old_ints);
+    return E_OK;
+}
+
+#if 0 // NOT SUPPORTED
+ER      chg_iXX ( UINT iXXXX );
+ER      ref_iXX ( UINT *p_iXXXX );
+#endif
+        
+// - Memorypool Management Functions
+#ifdef CYGPKG_UITRON_MEMPOOLVAR
+#if 0 < CYG_UITRON_NUM( MEMPOOLVAR )
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Variable )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_mpl ( ID mplid, T_CMPL *pk_cmpl )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cmpl );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLVAR, mplid );
+    Cyg_Mempool_Variable *p = &(CYG_UITRON_OBJS( MEMPOOLVAR )[ mplid - 1 ]);
+    Cyg_Mempool_Status stat;
+
+    // preserve the original memory area to use
+    p->get_status( CYG_MEMPOOL_STAT_ORIGBASE|CYG_MEMPOOL_STAT_ORIGSIZE, stat );
+
+    if ( stat.origsize < pk_cmpl->mplsz )
+        ret = E_NOMEM;
+    else if ( TA_TFIFO != pk_cmpl->mplatr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] =
+            new( p ) Cyg_Mempool_Variable( 
+                const_cast<cyg_uint8 *>(stat.origbase), stat.origsize );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_mpl ( ID mplid )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_NOEXS;
+    }
+    CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] = NULL;
+    p->~Cyg_Mempool_Variable();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+get_blk ( VP *p_blk, ID mplid, INT blksz )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blk );
+    CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    VP result = (VP)p->alloc(blksz);
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    *p_blk = result;
+    return E_OK;
+}
+
+
+CYG_UIT_FUNC_INLINE
+ER
+pget_blk ( VP *p_blk, ID mplid, INT blksz )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blk );
+    CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
+    VP result = (VP)p->try_alloc(blksz);
+    if ( ! result )
+        return E_TMOUT;
+    *p_blk = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+tget_blk ( VP *p_blk, ID mplid, INT blksz, TMO tmout )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blk );
+    CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    VP result;
+    if ( TMO_FEVR == tmout )
+        result = p->alloc(blksz);
+    else if ( TMO_POL == tmout )
+        result = p->try_alloc(blksz);
+    else
+        result = p->alloc( blksz,
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    *p_blk = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+rel_blk ( ID mplid, VP blk )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( blk );
+    cyg_bool result = p->free( (cyg_uint8 *)blk );
+    if ( ! result )
+        return E_PAR;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_mpl ( T_RMPL *pk_rmpl, ID mplid )
+{
+    Cyg_Mempool_Variable *p;
+    Cyg_Mempool_Status stat;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rmpl );
+    p->get_status( CYG_MEMPOOL_STAT_WAITING|
+                   CYG_MEMPOOL_STAT_TOTALFREE|
+                   CYG_MEMPOOL_STAT_MAXFREE, stat );
+
+    pk_rmpl->exinf = NADR;
+    pk_rmpl->wtsk = stat.waiting;
+    pk_rmpl->frsz = stat.totalfree;
+    pk_rmpl->maxsz = stat.maxfree;
+
+    return E_OK;
+}
+
+#endif // 0 < CYG_UITRON_NUM( MEMPOOLVAR )
+#endif // CYGPKG_UITRON_MEMPOOLVAR
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED
+#if 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Fixed )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_mpf ( ID mpfid, T_CMPF *pk_cmpf )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cmpf );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLFIXED, mpfid );
+    Cyg_Mempool_Fixed *p = &(CYG_UITRON_OBJS( MEMPOOLFIXED )[ mpfid - 1 ]);
+    Cyg_Mempool_Status stat;
+
+    // preserve the original memory area to use
+    p->get_status( CYG_MEMPOOL_STAT_ORIGBASE|CYG_MEMPOOL_STAT_ORIGSIZE, stat );
+
+    if ( stat.origsize < (pk_cmpf->blfsz * (pk_cmpf->mpfcnt + 1)) )
+        ret = E_NOMEM;
+    else if ( TA_TFIFO != pk_cmpf->mpfatr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] =
+            new( p )
+            Cyg_Mempool_Fixed( const_cast<cyg_uint8 *>(stat.origbase),
+                               stat.origsize, (CYG_ADDRWORD)pk_cmpf->blfsz );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_mpf ( ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_NOEXS;
+    }
+    CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] = NULL;
+    p->~Cyg_Mempool_Fixed();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+get_blf ( VP *p_blf, ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blf );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    VP result = (VP)p->alloc();
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    *p_blf = result;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+pget_blf ( VP *p_blf, ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blf );
+    VP result = (VP)p->try_alloc();
+    if ( ! result )
+        return E_TMOUT;
+    *p_blf = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+tget_blf ( VP *p_blf, ID mpfid, TMO tmout )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blf );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    VP result;
+    if ( TMO_FEVR == tmout )
+        result = p->alloc();
+    else if ( TMO_POL == tmout )
+        result = p->try_alloc();
+    else
+        result = p->alloc(
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    *p_blf = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+rel_blf ( ID mpfid, VP blf )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( blf );
+    cyg_bool result = p->free( (cyg_uint8 *)blf );
+    if ( ! result )
+        return E_PAR;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_mpf ( T_RMPF *pk_rmpf, ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    Cyg_Mempool_Status stat;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rmpf );
+
+    p->get_status( CYG_MEMPOOL_STAT_WAITING|
+                   CYG_MEMPOOL_STAT_TOTALFREE|
+                   CYG_MEMPOOL_STAT_TOTALALLOCATED|
+                   CYG_MEMPOOL_STAT_BLOCKSIZE, stat );
+
+    pk_rmpf->exinf = NADR;
+    pk_rmpf->wtsk = stat.waiting;
+
+    pk_rmpf->frbcnt = stat.totalfree / stat.blocksize;
+    // these two are "implementation dependent" ie. eCos only
+    pk_rmpf->numbcnt = stat.totalallocated / stat.blocksize;
+    pk_rmpf->bsize = stat.blocksize;
+
+    return E_OK;
+}
+        
+#endif // 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
+#endif // CYGPKG_UITRON_MEMPOOLFIXED
+
+// - Time Management Functions
+        
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+CYG_UIT_FUNC_INLINE
+ER
+set_tim ( SYSTIME *pk_tim )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_tim );
+    Cyg_Clock::real_time_clock->set_value(
+        CYG_UITRON_TIME_UIT_TO_SYS64( *pk_tim ) );
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+get_tim ( SYSTIME *pk_tim )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_tim );
+    *pk_tim = CYG_UITRON_TIME_SYS_TO_UIT64(
+        Cyg_Clock::real_time_clock->current_value() );
+    return E_OK;
+}
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK
+
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+dly_tsk ( DLYTIME dlytim )
+{
+    CYG_UIT_PARAMCHECK( 0 <= dlytim, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    if ( 0 >= dlytim )
+        return E_OK;
+    Cyg_Thread *self = Cyg_Thread::self();
+    CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
+    self->delay( CYG_UITRON_TIME_UIT_TO_SYS64( dlytim ) );
+    if ( Cyg_Thread::DONE != self->get_wake_reason() )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+#ifdef CYGPKG_UITRON_CYCLICS
+#if 0 < CYG_UITRON_NUM( CYCLICS )
+CYG_UIT_FUNC_INLINE
+ER
+def_cyc ( HNO cycno, T_DCYC *pk_dcyc )
+{
+    // pk_dcyc->cycatr is ignored
+    // The only relevant attribute is TA_HLNG/TA_ASM.
+    // This can be ignored as assembler routines are defined to be
+    // more conservative with registers than the procedure call standard.
+    cyg_tick_count t;
+    Cyg_Timer *p;
+    CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    CYG_UIT_PARAMCHECK( NULL != pk_dcyc, E_PAR );
+#endif
+    if( NADR == pk_dcyc ) {
+        p->~Cyg_Timer();
+        return E_OK;
+    }
+    CYG_UIT_PARAMCHECK( 0 == (pk_dcyc->cycact & ~TCY_ON), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 < pk_dcyc->cyctim, E_PAR );
+    t = CYG_UITRON_TIME_UIT_TO_SYS64( pk_dcyc->cyctim );
+    p->initialize(
+        Cyg_Clock::real_time_clock,
+        (cyg_alarm_fn *)pk_dcyc->cychdr,
+        (CYG_ADDRWORD)pk_dcyc->exinf,
+        Cyg_Clock::real_time_clock->current_value() + t,
+        t,
+        pk_dcyc->cycact);
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+act_cyc ( HNO cycno, UINT cycact )
+{
+    Cyg_Timer *p;
+    CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
+    CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
+    CYG_UIT_PARAMCHECK( 0 == (cycact & ~(TCY_ON | TCY_INI)), E_PAR );
+    p->activate(cycact);
+    return E_OK;
+}
+
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_cyc ( T_RCYC *pk_rcyc, HNO cycno )
+{
+    Cyg_Timer *p;
+    cyg_tick_count t;
+    CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
+    CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
+    CYG_UIT_PARAMCHECK_PTR( pk_rcyc );
+
+    pk_rcyc->exinf = (VP)p->get_data();
+    Cyg_Scheduler::lock();
+    t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
+    Cyg_Scheduler::unlock();
+    pk_rcyc->lfttim = CYG_UITRON_TIME_SYS_TO_UIT64( t );
+    pk_rcyc->cycact = (UINT)p->is_enabled();
+    return E_OK;
+}
+#endif // 0 < CYG_UITRON_NUM( CYCLICS )
+#endif // CYGPKG_UITRON_CYCLICS
+
+#ifdef CYGPKG_UITRON_ALARMS
+#if 0 < CYG_UITRON_NUM( ALARMS )
+CYG_UIT_FUNC_INLINE
+ER
+def_alm ( HNO almno, T_DALM *pk_dalm )
+{
+    Cyg_Timer *p;
+    cyg_tick_count t, now;
+    CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    CYG_UIT_PARAMCHECK( NULL != pk_dalm, E_PAR );
+#endif
+    if( NADR == pk_dalm ) {
+        p->~Cyg_Timer();
+        return E_OK;
+    }
+
+    CYG_UIT_PARAMCHECK( 0 == (pk_dalm->tmmode & ~TTM_REL), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 < pk_dalm->almtim, E_PAR );
+
+    // make the time arithmetic safe without locking
+    now = Cyg_Clock::real_time_clock->current_value();
+    t = CYG_UITRON_TIME_UIT_TO_SYS64( pk_dalm->almtim );
+    if( TTM_REL & pk_dalm->tmmode )
+        t += now;
+
+    CYG_UIT_PARAMCHECK( now < t, E_PAR );
+
+    p->initialize(Cyg_Clock::real_time_clock,
+                  (cyg_alarm_fn *)pk_dalm->almhdr,
+                  (CYG_ADDRWORD)pk_dalm->exinf,
+                  t, 0, Cyg_Timer::ENABLE);
+
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_alm ( T_RALM *pk_ralm, HNO almno )
+{
+    Cyg_Timer *p;
+    cyg_tick_count t;
+
+    CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_ralm );
+    CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
+
+    Cyg_Scheduler::lock();
+    t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
+    Cyg_Scheduler::unlock();
+    pk_ralm->exinf  = (VP)p->get_data();
+    pk_ralm->lfttim = CYG_UITRON_TIME_SYS_TO_UIT64( t );
+    return E_OK;
+}
+#endif // 0 < CYG_UITRON_NUM( ALARMS )
+#endif // CYGPKG_UITRON_ALARMS
+
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK
+        
+// - System Management Functions
+        
+CYG_UIT_FUNC_INLINE
+ER
+get_ver ( T_VER *pk_ver )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_ver );
+
+    pk_ver->maker       = CYGNUM_UITRON_VER_MAKER;
+    pk_ver->id          = CYGNUM_UITRON_VER_ID;
+    pk_ver->spver       = CYGNUM_UITRON_VER_SPVER;
+    pk_ver->prver       = CYGNUM_UITRON_VER_PRVER;
+    pk_ver->prno[0]     = CYGNUM_UITRON_VER_PRNO_0;
+    pk_ver->prno[1]     = CYGNUM_UITRON_VER_PRNO_1;
+    pk_ver->prno[2]     = CYGNUM_UITRON_VER_PRNO_2;
+    pk_ver->prno[3]     = CYGNUM_UITRON_VER_PRNO_3;
+    pk_ver->cpu         = CYGNUM_UITRON_VER_CPU;
+    pk_ver->var         = CYGNUM_UITRON_VER_VAR;
+   
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_sys ( T_RSYS *pk_rsys )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_rsys );
+    if ( ! Cyg_Interrupt::interrupts_enabled() )
+        // CPU is locked
+        pk_rsys->sysstat = TSS_LOC;
+    else
+        pk_rsys->sysstat =
+            (0 == cyg_uitron_dis_dsp_old_priority) ? TSS_TSK : TSS_DDSP;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_cfg ( T_RCFG *pk_rcfg )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_rcfg );
+    // no details here yet
+    return E_OK;
+}
+
+#if 0 // NOT SUPPORTED
+ER      def_svc ( FN s_fncd, T_DSVC *pk_dsvc );
+ER      def_exc ( UINT exckind, T_DEXC *pk_dexc );
+#endif
+        
+// - Network Support Functions
+        
+#if 0 // NOT SUPPORTED
+ER      nrea_dat ( INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr,
+               INT datsz );
+ER      nwri_dat ( INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr,
+               INT datsz );
+ER      nget_nod ( NODE *p_node );
+ER      nget_ver ( T_VER *pk_ver, NODE node );
+#endif
+
+// ========================================================================
+
+#endif // CYGPKG_UITRON
+
+#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+#endif // CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
+//EOF uit_func.inl
diff --git a/packages/compat/uitron/v2_0/include/uit_ifnc.h b/packages/compat/uitron/v2_0/include/uit_ifnc.h
new file mode 100644 (file)
index 0000000..d558b47
--- /dev/null
@@ -0,0 +1,182 @@
+#ifndef CYGONCE_COMPAT_UITRON_UIT_IFNC_H
+#define CYGONCE_COMPAT_UITRON_UIT_IFNC_H
+//===========================================================================
+//
+//      uit_ifnc.h
+//
+//      uITRON compatibility functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1999-08-16
+// Purpose:     uITRON compatibility functions
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+// ------------------------------------------------------------------------
+// Source Code Organization
+//
+// First, see pkgconf/uitron.h for details of applicable configuration
+// options.
+//
+// This file uit_ifnc.h provides prototypes for the task-independent parts
+// of the uITRON API, that is functions named ixxx_yyy() for calling in
+// ISRs.  We also define the uitron helper DSR that is needed to despool
+// stored up requests.
+// ------------------------------------------------------------------------
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+
+#ifdef CYGPKG_UITRON
+
+#include <cyg/infra/cyg_type.h>         // types; cyg_int32, CYG_ADDRWORD
+
+#include <cyg/compat/uitron/uit_type.h> // uITRON types; ER ID TMO T_MSG
+#include <cyg/compat/uitron/uit_func.h> // uITRON funcs and control macros.
+
+// ========================================================================
+//         u I T R O N   F U N C T I O N S
+// The function declarations themselves:
+
+// ------------------- These functions can be inline if so configured
+CYG_UIT_FUNC_EXTERN_BEGIN
+
+// ******************************************************
+// ***    6.5 C Language Interfaces                   ***
+// ******************************************************
+
+// - Task Management Functions
+
+// (None)
+        
+// - Task-Dependent Synchronization Functions
+        
+//ER      irsm_tsk ( ID tskid );
+//ER      ifrsm_tsk ( ID tskid );
+
+ER      iwup_tsk ( ID tskid );
+        
+// - Synchronization and Communication Functions
+        
+ER      isig_sem ( ID semid );
+
+ER      iset_flg ( ID flgid, UINT setptn );
+
+ER      isnd_msg ( ID mbxid, T_MSG *pk_msg );
+        
+// - Extended Synchronization and Communication Functions
+        
+// - Interrupt Management Functions
+        
+// (None)
+   
+// ---------------------------------------------------------------
+
+#define CYGPRI_UITRON_SET_RETCODE( _z_ ) do {                                   \
+    extern volatile int cyg_uit_dsr_actions_head;                               \
+    extern volatile int cyg_uit_dsr_actions_tail;                               \
+    (_z_) = (cyg_uit_dsr_actions_head == cyg_uit_dsr_actions_tail) ? 1 : 3;     \
+} while ( 0 )
+
+//void    ret_wup ( ID tskid );
+// Awaken the task (safely) and return Cyg_Interrupt::CALL_DSR
+#define ret_wup( _id_ ) do {                    \
+    register int retcode;                       \
+    (void)iwup_tsk( (_id_) );                   \
+    CYGPRI_UITRON_SET_RETCODE( retcode );       \
+    return retcode;                             \
+} while ( 0 )
+
+// Subsitute a version of ret_int that returns Cyg_Interrupt::CALL_DSR
+#undef ret_int
+#define ret_int()  do {                         \
+    register int retcode;                       \
+    CYGPRI_UITRON_SET_RETCODE( retcode );       \
+    return retcode;                             \
+} while ( 0 )
+
+
+// - Memorypool Management Functions
+
+// (None)
+        
+// - Time Management Functions
+        
+// (None)
+        
+// - System Management Functions
+        
+// (None)
+        
+// - Network Support Functions
+        
+// (None)
+        
+CYG_UIT_FUNC_EXTERN_END
+// ------------------- End of functions that can be inlined
+
+
+// ========================================================================
+// DSR: use this DSR with the uITRON-type ISR that uses the functions above
+// to get delayed/safe execution of the wakeup-type functions above.
+
+#ifdef __cplusplus
+extern "C"
+#endif
+void cyg_uitron_dsr( unsigned int vector, unsigned int count, unsigned int data );
+
+
+// ========================================================================
+
+#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+// functions are inline OR we are in the outline implementation, so define
+// the functions as inlines or plain functions depending on the value of
+// CYG_UIT_FUNC_INLINE from above.
+#include <cyg/compat/uitron/uit_ifnc.inl>
+#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+// ------------------------------------------------------------------------
+#endif // CYGPKG_UITRON
+
+#endif // CYGONCE_COMPAT_UITRON_UIT_IFNC_H
+// EOF uit_ifnc.h
diff --git a/packages/compat/uitron/v2_0/include/uit_ifnc.inl b/packages/compat/uitron/v2_0/include/uit_ifnc.inl
new file mode 100644 (file)
index 0000000..a864b3e
--- /dev/null
@@ -0,0 +1,218 @@
+#ifndef CYGONCE_COMPAT_UITRON_UIT_IFNC_INL
+#define CYGONCE_COMPAT_UITRON_UIT_IFNC_INL
+//===========================================================================
+//
+//      uit_ifnc.inl
+//
+//      uITRON compatibility functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1999-08-16
+// Purpose:     uITRON compatibility functions
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#ifdef CYGPKG_UITRON
+
+#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+class Cyg_Uit_Action {
+public:
+    typedef enum {
+        WUP_TSK,
+        SIG_SEM,
+        SET_FLG,
+        SND_MSG
+    } action;
+};
+
+extern volatile int cyg_uit_dsr_actions_head;
+extern volatile int cyg_uit_dsr_actions_tail;
+
+#define CYGNUM_UITRON_ISR_ACTION_QUEUEMASK (CYGNUM_UITRON_ISR_ACTION_QUEUESIZE-1)
+
+#if ((~CYGNUM_UITRON_ISR_ACTION_QUEUEMASK) &            \
+     ~((~CYGNUM_UITRON_ISR_ACTION_QUEUEMASK)-1))        \
+    != CYGNUM_UITRON_ISR_ACTION_QUEUESIZE
+#error CYGNUM_UITRON_ISR_ACTION_QUEUESIZE not a power of 2
+#endif
+
+extern Cyg_Uit_Action::action
+cyg_uit_dsr_actions[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
+
+extern ID
+cyg_uit_dsr_act_ids[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
+
+extern CYG_ADDRWORD
+cyg_uit_dsr_act_a1s[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
+
+CYG_UIT_FUNC_INLINE
+ER
+iwup_tsk ( ID tskid )
+{
+#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
+    if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
+        // then this ISR is the first one, and the sched was locked by the
+        // interrupt code.  So this is safe.
+        return wup_tsk( tskid );
+    }
+#endif
+    
+    register int i, head;
+    i = cyg_uit_dsr_actions_head;
+    head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
+    // If interrupts can be recursive, then there is a race here where a
+    // slot may be overwritten by a recursive interrupt, or actions from
+    // such lost; better though than having a slot contain *mixed* data
+    // from two intermingled interrupts.
+    if ( head != cyg_uit_dsr_actions_tail ) {
+        cyg_uit_dsr_actions_head = head;
+        cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::WUP_TSK;
+        cyg_uit_dsr_act_ids[ i ] = tskid;
+    }
+    return E_OK;
+}
+        
+#ifdef CYGPKG_UITRON_SEMAS
+#if 0 < CYG_UITRON_NUM( SEMAS )
+CYG_UIT_FUNC_INLINE
+ER
+isig_sem ( ID semid )
+{
+#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
+    if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
+        // then this ISR is the first one, and the sched was locked by the
+        // interrupt code.  So this is safe.
+        return sig_sem( semid );
+    }
+#endif
+    
+    register int i, head;
+    i = cyg_uit_dsr_actions_head;
+    head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
+    // If interrupts can be recursive, then there is a race here where a
+    // slot may be overwritten by a recursive interrupt, or actions from
+    // such lost; better though than having a slot contain *mixed* data
+    // from two intermingled interrupts.
+    if ( head != cyg_uit_dsr_actions_tail ) {
+        cyg_uit_dsr_actions_head = head;
+        cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::SIG_SEM;
+        cyg_uit_dsr_act_ids[ i ] = semid;
+    }
+    return E_OK;
+}
+#endif // 0 < CYG_UITRON_NUM( SEMAS )
+#endif // CYGPKG_UITRON_SEMAS
+
+#ifdef CYGPKG_UITRON_FLAGS
+#if 0 < CYG_UITRON_NUM( FLAGS )
+CYG_UIT_FUNC_INLINE
+ER
+iset_flg ( ID flgid, UINT setptn )
+{
+#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
+    if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
+        // then this ISR is the first one, and the sched was locked by the
+        // interrupt code.  So this is safe.
+        return set_flg( flgid, setptn );
+    }
+#endif
+    
+    register int i, head;
+    i = cyg_uit_dsr_actions_head;
+    head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
+    // If interrupts can be recursive, then there is a race here where a
+    // slot may be overwritten by a recursive interrupt, or actions from
+    // such lost; better though than having a slot contain *mixed* data
+    // from two intermingled interrupts.
+    if ( head != cyg_uit_dsr_actions_tail ) {
+        cyg_uit_dsr_actions_head = head;
+        cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::SET_FLG;
+        cyg_uit_dsr_act_ids[ i ] = flgid;
+        cyg_uit_dsr_act_a1s[ i ] = (CYG_ADDRWORD)setptn;
+    }
+    return E_OK;
+}
+#endif // 0 < CYG_UITRON_NUM( FLAGS )
+#endif // CYGPKG_UITRON_FLAGS
+
+#ifdef CYGPKG_UITRON_MBOXES
+#if 0 < CYG_UITRON_NUM( MBOXES )
+CYG_UIT_FUNC_INLINE
+ER
+isnd_msg ( ID mbxid, T_MSG *pk_msg )
+{
+#ifdef CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION
+    if ( 1 >= Cyg_Scheduler::get_sched_lock() ) {
+        // then this ISR is the first one, and the sched was locked by the
+        // interrupt code.  So this is safe.
+        return snd_msg( mbxid, pk_msg );
+    }
+#endif
+    
+    register int i, head;
+    i = cyg_uit_dsr_actions_head;
+    head = CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & ( 1 + i );
+    // If interrupts can be recursive, then there is a race here where a
+    // slot may be overwritten by a recursive interrupt, or actions from
+    // such lost; better though than having a slot contain *mixed* data
+    // from two intermingled interrupts.
+    if ( head != cyg_uit_dsr_actions_tail ) {
+        cyg_uit_dsr_actions_head = head;
+        cyg_uit_dsr_actions[ i ] = Cyg_Uit_Action::SND_MSG;
+        cyg_uit_dsr_act_ids[ i ] = mbxid;
+        cyg_uit_dsr_act_a1s[ i ] = (CYG_ADDRWORD)pk_msg;
+    }
+    return E_OK;
+}
+#endif // 0 < CYG_UITRON_NUM( MBOXES )
+#endif // CYGPKG_UITRON_MBOXES
+        
+// ========================================================================
+
+#endif // CYGPKG_UITRON
+
+#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+#endif // CYGONCE_COMPAT_UITRON_UIT_IFNC_INL
+//EOF uit_ifnc.inl
diff --git a/packages/compat/uitron/v2_0/include/uit_objs.hxx b/packages/compat/uitron/v2_0/include/uit_objs.hxx
new file mode 100644 (file)
index 0000000..e2efff9
--- /dev/null
@@ -0,0 +1,177 @@
+#ifndef CYGONCE_COMPAT_UITRON_UIT_OBJS_HXX
+#define CYGONCE_COMPAT_UITRON_UIT_OBJS_HXX
+//===========================================================================
+//
+//      uit_objs.hxx
+//
+//      uITRON static objects
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON static system objects
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+
+#ifdef CYGPKG_UITRON
+
+#include <cyg/infra/cyg_type.h>         // types; cyg_int32, CYG_ADDRWORD
+
+#include <pkgconf/kernel.h>
+
+#include <cyg/kernel/ktypes.h>
+
+#include <cyg/kernel/thread.hxx>        // Cyg_Thread
+#include <cyg/kernel/mbox.hxx>          // Cyg_Mbox
+#include <cyg/kernel/flag.hxx>          // Cyg_Flag
+#include <cyg/kernel/sema2.hxx>         // Cyg_Counting_Semaphore2
+#include <cyg/memalloc/memfixed.hxx>    // Cyg_Mempool_Fixed
+#include <cyg/memalloc/memvar.hxx>      // Cyg_Mempool_Variable
+#include <cyg/kernel/timer.hxx>         // Cyg_Timer
+
+// ------------------------------------------------------------------------
+// Some pasting macros to create names of the config macro and the
+// static data resulting:
+
+#define CYG_UITRON_NUM( _which_ )  (CYGNUM_UITRON_ ## _which_)
+#define CYG_UITRON_OBJS( _which_ )  cyg_uitron_ ## _which_
+#define CYG_UITRON_PTRS( _which_ )  cyg_uitron_ ## _which_ ## _ptrs
+// ------------------------------------------------------------------------
+// CYG_UITRON_DECL
+// 
+// Macro to declare static uitron static objects; uses the appropriate
+// config define for the number of them to have.
+
+#define CYG_UITRON_OBJS_INIT_PRIORITY CYG_INIT_PRIORITY( COMPAT )
+
+#define CYG_UITRON_DECL( _which_ ) \
+    CYG_UITRON_OBJS( _which_ ) [ CYG_UITRON_NUM( _which_ ) ] \
+    CYG_UITRON_OBJS_INIT_PRIORITY
+
+// and the array of pointers to them for those with dynamic existence:
+#define CYG_UITRON_DECL_PTRS( _which_ ) \
+    CYG_UITRON_PTRS( _which_ ) [ CYG_UITRON_NUM( _which_ ) ]
+
+
+// ------------------------------------------------------------------------
+// The external system objects themselves.
+
+#ifdef CYGPKG_UITRON_SEMAS
+extern
+Cyg_Counting_Semaphore2 CYG_UITRON_OBJS( SEMAS )        [];
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+extern
+Cyg_Counting_Semaphore2 *CYG_UITRON_PTRS( SEMAS )       [];
+#endif
+#endif
+#ifdef CYGPKG_UITRON_MBOXES
+extern
+Cyg_Mbox                CYG_UITRON_OBJS( MBOXES )       [];
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+extern
+Cyg_Mbox                *CYG_UITRON_PTRS( MBOXES )      [];
+#endif
+#endif
+#ifdef CYGPKG_UITRON_FLAGS
+extern
+Cyg_Flag                CYG_UITRON_OBJS( FLAGS )        [];
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+extern
+Cyg_Flag                *CYG_UITRON_PTRS( FLAGS )       [];
+#endif
+#endif
+// there must always be tasks
+extern
+Cyg_Thread              CYG_UITRON_OBJS( TASKS )        [];
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+extern
+Cyg_Thread              *CYG_UITRON_PTRS( TASKS )       [];
+#endif
+// no endif
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED
+extern
+Cyg_Mempool_Fixed       CYG_UITRON_OBJS( MEMPOOLFIXED ) [];
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+extern
+Cyg_Mempool_Fixed       *CYG_UITRON_PTRS( MEMPOOLFIXED )[];
+#endif
+#endif
+#ifdef CYGPKG_UITRON_MEMPOOLVAR
+extern
+Cyg_Mempool_Variable    CYG_UITRON_OBJS( MEMPOOLVAR )   [];
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+extern
+Cyg_Mempool_Variable    *CYG_UITRON_PTRS( MEMPOOLVAR )  [];
+#endif
+#endif
+#ifdef CYGPKG_UITRON_CYCLICS
+extern
+Cyg_Timer               CYG_UITRON_OBJS( CYCLICS )      [];
+#endif
+#ifdef CYGPKG_UITRON_ALARMS
+extern
+Cyg_Timer               CYG_UITRON_OBJS( ALARMS )       [];
+#endif
+
+// ------------------------------------------------------------------------
+// Ancillary system objects - cleaner than extending the basic class
+
+#ifdef CYGIMP_THREAD_PRIORITY
+// An array of priorities, for resetting back to the "created" prio when a
+// task cycles though exit, dormancy, restart.
+extern cyg_priority
+cyg_uitron_task_initial_priorities[ CYG_UITRON_NUM( TASKS ) ];
+// and an accessor macro, for the addressing of this is naturally
+// from 1..N also:
+#define CYG_UITRON_TASK_INITIAL_PRIORITY( _tskid_ ) \
+    (cyg_uitron_task_initial_priorities[ (_tskid_) - 1 ])
+#endif // CYGIMP_THREAD_PRIORITY
+
+// ------------------------------------------------------------------------
+
+#endif // CYGPKG_UITRON
+
+#endif // CYGONCE_COMPAT_UITRON_UIT_OBJS_HXX
+// EOF uit_objs.hxx
diff --git a/packages/compat/uitron/v2_0/include/uit_type.h b/packages/compat/uitron/v2_0/include/uit_type.h
new file mode 100644 (file)
index 0000000..f79c6a1
--- /dev/null
@@ -0,0 +1,687 @@
+#ifndef CYGONCE_COMPAT_UITRON_UIT_TYPE_H
+#define CYGONCE_COMPAT_UITRON_UIT_TYPE_H
+//===========================================================================
+//
+//      uit_type.h
+//
+//      uITRON specific data types as required by the API
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON specific data types as required by the API
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+
+#ifdef CYGPKG_UITRON
+
+// ------------------------------------------------------------------------
+// uITRON types
+//
+
+// from this section of the uITRON 3.02 manual:
+// ***********************************************************************
+// ***    6.4 Data Types                                               ***
+// ***********************************************************************
+//
+// ***  General-Purpose Data Types ***************************************
+
+typedef cyg_int8    B;          // signed 8-bit integer
+typedef cyg_int16   H;          // signed 16-bit integer
+typedef cyg_int32   W;          // signed 32-bit integer
+typedef cyg_uint8   UB;         // unsigned 8-bit integer
+typedef cyg_uint16  UH;         // unsigned 16-bit integer
+typedef cyg_uint32  UW;         // unsigned 32-bit integer
+                                // 
+typedef cyg_uint32  VW;         // unpredictable data type (32-bit size)
+typedef cyg_uint16  VH;         // unpredictable data type (16-bit size)
+typedef cyg_uint8   VB;         // unpredictable data type (8-bit size)
+                                
+typedef void *      VP;         // pointer to an unpredictable data type
+                                
+typedef CYG_ADDRWORD FP;        // program start address
+
+// * The difference between VB, VH and VW and B, H and W is that only the
+//   number of bits is known for the former, not the data type of the
+//   contents.  The latter clearly represent integers.
+//
+// ***  Data Types Dependent on ITRON Specification ***
+//
+// In order to clarify the meanings of certain parameters, the following
+// names are used for data types which appear frequently and/or have
+// special meanings.
+
+typedef cyg_int32  INT; // Signed integer (bit width of processor)
+typedef cyg_uint32 UINT;   // Unsigned integer (bit width of processor)
+typedef cyg_int32  BOOL;   // Boolean value.  TRUE (1) or FALSE (0).
+typedef cyg_uint16 FN;     // Function code.  Signed integer.  Maximum 2 bytes.
+typedef INT        ID;     // Object ID number (???id)
+typedef INT        BOOL_ID;// Boolean value or ID number
+typedef INT        HNO;    // Handler number
+typedef INT        RNO;    // Rendezvous number
+typedef INT        NODE;   // Node Number.  Usually a signed integer.
+typedef UINT       ATR;    // Object or handler attribute.  An unsigned integer.
+typedef INT        ER;     // Error code.  A signed integer.
+typedef INT        PRI;    // Task priority.  A signed integer.
+typedef UB         T_MSG;  // Message packet data structure used for mailboxes
+typedef INT        TMO;    // Timeout value.  A signed integer.
+                           // TMO_POL = 0 indicates polling,
+                           // while TMO_FEVR = -1 indicates wait forever.
+
+typedef cyg_uint64 CYGTM;
+typedef CYGTM      SYSTIME;// Data types used for specifying times.
+typedef CYGTM      CYCTIME;// Often split into upper and lower sections.
+typedef CYGTM      ALMTIME;// For details, see the chapter giving system
+typedef CYGTM      DLYTIME;// call descriptions;.
+
+// ***********************************************************************
+// ***    6.7 Error Codes                                              ***
+// ***********************************************************************
+
+enum {
+//------------------------------------------------------
+//Mnemonic Value      Description
+//------------------------------------------------------
+E_OK     = 0,      // Normal completion
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_SYS    = (-5),   // System error
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_NOMEM  = (-10),  // Insufficient memory
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_NOSPT  = (-17),  // Feature not supported
+E_INOSPT = (-18),  // Feature not supported by ITRON/FILE specification
+E_RSFN   = (-20),  // Reserved function code number
+E_RSATR  = (-24),  // Reserved attribute
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_PAR    = (-33),  // Parameter error
+E_ID     = (-35),  // Invalid ID number
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_NOEXS  = (-52),  // Object does not exist
+E_OBJ    = (-63),  // Invalid object state
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_MACV   = (-65),  // Memory access disabled or memory access violation
+E_OACV   = (-66),  // Object access violation
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_CTX    = (-69),  // Context error
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_QOVR   = (-73),  // Queuing or nesting overflow
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_DLT    = (-81),  // Object being waited for was deleted
+// - - - - - - - - // - - - - - - - - - - - - - - - - - -
+E_TMOUT  = (-85),  // Polling failure or timeout exceeded
+E_RLWAI  = (-86),  // WAIT state was forcibly released
+// - - - - - - - - // - - - - - - - - - - - - - - - - - - -
+#if 0 // CONNECTION FUNCTIONS ARE NOT SUPPORTED
+EN_NOND  = (-113), // Target node does not exist or cannot be accessed
+EN_OBJNO = (-114), // Specifies an object number which could not be
+                   // accessed on the target node
+EN_PROTO = (-115), // Protocol not supported on target node
+EN_RSFN  = (-116), // System call or function not supported on target node
+EN_COMM  = (-117), // No response from target node
+EN_RLWAI = (-118), // Connection function response wait state was forcibly
+                   // released
+EN_PAR   = (-119), // A value outside the range supported by the target
+                   // node and/or transmission packet format was specified
+                   // as a parameter
+EN_RPAR  = (-120), // A value outside the range supported by the issuing
+                   // node and/or transmission packet format was returned
+                   // as a return parameter
+EN_CTXID = (-121), // An object on another node was specified to a system
+                   // call issued from a task in dispatch disabled state
+                   // or from a task-independent portion
+EN_EXEC  = (-122), // System call could not be executed due to
+                   // insufficient resources on the target node
+EN_NOSPT = (-123), // Connection function not supported
+#endif // 0 CONNECTION FUNCTIONS ARE NOT SUPPORTED
+// - - - - - - - - // - - - - - - - - - - - - - - - - - - -
+};
+
+
+// *******************************************************************
+// ***    6.6 Common Constants and Data Structure Packet Formats   ***
+// *******************************************************************
+
+/* --- overall ----------------------- */
+
+/* invalid address or pointer value */
+#define NADR      ((void *)(-1)) 
+
+enum {
+        TRUE  =   1,    /* true */
+        FALSE =   0,    /* false */
+};
+
+/*    TMO tmout:   */
+enum {
+        TMO_POL  =    0,    /* polling */
+        TMO_FEVR =  (-1)    /* wait forever */
+};
+
+/* --- for task management functions ----------------------- */
+
+// cre_tsk:
+        typedef struct t_ctsk {
+                VP    exinf;     /* extended information */
+                ATR   tskatr;    /* task attributes */
+                FP    task;      /* task start address */
+                PRI   itskpri;   /* initial task priority */
+                INT   stksz;     /* stack size */
+                // ...
+            /* additional information may be included depending on the
+               implementation */
+                // ...
+        } T_CTSK;
+
+//    tskatr:
+enum {
+        TA_ASM    = 0x00,     /* program written in assembly language */
+        TA_HLNG   = 0x01,     /* program written in high-level language */
+        TA_COP0   = 0x8000,   /* uses coprocessor having ID = 0 */
+        TA_COP1   = 0x4000,   /* uses coprocessor having ID = 1 */
+        TA_COP2   = 0x2000,   /* uses coprocessor having ID = 2 */
+        TA_COP3   = 0x1000,   /* uses coprocessor having ID = 3 */
+        TA_COP4   = 0x0800,   /* uses coprocessor having ID = 4 */
+        TA_COP5   = 0x0400,   /* uses coprocessor having ID = 5 */
+        TA_COP6   = 0x0200,   /* uses coprocessor having ID = 6 */
+        TA_COP7   = 0x0100,   /* uses coprocessor having ID = 7 */
+};
+
+//    tskid:
+enum {
+        TSK_SELF  = 0,  /* task specifies itself */
+        /* FALSE     = 0, */ /* indicates a task-independent portion (return
+                          parameters only) */
+};
+//    tskpri:
+enum {
+        TPRI_INI  = 0,  /* specifies the initial priority on task startup
+                          (chg_pri) */
+        TPRI_RUN  = 0,  /* specifies the highest priority during execution
+                          (rot_rdq) */
+};
+    /* ref_tsk */
+        typedef struct t_rtsk {
+                VP     exinf;     /* extended information */
+                PRI    tskpri;    /* current priority */
+                UINT   tskstat;   /* task state */
+            /* the following are represent extended features of support
+               [level X] (implementation-dependent) */
+#if 0 // NOT SUPPORTED
+                UINT   tskwait;   /* cause of wait */
+                ID     wid;       /* ID of object being waited for */
+                INT    wupcnt;    /* wakeup request count */
+                INT    suscnt;    /* SUSPEND request count */
+                ATR    tskatr;    /* task attributes */
+                FP     task;      /* task start address */
+                PRI    itskpri;   /* initial task priority */
+                INT    stksz;     /* stack size */
+                        // ...
+#endif
+        } T_RTSK;
+
+//    tskstat:
+enum {
+        TTS_RUN   = 0x01,  /* RUN */
+        TTS_RDY   = 0x02,  /* READY */
+        TTS_WAI   = 0x04,  /* WAIT */
+        TTS_SUS   = 0x08,  /* SUSPEND */
+        TTS_WAS   = 0x0C,  /* WAIT-SUSPEND */
+        TTS_DMT   = 0x10,  /* DORMANT */
+};
+//    tskwait:
+enum {
+        TTW_SLP   = 0x0001,  /* wait due to slp_tsk or tslp_tsk */
+        TTW_DLY   = 0x0002,  /* wait due to dly_tsk */
+        TTW_NOD   = 0x0008,  /* connection function response wait */
+        TTW_FLG   = 0x0010,  /* wait due to wai_flg or twai_flg */
+        TTW_SEM   = 0x0020,  /* wait due to wai_sem or twai_sem */
+        TTW_MBX   = 0x0040,  /* wait due to rcv_msg or trcv_msg */
+        TTW_SMBF  = 0x0080,  /* wait due to snd_mbf or tsnd_mbf */
+        TTW_MBF   = 0x0100,  /* wait due to rcv_mbf or trcv_mbf */
+        TTW_CAL   = 0x0200,  /* wait for rendezvous call */
+        TTW_ACP   = 0x0400,  /* wait for rendezvous accept */
+        TTW_RDV   = 0x0800,  /* wait for rendezvous completion */
+        TTW_MPL   = 0x1000,  /* wait due to get_blk or tget_blk */
+        TTW_MPF   = 0x2000,  /* wait due to get_blf or tget_blf */
+};
+         /* Since the task states given by tskstat and tskwait are expressed
+            by bit correspondences, they are convenient when looking for OR
+            conditions (such as whether a task is in WAIT or READY state).
+            */
+
+/* --- for semaphore functions ----------------------- */
+
+    /* cre_sem */
+        typedef struct t_csem {
+                VP    exinf;    /* extended information */
+                ATR   sematr;   /* semaphore attributes */
+            /* Following is the extended function for [level X]. */
+                INT   isemcnt;   /* initial semaphore count */
+            /*  INT   maxsem;  NOT SUPPORTED maximum semaphore count */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_CSEM;
+
+    /* ref_sem */
+        typedef struct t_rsem {
+                VP      exinf;    /* extended information */
+                BOOL_ID wtsk;     /* indicates whether or not there is a
+                                     waiting task */
+                INT     semcnt;   /* current semaphore count */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RSEM;
+
+/* --- for eventflag functions ----------------------- */
+
+    /* cre_flg */
+        typedef struct t_cflg {
+                VP     exinf;     /* extended information */
+                ATR    flgatr;    /* eventflag attribute */
+                UINT   iflgptn;   /* initial eventflag */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_CFLG;
+
+//    flgatr:
+enum {
+        TA_WSGL   = 0x00,  /* multiple tasks are not allowed to wait (Wait
+                                Single Task) */
+        TA_WMUL   = 0x08,  /* multiple tasks are allowed to wait (Wait
+                                Multiple Task) */
+};
+//    wfmode:
+enum {
+        TWF_ANDW   = 0x00,  /* AND wait */
+        TWF_ORW    = 0x02,  /* OR wait */
+        TWF_CLR    = 0x01,  /* clear specification */
+};
+    /* ref_flg */
+        typedef struct t_rflg {
+                VP        exinf;      /* extended information */
+                BOOL_ID   wtsk;       /* indicates whether or not there is a
+                                         waiting task */
+                UINT      flgptn;     /* eventflag bit pattern */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RFLG;
+
+/* --- for mailbox functions ----------------------- */
+
+   /* cre_mbx */
+        typedef struct t_cmbx {
+                VP    exinf;    /* extended information */
+                ATR   mbxatr;   /* mailbox attributes */
+            /* Following is implementation-dependent function */
+            /*  INT   bufcnt; NOT SUPPORTED ring buffer size IS FIXED */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_CMBX;
+
+//    mbxatr:
+enum {
+        TA_TFIFO   = 0x00,  /* waiting tasks are handled by FIFO */
+        TA_TPRI    = 0x01,  /* waiting tasks are handled by priority */
+        TA_MFIFO   = 0x00,  /* messages are handled by FIFO */
+        TA_MPRI    = 0x02,  /* messages are handled by priority */
+};
+
+    /* ref_mbx */
+        typedef struct t_rmbx {
+                VP        exinf;    /* extended information */
+                BOOL_ID   wtsk;     /* indicates whether or not there is a
+                                       waiting task */
+                T_MSG*    pk_msg;   /* message to be sent next */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RMBX;
+
+/* --- for messagebuffer functions ----------------------- */
+
+#if 0 // NOT SUPPORTED
+    /* cre_mbf */
+        typedef struct t_cmbf {
+                VP    exinf;    /* extended information */
+                ATR   mbfatr;   /* messagebuffer attributes */
+                INT   bufsz;    /* messagebuffer size */
+                INT   maxmsz;   /* maximum size of messages */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_CMBF;
+
+//    mbfatr:
+//    mbfid:
+enum {
+        TMBF_OS  = (-4),   /* messagebuffer used for OS error log */
+        TMBF_DB  = (-3),   /* messagebuffer used for debugging */
+};
+    /* ref_mbf */
+        typedef struct t_rmbf {
+                VP        exinf;     /* extended information */
+                BOOL_ID   wtsk;      /* indicates whether or not there is a
+                                        task waiting to receive a message */
+                BOOL_ID   stsk;      /* indicates whether or not there is a
+                                        task waiting to send a message */
+                INT       msgsz;     /* size of message to be sent next */
+                INT       frbufsz;   /* size of free buffer */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RMBF;
+
+#endif
+/* --- for port or rendezvous functions ----------------------- */
+
+#if 0 // NOT SUPPORTED
+
+    /* cre_por */
+        typedef struct t_cpor {
+                VP    exinf;     /* extended information */
+                ATR   poratr;    /* port attributes */
+                INT   maxcmsz;   /* maximum call message size */
+                INT   maxrmsz;   /* maximum reply message size */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_CPOR;
+
+//    poratr:
+enum {
+        TA_NULL  = 0,  /* specifies no particular attributes */
+         /* TA_NULL should be used in place of zeroes to turn off all
+            attribute features. */
+};
+    /* ref_por */
+        typedef struct t_rpor {
+                VP        exinf;   /* extended information */
+                BOOL_ID   wtsk;    /* indicates whether or not there is a task
+                                      waiting to call a rendezvous */
+                BOOL_ID   atsk;    /* indicates whether or not there is a task
+                                      waiting to accept a rendezvous */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RPOR;
+#endif
+
+/* --- for interrupt management functions ----------------------- */
+
+#if 0 // NOT SUPPORTED
+    /* def_int */
+        typedef struct t_dint {
+                ATR   intatr;   /* interrupt handler attributes */
+                FP    inthdr;   /* interrupt handler address */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_DINT;
+#endif
+
+/* --- for memorypool management functions ----------------------- */
+
+    /* cre_mpl */
+        typedef struct t_cmpl {
+                VP    exinf;    /* extended information */
+                ATR   mplatr;   /* memorypool attributes */
+                INT   mplsz;    /* memorypool size */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_CMPL;
+
+//    mplatr:
+//    mplid:
+enum {
+        TMPL_OS  = (-4)   /* memorypool used by OS */
+};
+    /* ref_mpl */
+        typedef struct t_rmpl {
+                VP        exinf;    /* extended information */
+                BOOL_ID   wtsk;     /* indicates whether or not there are
+                                       waiting tasks */
+                INT       frsz;     /* total size of free memory */
+                INT       maxsz;    /* size of largest contiguous memory */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RMPL;
+
+    /* cre_mpf */
+        typedef struct t_cmpf {
+                VP    exinf;     /* extended information */
+                ATR   mpfatr;    /* memorypool attributes */
+                INT   mpfcnt;    /* block count for entire memorypool */
+                INT   blfsz;     /* fixed-size memory block size */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_CMPF;
+
+//    mpfatr:
+    /* ref_mpf */
+        typedef struct t_rmpf {
+                VP        exinf;    /* extended information */
+                BOOL_ID   wtsk;     /* indicates whether or not there are
+                                       waiting tasks */
+                INT       frbcnt;   /* free block count */
+            /* additional information may be included depending on the
+               implementation */
+                INT       numbcnt;  /* total number of blocks */
+                INT       bsize;    /* block size */
+
+        } T_RMPF;
+
+/* --- for time management functions ----------------------- */
+
+#if 0 // native definition is at head of this file
+    /* example for 32-bit CPUs */
+        typedef struct t_systime {
+                H    utime;   /* upper 16 bits */
+                UW   ltime;   /* lower 32 bits */
+        } SYSTIME, CYCTIME, ALMTIME;
+
+    /* example for 16-bit CPUs */
+        typedef struct t_systime {
+                H    utime;   /* upper 16 bits */
+                UH   mtime;   /* middle 16 bits */
+                UH   ltime;   /* lower 16 bits */
+        } SYSTIME, CYCTIME, ALMTIME;
+#endif
+         /* Member configuration depends on the bit width of the processor and
+            on the implementation.  A total of 48 bits is recommended. */
+
+    /* def_cyc */
+        typedef struct t_dcyc {
+                VP        exinf;    /* extended information */
+                ATR       cycatr;   /* cyclic handler attributes */
+                FP        cychdr;   /* cyclic handler address */
+                UINT      cycact;   /* cyclic handler activation */
+                CYCTIME   cyctim;   /* cyclic startup period */
+        } T_DCYC;
+
+//    cycact:
+enum {
+        TCY_OFF   = 0x00,  /* do not invoke cyclic handler */
+        TCY_ON    = 0x01,  /* invoke cyclic handler */
+        TCY_INT   = 0x02,  /* initialize cycle count */
+        /* Following changed from TCY_INT to TCY_INI to match
+           description in the body of the standard.  I assume TCY_INT
+           is a hypercorrection/typo; keep both */
+        TCY_INI   = 0x02,  /* initialize cycle count */
+};
+    /* ref_cyc */
+        typedef struct t_rcyc {
+                VP        exinf;    /* extended information */
+                CYCTIME   lfttim;   /* time left before next handler startup */
+                UINT      cycact;   /* cyclic handler activation */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RCYC;
+
+    /* def_alm */
+        typedef struct t_dalm {
+                VP        exinf;    /* extended information */
+                ATR       almatr;   /* alarm handler attributes */
+                FP        almhdr;   /* alarm handler address */
+                UINT      tmmode;   /* start time specification mode */
+                ALMTIME   almtim;   /* handler startup time */
+        } T_DALM;
+
+//    tmmode:
+enum {
+        TTM_ABS   = 0x00,  /* specified as an absolute time */
+        TTM_REL   = 0x01,  /* specified as a relative time */
+};
+    /* ref_alm */
+        typedef struct t_ralm {
+                VP        exinf;    /* extended information */
+                ALMTIME   lfttim;   /* time left before next handler startup */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RALM;
+
+/* --- for system management functions ----------------------- */
+
+    /* get_ver */
+        typedef struct t_ver {
+                UH   maker;     /* vendor */
+                UH   id;        /* format number */
+                UH   spver;     /* specification version */
+                UH   prver;     /* product version */
+                UH   prno[4];   /* product control information */
+                UH   cpu;       /* CPU information */
+                UH   var;       /* variation descriptor */
+        } T_VER;
+
+    /* ref_sys */
+        typedef struct t_rsys {
+                INT   sysstat;   /* system state */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_RSYS;
+
+//    sysstat:
+enum {
+        TSS_TSK   = 0,  /* normal state in which dispatching is enabled during
+                          task portion execution */
+        TSS_DDSP  = 1,   /* state after dis_dsp has been executed during task
+                          portion execution (dispatch disabled) */
+        TSS_LOC   = 3,   /* state after loc_cpu has been executed during task
+                          portion execution (interrupt and dispatch disabled)
+                          */
+        TSS_INDP  = 4,   /* state during execution of task-independent portions
+                          (interrupt and timer handlers) */
+};
+    /* ref_cfg */
+        typedef struct t_rcfg {
+            /* details concerning members are implementation dependent */
+        } T_RCFG;
+
+#if 0 // NOT SUPPORTED
+    /* def_svc */
+        typedef struct t_dsvc {
+                ATR   svcatr;   /* extended SVC handler attributes */
+                FP    svchdr;   /* extended SVC handler address */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_DSVC;
+
+    /* def_exc */
+        typedef struct t_dexc {
+                ATR   excatr;   /* exception handler attributes */
+                FP    exchdr;   /* exception handler address */
+                        // ...
+            /* additional information may be included depending on the
+               implementation */
+                        // ...
+        } T_DEXC;
+#endif
+
+/* --- for network management functions ----------------------- */
+
+#if 0 // NOT SUPPORTED
+//    NODE srcnode, dstnode, node:
+enum {
+        TND_SELF  = 0,     /* specifies the local node */
+        TND_OTHR  = (-1)   /* specifies default remote node */
+};
+#endif
+/* ------------------------------------------------------ */
+
+
+
+#endif // CYGPKG_UITRON
+
+#endif // CYGONCE_COMPAT_UITRON_UIT_TYPE_H
+// EOF uit_type.h
diff --git a/packages/compat/uitron/v2_0/src/uit_func.cxx b/packages/compat/uitron/v2_0/src/uit_func.cxx
new file mode 100644 (file)
index 0000000..9c4e9be
--- /dev/null
@@ -0,0 +1,192 @@
+//===========================================================================
+//
+//      uit_func.cxx
+//
+//      uITRON compatibility functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON compatibility functions
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+
+#ifdef CYGPKG_UITRON
+
+// invoke the inline function definition to create static C linkage
+// functions here:
+#define CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+#include <cyg/compat/uitron/uit_func.h>
+
+cyg_uint32 cyg_uitron_dis_dsp_old_priority = 0;
+
+// ------------------------------------------------------------------------
+//                  STARTUP
+// this routine is outside the uITRON specification; call it from
+// cyg_start(), cyg_package_start(), cyg_prestart() or cyg_user_start()
+// to start the uITRON tasks and scheduler.
+
+#if CYGNUM_UITRON_START_TASKS < 0
+#error CYGNUM_UITRON_START_TASKS should be >= 0
+#endif
+
+#if CYGNUM_UITRON_START_TASKS == 0
+#define START_TASKS CYGNUM_UITRON_TASKS
+#else
+#define START_TASKS CYGNUM_UITRON_START_TASKS
+#endif
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+#if START_TASKS > CYGNUM_UITRON_TASKS_INITIALLY
+#undef START_TASKS
+#define START_TASKS CYGNUM_UITRON_TASKS_INITIALLY
+#endif
+#endif
+
+#if START_TASKS > CYGNUM_UITRON_TASKS
+#undef START_TASKS
+#define START_TASKS CYGNUM_UITRON_TASKS
+#endif
+
+#if START_TASKS <= 0
+#error Number of uITRON tasks to start initially must be >= 0
+#endif
+
+
+#define SET_UP_PTRS( _which_ ) CYG_MACRO_START                            \
+    for ( i = 0;                                                          \
+          (i < CYGNUM_UITRON_ ## _which_ ## _INITIALLY) &&                \
+          (i < CYGNUM_UITRON_ ## _which_              )    ;              \
+          i++ ) {                                                         \
+        CYG_UITRON_PTRS( _which_ )[ i ] = CYG_UITRON_OBJS( _which_ ) + i; \
+    }                                                                     \
+    if ( (CYGNUM_UITRON_ ## _which_ ## _INITIALLY)                        \
+          < (CYGNUM_UITRON_ ## _which_) )                                 \
+        for ( /* i as is */; i < CYGNUM_UITRON_ ## _which_ ; i++ ) {      \
+            CYG_UITRON_PTRS( _which_ )[ i ] = NULL;                       \
+        }                                                                 \
+CYG_MACRO_END
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
+Cyg_Clock::converter uit_clock_to_system;
+Cyg_Clock::converter uit_clock_from_system;
+#endif
+#endif
+
+void cyg_uitron_start( void )
+{
+    cyg_int32 i;
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
+    // initialize the clock converters
+    Cyg_Clock::real_time_clock->
+        get_other_to_clock_converter( 1000000, &uit_clock_to_system );
+    Cyg_Clock::real_time_clock->
+        get_clock_to_other_converter( 1000000, &uit_clock_from_system );
+#endif
+#endif
+
+    for ( i = 0; i < START_TASKS; i++ ) {
+#ifdef CYGIMP_THREAD_PRIORITY
+        // save the initial priority in our private array
+        cyg_uitron_task_initial_priorities[ i ] = 
+            cyg_uitron_TASKS[ i ].get_priority();
+#endif
+        // and awaken the task:
+        cyg_uitron_TASKS[ i ].resume();
+    }
+    for ( /* i as is */; i < CYGNUM_UITRON_TASKS; i++ ) {
+#ifdef CYGIMP_THREAD_PRIORITY
+        // save the initial priority in our private array
+        cyg_uitron_task_initial_priorities[ i ] = 
+            cyg_uitron_TASKS[ i ].get_priority();
+#endif
+        // but ensure the task state is dormant.
+        cyg_uitron_TASKS[ i ].kill();
+    }
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+    SET_UP_PTRS( TASKS );
+#endif
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+    SET_UP_PTRS( SEMAS );
+#endif
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+    SET_UP_PTRS( MBOXES );
+#endif
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+    SET_UP_PTRS( FLAGS );
+#endif
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+    SET_UP_PTRS( MEMPOOLFIXED );
+#endif
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+    SET_UP_PTRS( MEMPOOLVAR );
+#endif
+}
+
+// These allow programs to link when cyg_uitron_start() is called
+// (often because of CYGSEM_START_UITRON_COMPATIBILITY from infra,
+//  though we define these regardless just in case)
+// even when there is no interest in uITRON and so the tasks are
+// not externally defined; the reference to cyg_uitron_start()
+// ensures the tasks array et al are still included...
+extern "C" {
+    void task1( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
+    void task2( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
+    void task3( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
+    void task4( unsigned int arg ) CYGBLD_ATTRIB_WEAK;
+}
+
+void task1( unsigned int arg ) {}
+void task2( unsigned int arg ) {}
+void task3( unsigned int arg ) {}
+void task4( unsigned int arg ) {}
+
+#endif // CYGPKG_UITRON
+
+// EOF uit_func.cxx
diff --git a/packages/compat/uitron/v2_0/src/uit_ifnc.cxx b/packages/compat/uitron/v2_0/src/uit_ifnc.cxx
new file mode 100644 (file)
index 0000000..ca5caee
--- /dev/null
@@ -0,0 +1,140 @@
+//===========================================================================
+//
+//      uit_ifnc.cxx
+//
+//      uITRON compatibility functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON compatibility functions for use in ISRs
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+
+#ifdef CYGPKG_UITRON
+
+// invoke the inline function definition to create static C linkage
+// functions here:
+#define CYGIMP_UITRON_INLINE_FUNCS 1
+#include <cyg/compat/uitron/uit_func.h>
+
+// Now ensure that we create *outline* funcs for the ixxx_yyy() functions
+// here, with C names or whatever, as required.
+
+#undef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+#undef CYGIMP_UITRON_INLINE_FUNCS
+#undef CYG_UIT_FUNC_EXTERN_BEGIN
+#undef CYG_UIT_FUNC_EXTERN_END
+
+#ifdef CYGIMP_UITRON_CPP_OUTLINE_FUNCS
+#define CYG_UIT_FUNC_EXTERN_BEGIN       extern "C++" {
+#define CYG_UIT_FUNC_EXTERN_END         }
+#else
+#define CYG_UIT_FUNC_EXTERN_BEGIN       extern "C" {
+#define CYG_UIT_FUNC_EXTERN_END         }
+#endif
+
+// Get extern C prototypes (or whatever uit_func.h above did)
+#include <cyg/compat/uitron/uit_ifnc.h>
+
+#undef  CYG_UIT_FUNC_INLINE
+#define CYG_UIT_FUNC_INLINE /* blank */
+#define CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+#include <cyg/compat/uitron/uit_ifnc.inl>
+
+volatile int cyg_uit_dsr_actions_head = 0;
+volatile int cyg_uit_dsr_actions_tail = 0;
+
+Cyg_Uit_Action::action
+cyg_uit_dsr_actions[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
+
+ID
+cyg_uit_dsr_act_ids[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
+
+CYG_ADDRWORD
+cyg_uit_dsr_act_a1s[ CYGNUM_UITRON_ISR_ACTION_QUEUESIZE ];
+
+void
+cyg_uitron_dsr( unsigned int vector, unsigned int count, unsigned int data )
+{
+    while ( cyg_uit_dsr_actions_tail != cyg_uit_dsr_actions_head ) {
+        switch ( cyg_uit_dsr_actions[ cyg_uit_dsr_actions_tail ] ) {
+        case Cyg_Uit_Action::WUP_TSK:
+            (void)wup_tsk( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ] );
+            break;
+#ifdef CYGPKG_UITRON_SEMAS
+#if 0 < CYG_UITRON_NUM( SEMAS )
+        case Cyg_Uit_Action::SIG_SEM:
+            (void)sig_sem( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ] );
+            break;
+#endif // 0 < CYG_UITRON_NUM( SEMAS )
+#endif // CYGPKG_UITRON_SEMAS
+#ifdef CYGPKG_UITRON_FLAGS
+#if 0 < CYG_UITRON_NUM( FLAGS )
+        case Cyg_Uit_Action::SET_FLG:
+            (void)set_flg( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ],
+                     (UINT)cyg_uit_dsr_act_a1s[ cyg_uit_dsr_actions_tail ] );
+            break;
+#endif // 0 < CYG_UITRON_NUM( FLAGS )
+#endif // CYGPKG_UITRON_FLAGS
+#ifdef CYGPKG_UITRON_MBOXES
+#if 0 < CYG_UITRON_NUM( MBOXES )
+        case Cyg_Uit_Action::SND_MSG:
+            (void)snd_msg( cyg_uit_dsr_act_ids[ cyg_uit_dsr_actions_tail ],
+                  (T_MSG *)cyg_uit_dsr_act_a1s[ cyg_uit_dsr_actions_tail ] );
+            break;
+#endif // 0 < CYG_UITRON_NUM( MBOXES )
+#endif // CYGPKG_UITRON_MBOXES
+        default:
+            CYG_FAIL( "enum Cyg_Uit_Action out of range!" );
+        }
+        cyg_uit_dsr_actions_tail =
+            CYGNUM_UITRON_ISR_ACTION_QUEUEMASK & (1+cyg_uit_dsr_actions_tail);
+    }
+}
+
+#endif // CYGPKG_UITRON
+
+// EOF uit_ifnc.cxx
diff --git a/packages/compat/uitron/v2_0/src/uit_objs.cxx b/packages/compat/uitron/v2_0/src/uit_objs.cxx
new file mode 100644 (file)
index 0000000..3d49012
--- /dev/null
@@ -0,0 +1,382 @@
+//===========================================================================
+//
+//      uit_objs.cxx
+//
+//      uITRON static objects
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON static system objects
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+
+#ifdef CYGPKG_UITRON
+
+#include <cyg/compat/uitron/uit_objs.hxx>
+                                        // declarations of the objects
+                                        // we define below, and everything
+                                        // we need to specify them.
+
+#include <cyg/hal/hal_arch.h>           // for CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+// ------------------------------------------------------------------------
+// Mboxes have no initializer.
+#ifdef CYGPKG_UITRON_MBOXES
+#if 0 < CYGNUM_UITRON_MBOXES
+Cyg_Mbox                CYG_UITRON_DECL( MBOXES );
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+Cyg_Mbox                *CYG_UITRON_DECL_PTRS( MBOXES );
+#endif
+#endif
+#endif // CYGPKG_UITRON_MBOXES
+
+// ------------------------------------------------------------------------
+// Flags have no initializer.
+#ifdef CYGPKG_UITRON_FLAGS
+#if 0 < CYGNUM_UITRON_FLAGS
+Cyg_Flag                CYG_UITRON_DECL( FLAGS );
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+Cyg_Flag                *CYG_UITRON_DECL_PTRS( FLAGS );
+#endif
+#endif
+#endif // CYGPKG_UITRON_FLAGS
+
+// ------------------------------------------------------------------------
+// Semaphores have an optional initializer.
+#ifdef CYGPKG_UITRON_SEMAS
+#if (0 < CYGNUM_UITRON_SEMAS) || \
+    defined( CYGDAT_UITRON_SEMA_INITIALIZERS )
+
+#ifndef CYGNUM_UITRON_SEMAS
+#error You must define CYGNUM_UITRON_SEMAS
+#endif
+
+Cyg_Counting_Semaphore2 CYG_UITRON_DECL( SEMAS )
+
+#ifdef CYGDAT_UITRON_SEMA_INITIALIZERS
+// a Macro to ease the construction:
+#define CYG_UIT_SEMA( _count_  ) Cyg_Counting_Semaphore2( (cyg_count32)(_count_) )
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+#define CYG_UIT_SEMA_NOEXS       Cyg_Counting_Semaphore2( (cyg_count32)    0     )
+#endif
+ = {
+    CYGDAT_UITRON_SEMA_INITIALIZERS
+}
+#undef CYG_UIT_SEMA
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+#undef CYG_UIT_SEMA_NOEXS
+#endif
+#endif // do we have initializers?
+; // the end of the declaration, with or without initializer
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+Cyg_Counting_Semaphore2 *CYG_UITRON_DECL_PTRS( SEMAS );
+#endif
+#endif
+#endif // CYGPKG_UITRON_SEMAS
+
+// ------------------------------------------------------------------------
+// tasks MUST be initialized, you must have some.
+#ifndef CYGDAT_UITRON_TASK_EXTERNS
+#error You must define CYGDAT_UITRON_TASK_EXTERNS
+#endif
+#ifndef CYGDAT_UITRON_TASK_INITIALIZERS
+#error You must define CYGDAT_UITRON_TASK_INITIALIZERS
+#endif
+#ifndef CYGNUM_UITRON_TASKS
+#error You must define CYGNUM_UITRON_TASKS
+#endif
+
+// a Macro to ease the construction:
+//      "name", priority, proc, stackbase, stacksize
+#define CYG_UIT_TASK( _name_, _prio_, _func_, _sb_, _ss_ ) \
+  Cyg_Thread(                           \
+        (CYG_ADDRWORD)(_prio_),         \
+        (_func_),                       \
+        (CYG_ADDRWORD)0,                \
+        _name_,                         \
+        (CYG_ADDRESS)(_sb_),            \
+        (cyg_ucount32)(_ss_) )
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+#define CYG_UIT_TASK_NOEXS( _name_, _sb_, _ss_ ) \
+  Cyg_Thread(                           \
+        (CYG_ADDRWORD)(CYG_SCHED_DEFAULT_INFO), \
+        (cyg_thread_entry *)(0),        \
+        (CYG_ADDRWORD)0,                \
+        _name_,                         \
+        (CYG_ADDRESS)(_sb_),            \
+        (cyg_ucount32)(_ss_) )
+#endif
+
+// FIXME: Xscale tools currently in use have a preprocessor bug causing
+// the below #ifs to be misinterpreted. Therefore a *temporary*
+// workaround is included to define a MAX macro, and change
+// CYGDAT_UITRON_TASK_EXTERNS and CYGDAT_UITRON_TASK_INITIALISERS in
+// the CDL to use it.
+#ifdef XSCALECPPFIXEDSOMETIME
+
+#ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM
+# ifdef CYGNUM_UITRON_STACK_SIZE
+#  if CYGNUM_UITRON_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+// then override the configured stack size
+#   undef CYGNUM_UITRON_STACK_SIZE
+#   define CYGNUM_UITRON_STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+#  endif // CYGNUM_UITRON_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
+# endif // CYGNUM_UITRON_STACK_SIZE
+#endif // CYGNUM_HAL_STACK_SIZE_MINIMUM
+
+#else
+#define MAX(_x_,_y_) ((_x_) > (_y_) ? (_x_) : (_y_))
+#endif
+
+// declare the symbols used in the initializer
+CYGDAT_UITRON_TASK_EXTERNS
+
+Cyg_Thread      CYG_UITRON_DECL( TASKS ) =
+{
+    CYGDAT_UITRON_TASK_INITIALIZERS
+};
+
+#undef CYG_UIT_TASK
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+#undef CYG_UIT_TASK_NOEXS
+#endif
+
+#ifdef CYGIMP_THREAD_PRIORITY
+// An ancillary array of priorities, for managing the "original" prio
+cyg_priority
+cyg_uitron_task_initial_priorities[ CYG_UITRON_NUM( TASKS ) ];
+#endif
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+Cyg_Thread              *CYG_UITRON_DECL_PTRS( TASKS );
+#endif
+
+// ------------------------------------------------------------------------
+// fixed memory pools MUST be initialized, IF you have some.
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED
+#if (0 < CYGNUM_UITRON_MEMPOOLFIXED) || \
+    defined (CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS) || \
+    defined (CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS)
+
+#ifndef CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS
+#error You must define CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS
+#endif
+#ifndef CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS
+#error You must define CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS
+#endif
+#ifndef CYGNUM_UITRON_MEMPOOLFIXED
+#error You must define CYGNUM_UITRON_MEMPOOLFIXED
+#endif
+
+// declare the symbols used in the initializer
+CYGDAT_UITRON_MEMPOOLFIXED_EXTERNS
+
+// a Macro to ease the construction: addr, size, blocksize
+#define CYG_UIT_MEMPOOLFIXED( _a_, _s_, _bs_ ) Cyg_Mempool_Fixed( \
+    (cyg_uint8 *)(_a_), (cyg_int32)(_s_), (CYG_ADDRWORD)(_bs_) )
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+// note that this just picks a suitable size for the initialization, which
+// should not be too inefficient
+#define CYG_UIT_MEMPOOLFIXED_NOEXS( _a_, _s_ ) Cyg_Mempool_Fixed( \
+    (cyg_uint8 *)(_a_), (cyg_int32)(_s_), (CYG_ADDRWORD) ((~7)&((_s_)/2)) )
+#endif
+
+Cyg_Mempool_Fixed       CYG_UITRON_DECL( MEMPOOLFIXED ) =
+{
+    CYGDAT_UITRON_MEMPOOLFIXED_INITIALIZERS
+};
+#undef CYG_UIT_MEMPOOLFIXED
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+#undef CYG_UIT_MEMPOOLFIXED_NOEXS
+#endif
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+Cyg_Mempool_Fixed       *CYG_UITRON_DECL_PTRS( MEMPOOLFIXED );
+#endif
+#endif // do we have fixed memory pools at all?
+#endif // CYGPKG_UITRON_MEMPOOLFIXED
+
+// ------------------------------------------------------------------------
+// variable memory pools MUST be initialized, IF you have some.
+#ifdef CYGPKG_UITRON_MEMPOOLVAR
+#if (0 < CYGNUM_UITRON_MEMPOOLVAR) || \
+    defined (CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS) || \
+    defined (CYGDAT_UITRON_MEMPOOLVAR_EXTERNS)
+
+#ifndef CYGDAT_UITRON_MEMPOOLVAR_EXTERNS
+#error You must define CYGDAT_UITRON_MEMPOOLVAR_EXTERNS
+#endif
+#ifndef CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS
+#error You must define CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS
+#endif
+#ifndef CYGNUM_UITRON_MEMPOOLVAR
+#error You must define CYGNUM_UITRON_MEMPOOLVAR
+#endif
+
+// declare the symbols used in the initializer
+CYGDAT_UITRON_MEMPOOLVAR_EXTERNS
+
+// a Macro to ease the construction: addr, size
+#define CYG_UIT_MEMPOOLVAR( _a_, _s_ ) Cyg_Mempool_Variable( \
+    (cyg_uint8 *)(_a_),(cyg_int32)(_s_))
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+#define CYG_UIT_MEMPOOLVAR_NOEXS( _a_, _s_ ) Cyg_Mempool_Variable( \
+    (cyg_uint8 *)(_a_),(cyg_int32)(_s_))
+#endif
+
+Cyg_Mempool_Variable CYG_UITRON_DECL( MEMPOOLVAR ) =
+{
+    CYGDAT_UITRON_MEMPOOLVAR_INITIALIZERS
+};
+#undef CYG_UIT_MEMPOOLVAR
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+#undef CYG_UIT_MEMPOOLVAR_NOEXS
+#endif
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+Cyg_Mempool_Variable    *CYG_UITRON_DECL_PTRS( MEMPOOLVAR );
+#endif
+#endif // do we have variable memory pools at all?
+#endif // CYGPKG_UITRON_MEMPOOLVAR
+
+// ------------------------------------------------------------------------
+// Cyclic alarm handlers might be initialized, if you have some.
+//
+#ifdef CYGPKG_UITRON_CYCLICS
+#if (0 < CYGNUM_UITRON_CYCLICS) || \
+    defined( CYGDAT_UITRON_CYCLIC_EXTERNS ) || \
+    defined( CYGDAT_UITRON_CYCLIC_INITIALIZERS )
+
+#ifndef CYGNUM_UITRON_CYCLICS
+#error You must define CYGNUM_UITRON_CYCLICS
+#endif
+
+#if defined( CYGDAT_UITRON_CYCLIC_INITIALIZERS ) || \
+    defined( CYGDAT_UITRON_CYCLIC_EXTERNS )
+
+#ifndef CYGDAT_UITRON_CYCLIC_INITIALIZERS
+#error You must define CYGDAT_UITRON_CYCLIC_INITIALIZERS
+#endif
+#ifndef CYGDAT_UITRON_CYCLIC_EXTERNS
+#error You must define CYGDAT_UITRON_CYCLIC_EXTERNS
+#endif
+
+// declare the symbols used in the initializer
+CYGDAT_UITRON_CYCLIC_EXTERNS
+
+#endif // have externs or initializers
+
+Cyg_Timer               CYG_UITRON_DECL( CYCLICS )
+
+#ifdef CYGDAT_UITRON_CYCLIC_INITIALIZERS
+
+#error *** CYCLIC INITIALIZERS ARE NOT SUPPORTED IN THIS RELEASE***
+
+// a Macro to ease the construction: proc, arg, time
+#define CYG_UIT_CYCLIC( ... ) Cyg_Timer()
+ = {
+    CYGDAT_UITRON_CYCLIC_INITIALIZERS
+}
+#undef CYG_UIT_CYCLIC
+#endif // do we have initializers?
+; // the end of the declaration, with or without initializer
+
+#endif // do we have cyclic alarms at all?
+#endif // CYGPKG_UITRON_CYCLICS
+
+// ------------------------------------------------------------------------
+// Oneshot alarm handlers might be initialized, if you have some.
+//
+#ifdef CYGPKG_UITRON_ALARMS
+#if (0 < CYGNUM_UITRON_ALARMS) || \
+    defined( CYGDAT_UITRON_ALARM_EXTERNS ) || \
+    defined( CYGDAT_UITRON_ALARM_INITIALIZERS )
+
+#ifndef CYGNUM_UITRON_ALARMS
+#error You must define CYGNUM_UITRON_ALARMS
+#endif
+
+#if defined( CYGDAT_UITRON_ALARM_INITIALIZERS ) || \
+    defined( CYGDAT_UITRON_ALARM_EXTERNS )
+
+#ifndef CYGDAT_UITRON_ALARM_INITIALIZERS
+#error You must define CYGDAT_UITRON_ALARM_INITIALIZERS
+#endif
+#ifndef CYGDAT_UITRON_ALARM_EXTERNS
+#error You must define CYGDAT_UITRON_ALARM_EXTERNS
+#endif
+
+// declare the symbols used in the initializer
+CYGDAT_UITRON_ALARM_EXTERNS
+
+#endif // have externs or initializers
+
+Cyg_Timer               CYG_UITRON_DECL( ALARMS )
+
+#ifdef CYGDAT_UITRON_ALARM_INITIALIZERS
+
+#error *** ALARM INITIALIZERS ARE NOT SUPPORTED IN THIS RELEASE***
+
+// a Macro to ease the construction: proc, arg, time
+#define CYG_UIT_ALARM( ... ) Cyg_Timer()
+ = {
+    CYGDAT_UITRON_ALARM_INITIALIZERS
+}
+#undef CYG_UIT_ALARM
+#endif // do we have initializers?
+; // the end of the declaration, with or without initializer
+
+#endif // do we have oneshot alarms at all?
+#endif // CYGPKG_UITRON_ALARMS
+
+// ------------------------------------------------------------------------
+#endif // CYGPKG_UITRON
+
+// EOF uit_objs.cxx
diff --git a/packages/compat/uitron/v2_0/tests/test1.c b/packages/compat/uitron/v2_0/tests/test1.c
new file mode 100644 (file)
index 0000000..bf1228a
--- /dev/null
@@ -0,0 +1,815 @@
+//===========================================================================
+//
+//      test1.c
+//
+//      uITRON "C" test program one
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercom = 0;
+volatile int intercount = 0;
+INT scratch = 0;
+
+#ifndef CYGSEM_KERNEL_SCHED_TIMESLICE
+#define TIMESLICEMSG "Assuming no kernel timeslicing"
+#define TSGO()          (1)
+#define TSRELEASE()     CYG_EMPTY_STATEMENT
+#define TSSTOP()        CYG_EMPTY_STATEMENT
+#define TSLOCK()        CYG_EMPTY_STATEMENT
+#define TSUNLOCK()      CYG_EMPTY_STATEMENT
+#define ICWAIT( _i_ )   CYG_EMPTY_STATEMENT
+
+#else
+// Now follow some nasty bodges to control the scheduling when basically it
+// isn't controlled ie. timeslicing is on.  It's bodgy because we're
+// testing normal synchronization methods, so we shouldn't rely on them for
+// comms between threads here.  Instead there's a mixture of communicating
+// via a flag (ts_interlock) which stops the "controlled" thread running
+// away, and waiting for the controlled thread to run enough for us.
+//
+// Tasks 3 and 4 are waited for by the control task: task 3 locks the
+// scheduler so is immediately descheduled when it unlocks it, task 4 does
+// waiting-type operations, so we must give it chance to run by yielding a
+// few times ourselves.  Note the plain constant in ICWAIT() below.
+
+#define TIMESLICEMSG "Assuming kernel timeslicing ENABLED"
+volatile int ts_interlock = 0;
+#define TSGO()          (ts_interlock)
+#define TSRELEASE()     ts_interlock = 1
+#define TSSTOP()        ts_interlock = 0
+
+#define TSLOCK()        CYG_MACRO_START                                 \
+    ER ercd2 = dis_dsp();                                               \
+    CYG_TEST_CHECK( E_OK == ercd2, "dis_dsp (TSLOCK) bad ercd2" );      \
+CYG_MACRO_END
+
+#define TSUNLOCK()      CYG_MACRO_START                                 \
+    ER ercd3 = ena_dsp();                                               \
+    CYG_TEST_CHECK( E_OK == ercd3, "ena_dsp (TSUNLOCK) bad ercd3" );    \
+CYG_MACRO_END
+
+#define ICWAIT( _i_ )   CYG_MACRO_START                                 \
+    int loops;                                                          \
+    for ( loops = 3; (0 < loops) || ((_i_) > intercount); loops-- ) {   \
+        ER ercd4 = rot_rdq( 0 ); /* yield */                            \
+        CYG_TEST_CHECK( E_OK == ercd4, "rot_rdq (ICWAIT) bad ercd4" );  \
+    }                                                                   \
+CYG_MACRO_END
+#endif // CYGSEM_KERNEL_SCHED_TIMESLICE
+
+/*
+#define IC() \
+CYG_MACRO_START \
+  static char *msgs[] = { "ZERO", "ONE", "TWO", "THREE", "FOUR", "LOTS" }; \
+  CYG_TEST_INFO( msgs[ intercount > 5 ? 5 : intercount ] ); \
+CYG_MACRO_END
+*/
+
+// #define CYG_TEST_UITRON_TEST1_LOOPING 1
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    T_RTSK ref_tskd;
+
+#ifdef CYG_TEST_UITRON_TEST1_LOOPING
+    while ( 1 ) {
+#endif // CYG_TEST_UITRON_TEST1_LOOPING
+
+    CYG_TEST_INFO( "Task 1 running" );
+    CYG_TEST_INFO( TIMESLICEMSG );
+
+    intercom = 0;
+    intercount = 0;
+
+    CYG_TEST_INFO( "Testing get_tid and ref_tsk" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = get_tid( NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_tid bad ercd !E_PAR" );
+#endif
+    ercd = get_tid( NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_tid bad ercd !E_PAR" );
+    ercd = ref_tsk( &ref_tskd, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
+    ercd = ref_tsk( &ref_tskd, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_tsk( NULL, 1 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_tsk bad ercd !E_PAR" );
+#endif
+    ercd = ref_tsk( NADR, 1 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_tsk bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    ercd = ref_tsk( &ref_tskd, 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 1" );
+    ercd = ref_tsk( &ref_tskd, 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 0" );
+    ercd = ref_tsk( &ref_tskd, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
+    CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
+
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
+
+    CYG_TEST_PASS( "get_tid, ref_tsk" );
+
+    CYG_TEST_INFO( "Testing prio change and start task" );
+    ercd = sta_tsk( 2, 99 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+
+    // drop pri of task 2
+    ercd = chg_pri( 2, 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ref_tsk( &ref_tskd, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RDY == ref_tskd.tskstat, "Bad task status 2" );
+    CYG_TEST_CHECK( 4 == ref_tskd.tskpri, "Bad task prio 2" );
+
+    // drop our pri below task 2
+    ercd = chg_pri( 0, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+
+    ercd = ref_tsk( &ref_tskd, 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 1" );
+    ercd = ref_tsk( &ref_tskd, 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 0" );
+    ercd = ref_tsk( &ref_tskd, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    // it will have run to completion and regained its original prio
+    CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
+    CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
+
+    // retest these now that the task has executed once
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = chg_pri( -6, 9 );
+    CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
+    ercd = chg_pri( 99, 9 );
+    CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
+    ercd = sta_tsk( -6, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
+    ercd = sta_tsk( 99, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
+#endif // we can test bad param error returns
+
+    CYG_TEST_PASS( "sta_tsk, chg_pri" );
+
+    CYG_TEST_INFO( "Testing delay and dispatch disabling" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    CYG_TEST_PASS( "dly_tsk, ena_dsp, dis_dsp" );
+    
+    CYG_TEST_INFO( "Testing ready queue manipulation" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ercd = rot_rdq( 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ercd = rot_rdq( 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rot_rdq( -6 );
+    CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
+    ercd = rot_rdq( 99 );
+    CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    
+    CYG_TEST_PASS( "rot_rdq" );
+
+    CYG_TEST_INFO( "Testing suspend/resume" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = sus_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
+    ercd = sus_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
+    ercd = rsm_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
+    ercd = rsm_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
+    ercd = frsm_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
+    ercd = frsm_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // drop task 3 pri to same as us
+    CYG_TEST_CHECK( 0 == intercount, "intercount != 0" );
+
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 3, 66 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 3, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 1 );
+    CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
+    ercd = sus_tsk( 3 );
+    TSRELEASE();
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    intercom = 0;                       // bad data to T3
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = rsm_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 2 );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+
+    CYG_TEST_INFO( "Command task 3 inner loop stop" );
+    intercom = 2 + 4;
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    
+    ercd = sus_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    intercom = 0;                       // bad data to T3
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ercd = sus_tsk( 3 );                // suspend AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    ercd = sus_tsk( 3 );                //     AND AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    ercd = rsm_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = rsm_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = rsm_tsk( 3 );                // expect restart this time
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 3 );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+
+    CYG_TEST_INFO( "Command task 3 inner loop stop 2" );
+    intercom = 2 + 4;
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    
+    ercd = sus_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    intercom = 0;                       // bad data to T3
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    ercd = sus_tsk( 3 );                // suspend AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    ercd = sus_tsk( 3 );                //     AND AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = frsm_tsk( 3 );               // expect restart this time
+    CYG_TEST_CHECK( E_OK == ercd, "frsm_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 4 );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+
+    TSRELEASE();
+    ercd = rsm_tsk( 3 );               // try it again
+    CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk bad ercd !E_OBJ" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 5 );
+    CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
+
+    TSRELEASE();
+    ercd = frsm_tsk( 3 );               // try it again
+    CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk bad ercd !E_OBJ" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 6 );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+
+    CYG_TEST_INFO( "Command task 3 all loops stop" );
+    intercom = 4 + 8;
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+    
+    intercom = intercount = 0;
+
+    CYG_TEST_PASS( "sus_tsk, rsm_tsk, frsm_tsk" );
+
+    CYG_TEST_INFO( "Testing sleep/wakeup stuff" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = wup_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
+    ercd = wup_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
+    ercd = can_wup( &scratch, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
+    ercd = can_wup( &scratch, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = can_wup( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "can_wup bad ercd !E_PAR" );
+#endif
+    ercd = can_wup( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "can_wup bad ercd !E_PAR" );
+    
+    ercd = wup_tsk( 0 );                // not ourself
+    CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
+    ercd = wup_tsk( 1 );                // ourself
+    CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk bad ercd !E_OBJ" );
+#endif // we can test bad param error returns
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = tslp_tsk( -6 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    ercd = tslp_tsk( TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+    ercd = tslp_tsk( 5 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = tslp_tsk( TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
+     ercd = tslp_tsk( TMO_POL );
+    CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
+    ercd = tslp_tsk( 5 );
+    CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = tslp_tsk( -6 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    ercd = tslp_tsk( TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+    ercd = tslp_tsk( 5 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+
+    // drop task 4 pri to same as us
+    intercount = 0;
+    intercom = 1;                       // test plain slp_tsk
+    TSRELEASE();
+    ercd = chg_pri( 4, 5 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "chg_pri bad ercd" );
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 4, 77 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 4, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+
+    ercd = wup_tsk( 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 1 );
+    CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
+    intercom = 2;                       // test tslp_tsk
+    TSRELEASE();
+    ercd = wup_tsk( 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 2 );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    intercom = 3;                       // test tslp_tsk
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    intercom = 1;                       // test slp_tsk next...
+    ercd = dly_tsk( 20 );               // without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ICWAIT( 3 );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+
+    intercom = 1;                       // ...test slp_tsk
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // without a wup (yet)
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    TSRELEASE();
+    ercd = tslp_tsk( 20 );              // yield again
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // and again
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );                // and yield
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 4 );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+
+    intercom = 1;                       // test slp_tsk
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // without a wup (yet)
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+
+    // this wup will restart it when we yield:
+    TSLOCK();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    // these will count up:
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    scratch = -1;
+    ercd = can_wup( &scratch, 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "Cancelled wups not 2" );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+    TSUNLOCK();
+
+    intercom = 4;                       // do nothing
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // and yield
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 5 );
+    CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // let it do nothing
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // lots of wups but no sleep
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
+    scratch = -1;
+    ercd = can_wup( &scratch, 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
+    CYG_TEST_CHECK( 3 == scratch, "Cancelled wups not 3" );
+    // now check that they are cancelled by doing a wait again
+    intercom = 1;                       // test slp_tsk
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // still without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // still without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    intercom = 4;                       // do nothing next
+    TSRELEASE();
+    ICWAIT( 6 );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+    ercd = rot_rdq( 0 );                // still without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );                // it will run now
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // it will run now
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 7 );
+    CYG_TEST_CHECK( 7 == intercount, "intercount != 7" );
+
+    TSRELEASE();
+    intercom = 99;                      // exit, all done
+    ercd = rot_rdq( 0 );                // let it run
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 8 );
+    CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
+
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // let it run
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
+   
+    CYG_TEST_PASS( "wup_tsk, can_wup, slp_tsk, tslp_tsk" );
+
+#ifdef CYG_TEST_UITRON_TEST1_LOOPING
+    chg_pri( 1, 1 );
+    rot_rdq( 0 );
+    ter_tsk( 2 );
+    rot_rdq( 0 );
+    ter_tsk( 3 );
+    rot_rdq( 0 );
+    ter_tsk( 4 );
+    rot_rdq( 0 );
+    }
+#endif // CYG_TEST_UITRON_TEST1_LOOPING
+
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    CYG_TEST_PASS( "Task 2 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
+    if ( 99 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 99" );
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 2 failed to exit" );
+}
+
+void task3( unsigned int arg )
+{
+    ER ercd;
+    TSLOCK();
+    CYG_TEST_PASS("Task3 running");
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
+    if ( 66 != arg )
+        CYG_TEST_FAIL( "Task 3 arg not 66" );
+
+    while ( 2 & intercom ) {
+        while ( 1 & intercom ) {
+            intercount++;
+            TSSTOP();
+            do {
+                TSUNLOCK();
+                ercd = rot_rdq( 0 );        // yield()
+                TSLOCK();
+                CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 1 (task3) bad ercd" );
+            } while ( !TSGO() );
+        }
+        CYG_TEST_CHECK( 4 & intercom, "should not have got here yet 1" );
+        TSSTOP();
+        do {
+            TSUNLOCK();
+            ercd = rot_rdq( 0 );            // yield()
+            TSLOCK();
+            CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 2 (task3) bad ercd" );
+        } while ( !TSGO() );
+    }
+    CYG_TEST_CHECK( 8 & intercom, "should not have got here yet 2" );
+    
+    TSUNLOCK();
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 3 failed to exit" );
+}
+
+void task4( unsigned int arg )
+{
+    ER ercd;
+    CYG_TEST_PASS("Task4 running");
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
+    if ( 77 != arg )
+        CYG_TEST_FAIL( "Task 4 arg not 77" );
+    while ( 1 ) {
+        switch ( intercom ) {
+        case 1:
+            ercd = slp_tsk();
+            CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
+            break;
+        case 2:
+            ercd = tslp_tsk( 10 );
+            CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
+            break;
+        case 3:
+            ercd = tslp_tsk( 10 );
+            CYG_TEST_CHECK( E_TMOUT == ercd,
+                            "slp_tsk (task4) bad ercd !E_TMOUT" );
+            break;
+        case 4:
+            // busily do nothing
+            while ( 4 == intercom ) {
+                ercd = rot_rdq( 0 );
+                CYG_TEST_CHECK( E_OK == ercd,
+                                "rot_rdq (task4 idle) bad ercd" );
+            }
+            break;
+        case 99:
+            goto out;
+        default:
+            CYG_TEST_FAIL( "Task 4 bad intercom" );
+            goto out;
+        }
+        intercount++;
+        TSSTOP();
+        do {
+            ercd = rot_rdq( 0 );            // yield()
+            CYG_TEST_CHECK( E_OK == ercd, "rot_rdq (task4) bad ercd" );
+        } while ( !TSGO() );
+    }
+out:
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 4 failed to exit" );
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test1.c
diff --git a/packages/compat/uitron/v2_0/tests/test2.c b/packages/compat/uitron/v2_0/tests/test2.c
new file mode 100644 (file)
index 0000000..ff7c556
--- /dev/null
@@ -0,0 +1,970 @@
+//===========================================================================
+//
+//      test2.c
+//
+//      uITRON "C" test program two
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+int intercom = 0;
+int intercount = 0;
+INT scratch = 0;
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+
+    T_RSEM sem_info;
+    T_RFLG flg_info;
+    T_RMBX mbx_info;
+    T_RMPF mpf_info;
+    T_RMPL mpl_info;
+    UINT flagptn;
+    static char foo[] = "Test message";
+    T_MSG *msgptr = (T_MSG *)foo;
+    T_MSG *rxptr = NULL;
+    VP blfptr = (VP)foo;
+    VP blkptr = (VP)foo;
+
+    int delay = 10;
+    if (cyg_test_is_simulator)
+        delay = 3;
+
+    CYG_TEST_INFO( "Task 1 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+    
+    // start a lower prio task to interact with
+    intercom = 1;
+    ercd = sta_tsk( 2, 222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    // Semaphores; all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing semaphore ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = sig_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
+    ercd = sig_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
+    ercd = wai_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
+    ercd = wai_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
+    ercd = preq_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
+    ercd = preq_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
+    ercd = twai_sem( -6, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
+    ercd = twai_sem( 99, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
+    ercd = twai_sem( 2, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_sem bad ercd !E_PAR" );
+    ercd = ref_sem( &sem_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
+    ercd = ref_sem( &sem_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_sem( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_sem bad ercd !E_PAR" );
+#endif
+    ercd = ref_sem( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_sem bad ercd !E_PAR" );
+    CYG_TEST_PASS( "bad calls: sig_sem, [t]wai_sem, preq_sem, ref_sem" );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = wai_sem( 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "wai_sem bad ercd !E_CTX" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_sem bad ercd !E_CTX" );
+    ercd = twai_sem( 2, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_sem(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = twai_sem( 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: wai_sem, twai_sem with dis_dsp" );
+
+    // check ref_sem with various states
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 2 == sem_info.semcnt, "semcnt should be 2" );
+    ercd = wai_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    intercom = 0;
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 != sem_info.wtsk, "sem.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be non0" );
+#if 1
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+#else // old, non-uITRON semantics
+    CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
+#endif
+    ercd = dly_tsk( delay );               // let task 2 pick up the signal
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    CYG_TEST_PASS( "good calls: sig_sem, [t]wai,preq_sem with ref_sem" );
+
+    // Flags; all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing flag ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = set_flg( -6, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
+    ercd = set_flg( 99, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
+    ercd = clr_flg( -6, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "clr_flg bad ercd !E_ID" );
+    ercd = clr_flg( 99, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "sig_flg bad ercd !E_ID" );
+    ercd = wai_flg( &flagptn, -6, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
+    ercd = wai_flg( &flagptn, 99, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = wai_flg( NULL, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
+#endif
+    ercd = wai_flg( NADR, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
+    ercd = wai_flg( &flagptn, 2, 7, 34657 );
+    CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
+    ercd = wai_flg( &flagptn, 2, 0, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
+    ercd = pol_flg( &flagptn, -6, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
+    ercd = pol_flg( &flagptn, 99, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = pol_flg( NULL, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
+#endif
+    ercd = pol_flg( NADR, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
+    ercd = pol_flg( &flagptn, 2, 7, 34657 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
+    ercd = pol_flg( &flagptn, 2, 0, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
+    ercd = twai_flg( &flagptn, -6, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
+    ercd = twai_flg( &flagptn, 99, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = twai_flg( NULL, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+#endif
+    ercd = twai_flg( NADR, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+    ercd = twai_flg( &flagptn, 2, 7, 34657, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+    ercd = twai_flg( &flagptn, 2, 0, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+    ercd = ref_flg( &flg_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
+    ercd = ref_flg( &flg_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_flg( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_flg bad ercd !E_PAR" );
+#endif
+    ercd = ref_flg( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_flg bad ercd !E_PAR" );
+    CYG_TEST_PASS( "bad calls: set_flg, clr_flg, [t]wai,pol_flg, ref_flg" );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = wai_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_CTX == ercd, "wai_flg bad ercd !E_CTX" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_flg bad ercd !E_CTX" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_flg(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
+    ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: wai_flg, twai_flg with dis_dsp" );
+
+    // check ref_flg with various states
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
+    ercd = set_flg( 2, 0x5555 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0x5555 == flg_info.flgptn, "flgptn should be 0x5555" );
+    ercd = clr_flg( 2, 0xF0F0 );
+    CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0x5050 == flg_info.flgptn, "flgptn should be 0x5050" );
+    ercd = set_flg( 2, 0xFFFF );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be 0" );
+    CYG_TEST_CHECK( 0xFFFF == flg_info.flgptn, "flgptn should be 0xFFFF" );
+    CYG_TEST_PASS( "good calls: clr_flg, set_flg, wai_flg with ref_flg" );
+
+    // Mailboxes; all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing mailbox ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = snd_msg( -6, msgptr );
+    CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
+    ercd = snd_msg( 99, msgptr );
+    CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = snd_msg( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "snd_msg bad ercd !E_PAR" );
+#endif
+    ercd = snd_msg( 2, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "snd_msg bad ercd !E_PAR" );
+    ercd = rcv_msg( &rxptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
+    ercd = rcv_msg( &rxptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = rcv_msg( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "rcv_msg bad ercd !E_PAR" );
+#endif
+    ercd = rcv_msg( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "rcv_msg bad ercd !E_PAR" );
+    ercd = prcv_msg( &rxptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
+    ercd = prcv_msg( &rxptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = prcv_msg( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "prcv_msg bad ercd !E_PAR" );
+#endif
+    ercd = prcv_msg( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "prcv_msg bad ercd !E_PAR" );
+    ercd = trcv_msg( &rxptr, -6, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
+    ercd = trcv_msg( &rxptr, 99, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
+    ercd = trcv_msg( &rxptr, 2, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = trcv_msg( NULL, 2, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
+#endif
+    ercd = trcv_msg( NADR, 2, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
+    ercd = ref_mbx( &mbx_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
+    ercd = ref_mbx( &mbx_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_mbx( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mbx bad ercd !E_PAR" );
+#endif
+    ercd = ref_mbx( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mbx bad ercd !E_PAR" );
+    CYG_TEST_PASS( "bad calls: snd_msg, [pt]rcv_msg, ref_mbx" );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = prcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "rcv_msg bad ercd !E_CTX" );
+    ercd = trcv_msg( &rxptr, 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg bad ercd !E_CTX" );
+    ercd = trcv_msg( &rxptr, 2, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = trcv_msg( &rxptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
+    ercd = prcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = prcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: rcv_msg, trcv_msg with dis_dsp" );
+
+    // check ref_mbx with various states
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 != mbx_info.wtsk, "mbx.wtsk should be non0" );
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+    ercd = snd_msg( 2, msgptr );
+    CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
+#if 1
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+#else // old, non-uITRON semantics
+    CYG_TEST_CHECK( msgptr == mbx_info.pk_msg, "mbx peek should be msgptr" );
+#endif
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+    // fill the message box, expect E_QOVR
+    for ( scratch = 0 ; scratch < 100 ; scratch++ ) {
+        if ( E_OK != ( ercd = snd_msg( 2, msgptr ) ) )
+            break;
+    }
+    CYG_TEST_CHECK( (100 == scratch) || (E_QOVR == ercd),
+                    "snd_msg bad ercd !E_QOVR/E_OK" );
+    // empty the message box, expect the right number and E_TMOUT
+    for (             ;     1         ; scratch-- ) {
+        if ( E_OK != ( ercd = prcv_msg( &rxptr, 2 ) ) )
+            break;
+    }
+    CYG_TEST_CHECK( 0 == scratch, "rcv_msg count bad scratch!=0" );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "rcv_msg bad ercd !E_TMOUT" );
+
+    CYG_TEST_PASS( "good calls: rcv_msg, snd_msg with ref_msg" );
+
+    // Fixed block memory pools: all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing fixed block memory ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_blf( -6, blfptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
+    ercd = rel_blf( 99, blfptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = rel_blf( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
+#endif
+    ercd = rel_blf( 2, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    ercd = rel_blf( 2, blfptr );        // it did not come from a mpf
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blf( &blfptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
+    ercd = get_blf( &blfptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = get_blf( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_blf bad ercd !E_PAR" );
+#endif
+    ercd = get_blf( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_blf bad ercd !E_PAR" );
+    ercd = pget_blf( &blfptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
+    ercd = pget_blf( &blfptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = pget_blf( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pget_blf bad ercd !E_PAR" );
+#endif
+    ercd = pget_blf( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pget_blf bad ercd !E_PAR" );
+    ercd = tget_blf( &blfptr, -6, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
+    ercd = tget_blf( &blfptr, 99, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
+    ercd = tget_blf( &blfptr, 2, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = tget_blf( NULL, 2, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
+#endif
+    ercd = tget_blf( NADR, 2, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
+    ercd = ref_mpf( &mpf_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
+    ercd = ref_mpf( &mpf_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_mpf( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mpf bad ercd !E_PAR" );
+#endif
+    ercd = ref_mpf( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mpf bad ercd !E_PAR" );
+    CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf, ref_mpf " );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    // consume the whole thing then do it again, expecting E_TMOUT
+    while ( E_OK == (ercd = pget_blf( &blfptr, 2 ) ) )
+        continue;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
+    ercd = tget_blf( &blfptr, 2, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blf(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = tget_blf( &blfptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf with ena_dsp" );
+
+    // check ref_mpf with various states
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 != mpf_info.wtsk, "mpf.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
+#if 1
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+#else // old, non-uITRON semantics
+    CYG_TEST_CHECK( 0 != mpf_info.frbcnt, "mpf.frbcnt should be non0" );
+#endif
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+    CYG_TEST_PASS( "good calls: rel_blf, get_blf with ref_mpf" );
+
+    // Variable block memory pools; illegal arguments
+    CYG_TEST_INFO( "Testing variable block memory ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_blk( -6, blkptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
+    ercd = rel_blk( 99, blkptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = rel_blk( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
+#endif
+    ercd = rel_blk( 2, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    ercd = rel_blk( 2, blkptr );        // it did not come from a mpl
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blk( &blkptr, -6, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
+    ercd = get_blk( &blkptr, 99, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = get_blk( NULL, 2, 100 );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_blk bad ercd !E_PAR" );
+#endif
+    ercd = get_blk( NADR, 2, 100 );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_blk bad ercd !E_PAR" );
+    ercd = pget_blk( &blkptr, -6, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
+    ercd = pget_blk( &blkptr, 99, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = pget_blk( NULL, 2, 100 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pget_blk bad ercd !E_PAR" );
+#endif
+    ercd = pget_blk( NADR, 2, 100 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pget_blk bad ercd !E_PAR" );
+    ercd = tget_blk( &blkptr, -6, 100, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
+    ercd = tget_blk( &blkptr, 99, 100, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
+    ercd = tget_blk( &blkptr, 2, 100, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = tget_blk( NULL, 2, 100, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
+#endif
+    ercd = tget_blk( NADR, 2, 100, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
+    ercd = ref_mpl( &mpl_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
+    ercd = ref_mpl( &mpl_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_mpl( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mpl bad ercd !E_PAR" );
+#endif
+    ercd = ref_mpl( NADR, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mpl bad ercd !E_PAR" );
+    CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk, ref_mpl " );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    // consume the whole thing then do it again, expecting E_TMOUT
+    while ( E_OK == (ercd = pget_blk( &blkptr, 2, 100 ) ) )
+        continue;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
+    ercd = tget_blk( &blkptr, 2, 100, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blk(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk with ena_dsp" );
+
+    // check ref_mpl with various states
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
+    CYG_TEST_CHECK( mpl_info.maxsz <= mpl_info.frsz,
+                    "mpl.maxsz not < mpl.frsz" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 != mpl_info.wtsk, "mpl.wtsk should be non0" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
+    CYG_TEST_PASS( "good calls: rel_blk, get_blk with ref_mpl" );
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    T_MSG *msgp = NULL;
+    UINT flgval = 0;
+    VP blfp = NULL;
+    VP blkp = NULL;
+
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
+    if ( 222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 222" );
+
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = wai_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = wai_flg( &flgval, 2, 99, TWF_ANDW );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
+    CYG_TEST_CHECK( 99 == (99 & flgval), "flg value no good" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = rcv_msg( &msgp, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
+    CYG_TEST_CHECK( NULL != msgp, "no msg received" );
+    CYG_TEST_CHECK( NADR != msgp, "no msg received" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = get_blf( &blfp, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
+    CYG_TEST_CHECK( NULL != blfp, "no blf allocated" );
+    CYG_TEST_CHECK( NADR != blfp, "no blf allocated" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = get_blk( &blkp, 2, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
+    CYG_TEST_CHECK( NULL != blkp, "no blk allocated" );
+    CYG_TEST_CHECK( NADR != blkp, "no blk allocated" );
+
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 2 failed to exit" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test2.c
diff --git a/packages/compat/uitron/v2_0/tests/test3.c b/packages/compat/uitron/v2_0/tests/test3.c
new file mode 100644 (file)
index 0000000..69eb06e
--- /dev/null
@@ -0,0 +1,255 @@
+//===========================================================================
+//
+//      test3.c
+//
+//      uITRON "C" test program three
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+int t2done = 0;
+int t3done = 0;
+int t4done = 0;
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 1 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+    
+    // start lower prio tasks to interact with
+    ercd = sta_tsk( 2, 222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = sta_tsk( 3, 333 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = sta_tsk( 4, 444 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+
+    // now start the test
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    CYG_TEST_INFO( "T1 awoken" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    CYG_TEST_INFO( "T1 signalled" );
+    
+    // let the others complete, so we get the status back
+    ercd = dly_tsk( 50 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    
+    CYG_TEST_CHECK( t2done, "t2 not done" );
+    CYG_TEST_CHECK( t3done, "t3 not done" );
+    CYG_TEST_CHECK( t4done, "t4 not done" );
+
+    CYG_TEST_PASS( "Immediate-dispatch producer/consumer test OK" );
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
+    if ( 222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 222" );
+
+    // now start the test
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    CYG_TEST_INFO( "T2 awoken" );
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = wup_tsk( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+
+    CYG_TEST_INFO( "T2 completing" );
+    t2done++;
+
+    ercd = slp_tsk();
+    CYG_TEST_FAIL( "Task 2 sleep came back" );
+}
+
+void task3( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 3 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
+    if ( 333 != arg )
+        CYG_TEST_FAIL( "Task 3 arg not 333" );
+
+    // now start the test
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    CYG_TEST_INFO( "T3 awoken" );
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    
+    CYG_TEST_INFO( "T3 completing" );
+    t3done++;
+
+    ercd = slp_tsk();
+    CYG_TEST_FAIL( "Task 3 sleep came back" );
+}
+
+void task4( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 4 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
+    if ( 444 != arg )
+        CYG_TEST_FAIL( "Task 4 arg not 444" );
+
+    // now start the test
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+
+    CYG_TEST_INFO( "T4 completing" );
+    t4done++;
+
+    ercd = slp_tsk();
+    CYG_TEST_FAIL( "Task 4 sleep came back" );
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test3.c
diff --git a/packages/compat/uitron/v2_0/tests/test4.c b/packages/compat/uitron/v2_0/tests/test4.c
new file mode 100644 (file)
index 0000000..a589623
--- /dev/null
@@ -0,0 +1,403 @@
+//===========================================================================
+//
+//      test4.c
+//
+//      uITRON "C" test program four
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   dsm
+// Contributors:        dsm
+// Date:        1998-06-12
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough cyclic handlers */            \
+    defined( CYGPKG_UITRON_CYCLICS )                            && \
+    (CYGNUM_UITRON_CYCLICS >= 3)                                && \
+    (CYGNUM_UITRON_CYCLICS < 90)                                && \
+                                                                   \
+    /* test configuration for enough alarm handlers */             \
+    defined( CYGPKG_UITRON_ALARMS )                             && \
+    (CYGNUM_UITRON_ALARMS >= 3)                                 && \
+    (CYGNUM_UITRON_ALARMS < 90)                                 && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+INT scratch;
+
+void hand1(void)
+{
+    CYG_TEST_INFO("Handler 1 called");
+    intercount++;
+}
+
+void hand2(void)
+{
+    CYG_TEST_CHECK( 2 == intercount, "handler out of sync" );
+    CYG_TEST_INFO("Handler 2 called");
+    intercount++;
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+
+    T_DCYC dcyc;
+    T_DALM dalm;
+    T_RCYC rcyc;
+    T_RALM ralm;
+
+    unsigned int tm;
+
+    static char foo[] = "Test message";
+    VP info = (VP)foo;
+
+    // Increase times when running on HW since overhead of GDB packet
+    // acknowledgements may cause tests of timing to fail.
+    if (cyg_test_is_simulator)
+        tm = 1;
+    else
+        tm = 4;
+
+    CYG_TEST_INFO( "Task 1 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+
+    dcyc.exinf  = (VP)info;
+    dcyc.cycatr = TA_HLNG;
+    dcyc.cychdr = (FP)&hand1;
+    dcyc.cycact = TCY_INI;              // bad
+    dcyc.cyctim = 2;
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dcyc.cycact = TCY_OFF;              // make good
+    dcyc.cyctim = 0;                    // bad
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dcyc.cyctim = 1;                    // make good
+
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );    
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_cyc(-6, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+    ercd = def_cyc(99, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+
+    ercd = act_cyc(-6, TCY_OFF);
+    CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
+    ercd = act_cyc(99, TCY_OFF);
+    CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
+    ercd = act_cyc( 3, ~0);
+    CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
+    
+    ercd = ref_cyc(&rcyc, -6);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
+    ercd = ref_cyc(&rcyc, 99);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_cyc(NULL,  3);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
+#endif
+    ercd = ref_cyc(NADR,  3);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    ercd = def_cyc(3, (T_DCYC *)NADR);
+    CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = ref_cyc(&rcyc,  3);
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );    
+#endif // we can test bad param error returns
+
+    CYG_TEST_PASS( "bad calls: def_cyc, act_cyc, ref_cyc" );
+
+    dalm.exinf  = (VP)info;
+    dalm.almatr = TA_HLNG;
+    dalm.almhdr = (FP)&hand2;
+    dalm.tmmode = ~0;                   // bad
+    dalm.almtim = 20;
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dalm.tmmode = TTM_REL;              // make good
+    dalm.almtim = 0;                    // bad
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dalm.almtim = 1000;                 // make good
+
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = ref_alm(&ralm, -6);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
+    ercd = ref_alm(&ralm, 99);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_alm(NULL,  3);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
+#endif
+    ercd = ref_alm(NADR,  3);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
+
+#endif // we can test bad param error returns
+    ercd = def_alm(3, (T_DALM *)NADR);
+    CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = ref_alm(&ralm,  3);
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );    
+#endif // we can test bad param error returns
+
+    CYG_TEST_PASS( "bad calls: def_alm, act_alm, ref_alm" );
+    
+    dcyc.exinf  = (VP)info;
+    dcyc.cycatr = TA_HLNG;
+    dcyc.cychdr = (FP)&hand1;
+    dcyc.cycact = TCY_ON;
+    dcyc.cyctim = 50*tm;    
+    
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+    ercd = act_cyc(3, TCY_OFF);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
+    ercd = act_cyc(3, TCY_ON);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
+    
+    CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc");
+
+    dalm.exinf  = (VP)info;
+    dalm.almatr = TA_HLNG;
+    dalm.almhdr = (FP)&hand2;
+    dalm.tmmode = TTM_REL;
+    dalm.almtim = 120*tm;
+
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
+    ercd = ref_alm(&ralm, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_alm bad ercd" );
+    CYG_TEST_CHECK( info == ralm.exinf, "ralm.exinf should be info" );
+    CYG_TEST_CHECK( 115*tm < ralm.lfttim, "ralm.lfttim too small" );
+    CYG_TEST_CHECK( ralm.lfttim <= 120*tm, "ralm.lfttim too big" );
+
+    // Expect handlers to be called at approximate times
+    // time           intercount
+    // tm*50  hand1   0
+    // tm*100 hand1   1
+    // tm*120 hand2   2
+    // tm*150 hand1   3
+
+    ercd = dly_tsk(160*tm);
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 4 == intercount, "handlers not both called" );
+    
+    ercd = act_cyc(3, TCY_OFF);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(off) bad ercd" );
+
+    ercd = dly_tsk(60*tm);              // enough for at least one tick
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 4 == intercount, "cyclic not disabled" );
+
+    // approx time now 220, so we expect a cycle in about 30 ticks
+    ercd = act_cyc(3, TCY_ON);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 25*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 35*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+
+    // now resynchronize with right now:
+    ercd = act_cyc(3, TCY_ON|TCY_INI);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+
+    // wait a bit and check that time marches on, or even down
+    ercd = dly_tsk(10*tm);
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 35*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 45*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+
+    // now turn it off and re-synch with right now:
+    ercd = act_cyc(3, TCY_OFF|TCY_INI);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
+
+    ercd = act_cyc(3, TCY_OFF);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+
+    CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc, def_alm, ref_alm");
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test4.c
diff --git a/packages/compat/uitron/v2_0/tests/test5.c b/packages/compat/uitron/v2_0/tests/test5.c
new file mode 100644 (file)
index 0000000..4a86cc0
--- /dev/null
@@ -0,0 +1,353 @@
+//===========================================================================
+//
+//      test5.c
+//
+//      uITRON "C" test program five
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   dsm
+// Contributors:        dsm
+// Date:        1998-06-12
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+UINT scratch;
+T_MSG *t_msg;
+VP vp;
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    T_RSYS rsys;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    // check initial state
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+    // disable intrs and check state
+    ercd = loc_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // try an illegal op
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
+#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // enable intrs and check state and a legal sleep
+    ercd = unl_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+    ercd = dly_tsk( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    // disable intrs and try scheduler illegal ops
+    ercd = loc_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_CTX == ercd, "dis_dsp bad ercd !E_CTX" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_CTX == ercd, "ena_dsp bad ercd !E_CTX" );
+#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // enable again and check state
+    ercd = unl_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+    // disable the scheduler and check state
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_DDSP == rsys.sysstat, "system state not TSS_DDSP" );
+    // disable intrs and check state
+    ercd = loc_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
+    // then unlock and check state
+    ercd = unl_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+
+    CYG_TEST_PASS( "Interrupt dis/enabling and interactions" );
+
+    // and now we can do the rest of the test
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
+    ercd = rel_wai( 1 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
+    ercd = rel_wai( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
+    ercd = rel_wai( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
+#endif // we can test bad param error returns
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
+    ercd = rel_wai( 1 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
+#endif // we can test bad param error returns
+
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "wai_sem bad ercd !E_RLWAI" );
+
+    ercd = twai_sem( 1, 20 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "twai_sem bad ercd !E_RLWAI" );
+
+    ercd = wai_flg( &scratch, 1, 9999, 0 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "wai_flg bad ercd !E_RLWAI" );
+
+    ercd = twai_flg( &scratch, 1, 9999, 0, 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "twai_flg bad ercd !E_RLWAI" );
+
+    ercd = rcv_msg( &t_msg, 1 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "rcv_msg bad ercd !E_RLWAI" );
+
+    ercd = trcv_msg( &t_msg, 1, 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "trcv_msg bad ercd !E_RLWAI" );
+
+    // these are loops so as to consume the whole of the mempool
+    // in order to wait at the end
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = get_blf( &vp, 3 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "get_blf bad ercd !E_RLWAI" );
+
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = tget_blf( &vp, 3, 10 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blf bad ercd !E_RLWAI" );
+
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = get_blk( &vp, 1, 1000 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "get_blk bad ercd !E_RLWAI" );
+
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = tget_blk( &vp, 1, 1000, 10 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blk bad ercd !E_RLWAI" );
+
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "dly_tsk bad ercd !E_RLWAI" );
+
+    ercd = tslp_tsk( 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "tslp_tsk bad ercd !E_RLWAI" );
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_RLWAI == ercd, "slp_tsk bad ercd !E_RLWAI" );
+
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    CYG_TEST_PASS("release wait: various waiting calls");
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    for ( i = 0 ; i < 100; i++ ) {
+        ercd = rel_wai( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+    }        
+    // we expect task2 to be killed here
+    CYG_TEST_FAIL( "Task 2 ran to completion!" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test5.c
diff --git a/packages/compat/uitron/v2_0/tests/test6.c b/packages/compat/uitron/v2_0/tests/test6.c
new file mode 100644 (file)
index 0000000..c026d66
--- /dev/null
@@ -0,0 +1,599 @@
+//===========================================================================
+//
+//      test6.c
+//
+//      uITRON "C" test program six
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-01
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+UINT scratch;
+T_MSG *t_msg = (T_MSG *)&scratch;
+T_MSG *msg;
+VP vp;
+
+T_CSEM t_csem = { NULL, 0, 0 };
+T_CMBX t_cmbx = { NULL, 0 };
+T_CFLG t_cflg = { NULL, 0, 0 };
+T_RSEM t_rsem;
+T_RMBX t_rmbx;
+T_RFLG t_rflg;
+
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    int tests = 0;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
+    ercd = del_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
+    ercd = cre_sem( -6, &t_csem );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
+    ercd = cre_sem( 99, &t_csem );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_sem( 3, &t_csem );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_sem bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_sem( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    // check it is deleted
+    ercd = sig_sem( 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    ercd = preq_sem( 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "preq_sem bad ercd !E_NOEXS" );
+    ercd = twai_sem( 3, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "twai_sem bad ercd !E_NOEXS" );
+    ercd = wai_sem( 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wai_sem bad ercd !E_NOEXS" );
+    ercd = ref_sem( &t_rsem, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_sem bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_sem( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_sem bad ercd !E_PAR" );
+#endif
+    ercd = cre_sem( 3, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_sem bad ercd !E_PAR" );
+    t_csem.sematr = 0xfff;
+    ercd = cre_sem( 3, &t_csem );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_sem bad ercd !E_RSATR" );
+    t_csem.sematr = 0;
+#endif // we can test bad param error returns
+    ercd = cre_sem( 3, &t_csem );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+    // and check we can use it
+    ercd = sig_sem( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = wai_sem( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = preq_sem( 3 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 3, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
+    ercd = ref_sem( &t_rsem, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_sem( 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    // re-create and do it again
+    ercd = cre_sem( 1, &t_csem );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+    ercd = cre_sem( 2, &t_csem );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+
+    // now wait while task 2 deletes the wait objects again
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_sem( 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete semaphores");
+#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_flg( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
+    ercd = del_flg( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
+    ercd = cre_flg( -6, &t_cflg );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
+    ercd = cre_flg( 99, &t_cflg );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_flg bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_flg( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    // check it is deleted
+    ercd = set_flg( 3, 0x6789 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
+    ercd = clr_flg( 3, 0x9876 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
+    ercd = pol_flg( &scratch, 3, 0xdddd, TWF_ANDW );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pol_flg bad ercd !E_NOEXS" );
+    ercd = twai_flg( &scratch, 3, 0x4444, TWF_ORW, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "twai_flg bad ercd !E_NOEXS" );
+    ercd = wai_flg( &scratch, 3, 0xbbbb, TWF_ANDW | TWF_CLR );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wai_flg bad ercd !E_NOEXS" );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_flg bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_flg( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_flg bad ercd !E_PAR" );
+#endif
+    ercd = cre_flg( 3, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_flg bad ercd !E_PAR" );
+    t_cflg.flgatr = 0xfff;
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_flg bad ercd !E_RSATR" );
+#endif // we can test bad param error returns
+    // now create it well
+    t_cflg.flgatr = 0;
+    t_cflg.iflgptn = 0;
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+    // and check we can use it
+    ercd = clr_flg( 3, 0x7256 );
+    CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
+    ercd = set_flg( 3, 0xff );
+    CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
+    ercd = wai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
+    ercd = pol_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
+    // now create it again with a preset pattern and check that we can
+    // detect that pattern:
+    ercd = del_flg( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    t_cflg.flgatr = 0;
+    t_cflg.iflgptn = 0x1234;
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+    // and check we can use it
+    ercd = wai_flg( &scratch, 3, 0x1200, TWF_ANDW );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
+    ercd = pol_flg( &scratch, 3, 0x0034, TWF_ANDW );
+    CYG_TEST_CHECK( E_OK == ercd, "pol_flg bad ercd" );
+    ercd = twai_flg( &scratch, 3, 0x1004, TWF_ANDW, 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "twai_flg bad ercd" );
+    ercd = pol_flg( &scratch, 3, 0xffedcb, TWF_ORW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0x1234 == t_rflg.flgptn, "ref_flg bad ercd" );
+    ercd = clr_flg( 3, 0 );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
+
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_flg( &scratch, 1, 0xaa, TWF_ANDW );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_flg( &scratch, 2, 0x55, TWF_ANDW, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = set_flg( 1, 0x22 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
+    ercd = clr_flg( 2, 0xdd );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
+    // re-create and do it again
+    t_cflg.iflgptn = 0x5555;
+    ercd = cre_flg( 1, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+    t_cflg.iflgptn = 0;
+    ercd = cre_flg( 2, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+
+    // now wait while task 2 deletes the wait objects again
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_flg( &scratch, 1, 0xaaaa, TWF_ORW | TWF_CLR );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_flg( &scratch, 2, 0xffff, TWF_ORW, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = clr_flg( 1, 0xd00d );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
+    ercd = set_flg( 2, 0xfff00 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete flags");
+#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_mbx( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
+    ercd = del_mbx( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
+    ercd = cre_mbx( -6, &t_cmbx );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
+    ercd = cre_mbx( 99, &t_cmbx );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_mbx( 3, &t_cmbx );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_mbx bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_mbx( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    // check it is deleted
+    ercd = snd_msg( 3, t_msg );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    ercd = rcv_msg( &msg, 3 );       
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rcv_msg bad ercd !E_NOEXS" );
+    ercd = trcv_msg( &msg, 3, 10 );   
+    CYG_TEST_CHECK( E_NOEXS == ercd, "trcv_msg bad ercd !E_NOEXS" );
+    ercd = prcv_msg( &msg, 3 );        
+    CYG_TEST_CHECK( E_NOEXS == ercd, "prcv_msg bad ercd !E_NOEXS" );
+    ercd = ref_mbx( &t_rmbx, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mbx bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_mbx( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mbx bad ercd !E_PAR" );
+#endif
+    ercd = cre_mbx( 3, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mbx bad ercd !E_PAR" );
+    t_cmbx.mbxatr = 0xfff;
+    ercd = cre_mbx( 3, &t_cmbx );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_mbx bad ercd !E_RSATR" );
+    t_cmbx.mbxatr = 0;
+#endif // we can test bad param error returns
+    ercd = cre_mbx( 3, &t_cmbx );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
+    // and check we can use it
+    ercd = snd_msg( 3, t_msg );
+    CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
+    ercd = rcv_msg( &msg, 3 );       
+    CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
+    ercd = trcv_msg( &msg, 3, 2 );   
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
+    ercd = prcv_msg( &msg, 3 );                            
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = ref_mbx( &t_rmbx, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rcv_msg( &msg, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = trcv_msg( &msg, 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = snd_msg( 1, t_msg );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    ercd = snd_msg( 2, t_msg );       
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    // re-create and do it again
+    ercd = cre_mbx( 1, &t_cmbx );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
+    ercd = cre_mbx( 2, &t_cmbx );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
+
+    // now wait while task 2 deletes the wait objects again
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rcv_msg( &msg, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = trcv_msg( &msg, 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = snd_msg( 1, t_msg );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    ercd = snd_msg( 2, t_msg );       
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete mboxes");
+#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
+
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    ercd = dly_tsk( 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    // all done
+    if ( 0 == tests ) {
+        CYG_TEST_NA( "No objects have create/delete enabled" );
+    }
+    else {
+        CYG_TEST_EXIT( "All done" );
+    }
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+    ercd = del_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+    ercd = del_flg( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_flg( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_flg( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_flg( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+    ercd = del_mbx( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mbx( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mbx( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mbx( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
+
+    // we expect task2 to be killed here
+    CYG_TEST_FAIL( "Task 2 ran to completion!" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test6.c
diff --git a/packages/compat/uitron/v2_0/tests/test7.c b/packages/compat/uitron/v2_0/tests/test7.c
new file mode 100644 (file)
index 0000000..7cd2724
--- /dev/null
@@ -0,0 +1,1013 @@
+//===========================================================================
+//
+//      test7.c
+//
+//      uITRON "C" test program seven
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-01
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+// ========================================================================
+
+typedef enum {
+    START_WAITOP = 0,
+    SLEEP = 0,
+    DELAY,
+    SEMGET,
+    FLAGWAIT,
+    MSGGET,
+    MEMFIXEDGET,
+    MEMVARGET,
+    DONE_WAITOP
+} WAITOP;
+
+typedef enum {
+    START_TYPE = 0,
+    PLAIN = 0,
+    TIMED = 1,
+    DONE_TYPE
+} WAITTYPE;
+
+typedef enum {
+    START_KILLOP = 0,
+
+    // These are the 5 ways out of a wait that we perm
+    // with other circumstances:
+    SIGNAL = 0,                         // do the appropriate producer op
+    TIMEOUT,                            // wait for the timeout to fire
+    RELEASE,                            // do a rel_wai()
+    DELETE,                             // delete the object; del_xxx()
+    KILL,                               // do a ter_tsk() on the waiter
+
+    SUSPEND_SIGNAL_RESUME,
+    SUSPEND_TIMEOUT_RESUME,
+    SUSPEND_RELEASE_RESUME,
+    SUSPEND_DELETE_RESUME,
+    SUSPEND_KILL,                       // resume not applicable
+
+    SUSPEND_SIGNAL_KILL,
+    SUSPEND_TIMEOUT_KILL,
+    SUSPEND_RELEASE_KILL,
+    SUSPEND_DELETE_KILL,
+    // SUSPEND_KILL_KILL not applicable
+
+#if 0
+    // support these later if _really_ keen.
+    SUSPEND_SIGNAL_DELETE_RESUME,
+    SUSPEND_TIMEOUT_DELETE_RESUME,
+    SUSPEND_RELEASE_DELETE_RESUME,
+    // SUSPEND_DELETE_DELETE_RESUME not applicable
+    // SUSPEND_KILL_DELETE_RESUME not applicable
+
+    SUSPEND_SIGNAL_DELETE_KILL,
+    SUSPEND_TIMEOUT_DELETE_KILL,
+    SUSPEND_RELEASE_DELETE_KILL,
+    // SUSPEND_DELETE_DELETE_KILL,
+    SUSPEND_KILL_DELETE                 // 2nd kill not applicable
+#endif
+          
+    DONE_KILLOP
+} KILLOP;
+        
+// ========================================================================
+
+char * waitstrings[] =
+{ "Sleep ", "Delay ", "Sema  ", "Flag  ", "Mbox  ", "MemFix", "MemVar" };
+
+char * typestrings[] =
+{ " (Plain) : ", " (Timed) : " };
+
+char * killstrings[] =
+{ "Signal",
+  "Wait-for-timeout",
+  "Release-wait",
+  "Delete-object",
+  "Kill-task",
+
+  "Suspend/Signal/Resume",
+  "Suspend/Wait-for-timeout/Resume",
+  "Suspend/Release-wait/Resume",
+  "Suspend/Delete-object/Resume",
+  "Suspend/Kill-task",
+
+  "Suspend/Signal/Kill-task",
+  "Suspend/Wait-for-timeout/Kill-task",
+  "Suspend/Release-wait/Kill-task",
+  "Suspend/Delete-object/Kill-task",
+  
+
+};
+
+// ========================================================================
+
+inline int task2arg( WAITOP wait, WAITTYPE waittype, KILLOP kill )
+{
+    return waittype + (wait << 1) + (kill << 8);
+}
+
+inline void decodearg( int arg, WAITOP *pwait, WAITTYPE *pwaittype, KILLOP *pkill )
+{
+    *pwaittype = (arg & 1) ? TIMED : PLAIN;
+    *pwait  = (arg >> 1) & 0x7f;
+    *pkill  = (arg >> 8);
+}
+
+static char *strdog( char *p, char *q )
+{
+    while ( 0 != (*p++ = *q++) );
+    return p - 1;
+}
+
+static char *
+makemsg( char *z, WAITOP wait, WAITTYPE waittype, KILLOP kill )
+{
+    static char buf[ 1000 ];
+    char *p = buf;
+    p = strdog( p, z );
+    p = strdog( p, waitstrings[ wait ] );
+    p = strdog( p, typestrings[ waittype ] );
+    p = strdog( p, killstrings[ kill ] );
+    *p = 0;
+    return buf;
+}
+
+// ========================================================================
+
+volatile int intercom = 0;
+
+// ========================================================================
+
+T_RTSK rtsk;
+
+void
+do_suspend( void )
+{
+    ER ercd;
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat !TTS_WAI" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_WAS == rtsk.tskstat, "bad tskstat !TTS_WAS" );
+}
+
+void
+do_resume( void )
+{
+    ER ercd;
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_SUS == rtsk.tskstat, "bad tskstat !TTS_SUS" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RDY == rtsk.tskstat, "bad tskstat !TTS_RDY" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+}
+
+// ========================================================================
+
+#define T1_WAIT (7)
+#define T2_WAIT (5)
+
+#define T1_MALLOC (110)
+#ifdef CYGSEM_KERNEL_MEMORY_COALESCE
+#define T2_MALLOC (100)
+#else
+#define T2_MALLOC T1_MALLOC
+#endif
+
+VP vptmp;
+VP vp = NULL;
+VP vp1 = NULL;
+VP t2vp = NULL;
+VP t2vp_backup = NULL;
+
+UINT scratch;
+
+T_MSG *msg = (T_MSG *)&scratch;
+T_MSG *msg1;
+
+void
+do_prep( WAITOP wait )
+{
+    ER ercd;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+    case SEMGET:
+    case FLAGWAIT:
+    case MSGGET:
+        // do nothing for all of those
+        break;
+    case MEMFIXEDGET:
+        // allocate all the memory in the pool; remember a couple
+        // for freeing as the signalling operation:
+        t2vp = NULL;
+        vp = vptmp = NULL;
+        do {
+            vp1 = vptmp;
+            vptmp = vp;
+            ercd = pget_blf( &vp, 1 );
+        } while ( E_OK == ercd );
+        CYG_TEST_CHECK( E_TMOUT == ercd, "get_blf bad ercd" );
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        break;
+    case MEMVARGET:
+        // allocate all the memory in the pool; remember a couple
+        // for freeing as the signalling operation:
+        t2vp = NULL;
+        vp = vptmp = NULL;
+        do {
+            vp1 = vptmp;
+            vptmp = vp;
+            ercd = pget_blk( &vp, 1, T1_MALLOC );
+        } while ( E_OK == ercd );
+        CYG_TEST_CHECK( E_TMOUT == ercd, "get_blk bad ercd" );
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void
+do_tidyup( WAITOP wait )
+{
+    ER ercd;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+    case SEMGET:
+    case MSGGET:
+        // do nothing for all of those
+        break;
+    case FLAGWAIT:
+        // clear the flag variable
+        ercd = clr_flg( 1, 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd, tidy vp" );
+        break;
+    case MEMFIXEDGET:
+        if ( NULL != vp ) {
+            ercd = rel_blf( 1, vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp" );
+        }
+        if ( NULL != vp1 ) {
+            ercd = rel_blf( 1, vp1 );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp1" );
+        }
+        if ( NULL != t2vp ) {
+            ercd = rel_blf( 1, t2vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy t2vp" );
+        }
+        break;
+    case MEMVARGET:
+        if ( NULL != vp ) {
+            ercd = rel_blk( 1, vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp" );
+        }
+        if ( NULL != vp1 ) {
+            ercd = rel_blk( 1, vp1 );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp1" );
+        }
+        if ( NULL != t2vp ) {
+            ercd = rel_blk( 1, t2vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy t2vp" );
+        }
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void
+do_recreate( WAITOP wait )
+{ 
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+    static T_CSEM t_csem = { NULL, 0, 0 };
+#endif
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+    static T_CMBX t_cmbx = { NULL, 0 };
+#endif
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+    static T_CFLG t_cflg = { NULL, 0, 0 };
+#endif
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+    static T_CMPF t_cmpf = { NULL, 0, 20, 95 };
+#endif
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+    static T_CMPL t_cmpl = { NULL, 0, 2000 };
+#endif
+    ER ercd = E_OK;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+        // do nothing for all of those
+        break;
+    case SEMGET:
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+        // create the semaphore
+        ercd = cre_sem( 1, &t_csem );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate SEMGET" );
+#endif
+        break;
+    case FLAGWAIT:
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+        // create the flag
+        ercd = cre_flg( 1, &t_cflg );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate FLAGWAIT" );
+#endif
+        break;
+    case MSGGET:
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+        // create the mbox
+        ercd = cre_mbx( 1, &t_cmbx );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate MSGGET" );
+#endif
+        break;
+    case MEMFIXEDGET:
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+        // create the mempool
+        ercd = cre_mpf( 1, &t_cmpf );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate MEMFIXEDGET" );
+#endif
+        break;
+    case MEMVARGET:
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+        // create the mempool
+        ercd = cre_mpl( 1, &t_cmpl );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate MEMVARGET" );
+#endif
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+    // this is just to use ercd to prevent warnings
+    CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
+}
+
+
+
+void
+do_signal( WAITOP wait )
+{
+    ER ercd;
+    switch ( wait ) {
+    case SLEEP:
+        // send a wakeup
+        ercd = wup_tsk( 2 );
+        CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+        break;
+    case DELAY:
+        // simply wait for task 2's delay to complete
+        ercd = dly_tsk( T1_WAIT );
+        CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+        break;
+    case SEMGET:
+        // signal the semaphore
+        ercd = sig_sem( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+        break;
+    case FLAGWAIT:
+        // set the flag bits
+        ercd = set_flg( 1, 0xff );
+        CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
+        break;
+    case MSGGET:
+        // send a message
+        ercd = snd_msg( 1, msg );
+        CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
+        break;
+    case MEMFIXEDGET:
+        // release a couple of blocks we allocated earlier.  I hope.
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        ercd = rel_blf( 1, vp );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+        vp = NULL;
+        ercd = rel_blf( 1, vp1 );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd1" );
+        vp1 = NULL;
+        break;
+    case MEMVARGET:
+        // release a couple of blocks we allocated earlier.  I hope.
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        ercd = rel_blk( 1, vp );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+        vp = NULL;
+        ercd = rel_blk( 1, vp1 );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd1" );
+        vp1 = NULL;
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void
+do_delete( WAITOP wait )
+{
+    ER ercd = E_OK;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+        CYG_TEST_FAIL( "bad call to do_delete( SLEEP or DELAY )" );
+        break;
+    case SEMGET:
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+        // delete the semaphore
+        ercd = del_sem( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( SEMGET )" );
+#endif
+        break;
+    case FLAGWAIT:
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+        // delete the flag
+        ercd = del_flg( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( FLAGWAIT )" );
+#endif
+        break;
+    case MSGGET:
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+        // delete the mbox
+        ercd = del_mbx( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( MSGGET )" );
+#endif
+        break;
+    case MEMFIXEDGET:
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+        // delete the mempool
+        ercd = del_mpf( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( MEMFIXEDGET )" );
+#endif
+        break;
+    case MEMVARGET:
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+        // delete the mempool
+        ercd = del_mpl( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( MEMVARGET )" );
+#endif
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+    // this is just to use ercd to prevent warnings
+    CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
+}
+
+
+ER
+do_wait( WAITOP wait, WAITTYPE type )
+{
+    switch ( wait ) {
+    case SLEEP:
+        return ( PLAIN == type ) ? slp_tsk() : tslp_tsk( T2_WAIT );
+    case DELAY:
+        return dly_tsk( T2_WAIT );      // forget the type
+    case SEMGET:
+        return ( PLAIN == type ) ? wai_sem( 1 ) : twai_sem( 1, T2_WAIT );
+    case FLAGWAIT:
+        return ( PLAIN == type ) ?
+            wai_flg( &scratch, 1, 0x55, TWF_ANDW ) :
+           twai_flg( &scratch, 1, 0xaa, TWF_ANDW, T2_WAIT );
+    case MSGGET:
+        return ( PLAIN == type ) ?
+            rcv_msg( &msg1, 1 ) :
+           trcv_msg( &msg1, 1, T2_WAIT );
+    case MEMFIXEDGET:
+        return ( PLAIN == type ) ?
+            get_blf( &t2vp, 1 ) :
+           tget_blf( &t2vp, 1, T2_WAIT );
+    case MEMVARGET:
+        return ( PLAIN == type ) ?
+            get_blk( &t2vp, 1, T2_MALLOC ) :
+           tget_blk( &t2vp, 1, T2_MALLOC, T2_WAIT );
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+    CYG_TEST_FAIL( "Bad wait in do_wait" );
+    return E_SYS;
+}
+
+// ========================================================================
+void task1( unsigned int arg )
+{
+    ER ercd;
+    WAITOP wait;
+    WAITTYPE type;
+    KILLOP kill;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    ercd = chg_pri( 1, 8 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+
+    for ( wait = START_WAITOP; wait < DONE_WAITOP ; wait++) {
+        for ( type = START_TYPE; type < DONE_TYPE   ; type++ ) {
+            for ( kill = START_KILLOP; kill < DONE_KILLOP ; kill++ ) {
+                
+                // These clauses deal with a couple of special cases:
+                // [doing it this way helps keep the rest of the code
+                //  nicely general and orthogonal]
+                // 
+                // 1) DELAY: dly_tsk(): when this times out, the retcode is
+                // E_OK rather than E_TMOUT, and it always times out.  The
+                // "signalling" method here is just to wait yourself.  So we
+                // do not test DELAY with TIMED type.
+                //
+                // 2) PLAIN tests with TIMEOUT kill operations: a PLAIN test
+                // will not time out, it'll wait forever, so waiting for it
+                // so to do is pointless; further, we would check for the
+                // wrong error code.  So we do not test PLAIN tests with
+                // TIMOUT kill operations.
+                //
+                // 3) SLEEP or DELAY tests with DELETE operations: there is
+                // no synchronization to delete in those cases.
+                // 3a) Individual object types are tested for delete support,
+                // and if there is none, the test is skipped.
+
+                if ( DELAY == wait && TIMED == type )
+                    continue;
+
+                if ( PLAIN == type &&
+                     ( (        TIMEOUT        == kill) ||
+                       (SUSPEND_TIMEOUT_RESUME == kill) ||
+                       (SUSPEND_TIMEOUT_KILL   == kill) ) )
+                    continue;
+
+                if ( ( 
+#ifndef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+                    (SEMGET      == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+                    (FLAGWAIT    == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+                    (MSGGET      == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+                    (MEMFIXEDGET == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+                    (MEMVARGET   == wait) ||
+#endif
+                    (SLEEP       == wait) ||
+                    (DELAY       == wait)
+                    ) &&
+                     ((DELETE                == kill) ||
+                      (SUSPEND_DELETE_RESUME == kill) ||
+                      (SUSPEND_DELETE_KILL   == kill)) )
+                    continue;
+
+
+                CYG_TEST_INFO( makemsg( "T1: ", wait, type, kill ) );
+
+                intercom = 0;
+
+                // prepare the synchronization objects
+                // (actually, just empty the mempools)
+                do_prep( wait );
+
+                // start task 2 at a higher priority than myself
+                ercd = dis_dsp();
+                CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+                ercd = sta_tsk( 2, task2arg( wait, type, kill ) );
+                CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+                ercd = chg_pri( 2, 5 );
+                CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+                ercd = ena_dsp();
+                CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+                // task 2 should run now, until it waits.
+
+                ercd = ref_tsk( &rtsk, 2 );
+                CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+                CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat" );
+                CYG_TEST_CHECK( 5 == rtsk.tskpri, "bad tskpri" );
+
+                switch ( kill ) {
+                case SIGNAL:
+                    // signal the task appropriately
+                    do_signal( wait );
+                    // it should now have run to completion
+                    break;
+                case TIMEOUT:
+                    // wait for the timeout to occur
+                    ercd = dly_tsk( T1_WAIT );
+                    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+                    // it should now have run to completion
+                    break;
+                case RELEASE:
+                    // hit the task with a release-wait
+                    ercd = rel_wai( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+                    // it should now have run to completion
+                    break;
+                case DELETE:
+                    // delete the object appropriately
+                    do_delete( wait );
+                    // it should now have run to completion
+                    break;
+                case KILL:
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_SIGNAL_RESUME:
+                    // suspend the task
+                    do_suspend();
+                    // signal the task appropriately
+                    do_signal( wait );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_TIMEOUT_RESUME:
+                    // suspend the task
+                    do_suspend();
+                    // wait for the timeout to occur
+                    ercd = dly_tsk( T1_WAIT );
+                    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_RELEASE_RESUME:
+                    // suspend the task
+                    do_suspend();
+                    // hit the task with a release-wait
+                    ercd = rel_wai( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_DELETE_RESUME:
+                    // suspend the task
+                    do_suspend();
+                    // delete the object appropriately
+                    do_delete( wait );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_SIGNAL_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // signal the task appropriately
+                    do_signal( wait );
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_TIMEOUT_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // wait for the timeout to occur
+                    ercd = dly_tsk( T1_WAIT );
+                    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_RELEASE_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // hit the task with a release-wait
+                    ercd = rel_wai( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+                     // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_DELETE_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // delete the object appropriately
+                    do_delete( wait );
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                default:
+                    CYG_TEST_FAIL( "bad switch" );
+                    break;
+                }
+                
+                // task 2 should be dormant now, however it got there
+                ercd = ref_tsk( &rtsk, 2 );
+                CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+                CYG_TEST_CHECK( TTS_DMT == rtsk.tskstat, "bad tskstat" );
+
+                if ( (SUSPEND_SIGNAL_KILL == kill) &&
+                     ((MEMFIXEDGET == wait) || (MEMVARGET == wait)) ) {
+                    // it was a killed successful memory alloc, so we have
+                    // lost the pointer to memory allocated; there is an
+                    // implicit storeleak problem when the task trying
+                    // to allocate is signalled then killed.
+                    // Recreate the pointer from an old version:
+                    CYG_TEST_CHECK( NULL == t2vp, "t2vp WAS allocated!" );
+                    t2vp = t2vp_backup;
+                }
+
+                switch ( kill ) {
+                case KILL:
+                case SUSPEND_KILL:
+                case SUSPEND_SIGNAL_KILL:
+                case SUSPEND_TIMEOUT_KILL:
+                case SUSPEND_RELEASE_KILL:
+                case SUSPEND_DELETE_KILL:
+                    // if task 2 was killed, expect only one increment
+                    CYG_TEST_CHECK( 1 == intercom, "intercom bad value !1" );
+                    break;
+                default:
+                    // otherwise expect two increments
+                    CYG_TEST_CHECK( 2 == intercom, "intercom bad value !2" );
+                    break;
+                }
+                
+                // tidy up or recreate the synchronization objects
+                if ( (DELETE                == kill) ||
+                     (SUSPEND_DELETE_RESUME == kill) ||
+                     (SUSPEND_DELETE_KILL   == kill) )
+                    do_recreate( wait );
+                else
+                    do_tidyup( wait );
+            }
+        }
+    }
+    CYG_TEST_PASS("synchronization interaction tests");
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    WAITOP wait;
+    WAITTYPE waittype;
+    KILLOP kill;
+
+    decodearg( arg, &wait, &waittype, &kill );
+
+//    CYG_TEST_INFO( makemsg( " 2: ", wait, waittype, kill ) );
+
+    intercom++;
+    ercd = do_wait( wait, waittype );
+    intercom++;
+
+    switch ( kill ) {
+    case SIGNAL:
+    case SUSPEND_SIGNAL_RESUME:
+        // we expect to have been signalled correctly
+        CYG_TEST_CHECK( E_OK == ercd, "T2 wait bad ercd" );
+        // here we know that the op completed OK
+        if ( (MEMFIXEDGET == wait) || (MEMVARGET == wait) ) {
+            // it was a successful memory alloc of whichever type,
+            // so we can save away a copy of t2vp for working round an
+            // implicit storeleak problem when the task trying to allocate
+            // is signalled then killed:
+            CYG_TEST_CHECK( NULL != t2vp, "No t2vp allocated!" );
+            t2vp_backup = t2vp;
+        }
+        break;
+    case TIMEOUT:
+    case SUSPEND_TIMEOUT_RESUME:
+        // we expect to have timed out - if it's a timeout op.
+        CYG_TEST_CHECK( E_TMOUT == ercd, "T2 timeout bad ercd, !E_TMOUT" );
+        break;
+    case RELEASE:
+    case SUSPEND_RELEASE_RESUME:
+        // we expect to have suffered a release wait.
+        CYG_TEST_CHECK( E_RLWAI == ercd, "T2 release bad ercd, !E_RLWAI" );
+        break;
+    case DELETE:
+    case SUSPEND_DELETE_RESUME:
+        // we expect to be told the object is gone
+        CYG_TEST_CHECK( E_DLT == ercd, "T2 release bad ercd, !E_DLT" );
+        break;
+    case KILL:
+    case SUSPEND_KILL:
+    case SUSPEND_SIGNAL_KILL:
+    case SUSPEND_TIMEOUT_KILL:
+    case SUSPEND_RELEASE_KILL:
+    case SUSPEND_DELETE_KILL:
+        // we expect to have been killed here, ie. this won't execute!
+        CYG_TEST_FAIL( "Task 2 ran to completion!" );
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test7.c
diff --git a/packages/compat/uitron/v2_0/tests/test8.c b/packages/compat/uitron/v2_0/tests/test8.c
new file mode 100644 (file)
index 0000000..408ed6f
--- /dev/null
@@ -0,0 +1,393 @@
+//===========================================================================
+//
+//      test8.c
+//
+//      uITRON "C" test program eight
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-12
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+INT scratch;
+
+void newtask( unsigned int arg );
+void task2( unsigned int arg );
+void task3( unsigned int arg );
+void task4( unsigned int arg );
+
+T_CTSK t_ctsk = { NULL, 0, (FP)&newtask, 1, CYGNUM_UITRON_STACK_SIZE };
+T_RTSK t_rtsk;
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    // change us to prio 3 for flexibility
+    ercd = chg_pri( 0, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+    // first, check that we can delete a task:
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
+    ercd = del_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
+    ercd = cre_tsk( -6, &t_ctsk );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
+    ercd = cre_tsk( 99, &t_ctsk );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
+    // try a pre-existing object - ourselves!
+    ercd = cre_tsk( 1, &t_ctsk );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
+    // try deleting an active task
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    // Task 2 is now ready-to-run, lower prio than us
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    // Task 2 is now sleeping
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    // try deleting a running task - ourselves!
+    ercd = del_tsk( 1 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    // terminate task 2; should then be OK to delete it
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    // and check it is deleted
+    ercd = sta_tsk( 2, 99 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
+    ercd = chg_pri( 2, 6 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
+    // recreate task2, with the same function
+    t_ctsk.task = (FP)&task2;
+    t_ctsk.itskpri = 7;
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
+    CYG_TEST_CHECK( TTS_DMT == t_rtsk.tskstat,
+                    "Bad tskstat in new task2 !TTS_DMT" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    // now start the task and do the same lot again...
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
+    // try deleting an active task
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    // Task 2 is now ready-to-run, lower prio than us
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
+    // Task 2 is now sleeping
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
+    CYG_TEST_CHECK( TTS_WAI == t_rtsk.tskstat,
+                    "Bad tskstat in new task2 !TTS_WAI" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    // up its priority
+    ercd = chg_pri( 2, 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    // awaken task 2; it will then exit-and-delete itself:
+    CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    // and check it is deleted
+    ercd = sta_tsk( 2, 99 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
+    ercd = chg_pri( 2, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_tsk( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
+#endif
+    ercd = cre_tsk( 2, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
+    t_ctsk.stksz = 0x40000000;
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_tsk bad ercd !E_NOMEM" );
+    t_ctsk.stksz = CYGNUM_UITRON_STACK_SIZE;
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+#endif // we can test bad param error returns
+
+    ercd = del_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
+    t_ctsk.task = (FP)&task4;
+    t_ctsk.itskpri = 9;
+    ercd = cre_tsk( 3, &t_ctsk );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    // check we can delete it again immediately
+    ercd = del_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
+    ercd = ref_tsk( &t_rtsk, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
+    t_ctsk.task = (FP)&newtask;
+    t_ctsk.itskpri = 1;
+    ercd = cre_tsk( 3, &t_ctsk );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    ercd = sta_tsk( 3, 999 );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    // it should have run now, and exited
+    CYG_TEST_CHECK( 5 == intercount, "bad intercount !5" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    // and check that it will just run again...
+    ercd = sta_tsk( 3, 999 );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    // it should have run now, and exited
+    CYG_TEST_CHECK( 7 == intercount, "bad intercount !7" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    // all done.
+
+    CYG_TEST_PASS("create/delete tasks");
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+#else // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
+    CYG_TEST_NA( "Tasks do not have create/delete enabled" );
+#endif // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
+    ext_tsk();
+}
+
+
+
+void newtask( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Newtask running" );
+    CYG_TEST_CHECK( 999 == arg, "Bad arg to newtask() !999" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 3 == i, "tid not 3" );
+    intercount++;
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    intercount++;
+    // and just return
+}
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    intercount++;
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+
+    intercount++;
+
+    exd_tsk(); // if we are not killed first
+
+    intercount++; // shouldn't happen
+}
+
+void task3( unsigned int arg )
+{
+    CYG_TEST_FAIL( "How come I'm being run?" );
+}
+
+void task4( unsigned int arg )
+{
+    CYG_TEST_FAIL( "How come I'm being run?" );
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test8.c
diff --git a/packages/compat/uitron/v2_0/tests/test9.c b/packages/compat/uitron/v2_0/tests/test9.c
new file mode 100644 (file)
index 0000000..7d62b5d
--- /dev/null
@@ -0,0 +1,489 @@
+//===========================================================================
+//
+//      test9.c
+//
+//      uITRON "C" test program nine
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-16
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+VP vp;
+
+T_CMPL t_cmpl = { NULL, 0, 1000 };
+T_RMPL t_rmpl;
+T_CMPF t_cmpf = { NULL, 0, 10, 100 };
+T_RMPF t_rmpf;
+
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    int tests = 0;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_mpf( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
+    ercd = del_mpf( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
+    ercd = cre_mpf( -6, &t_cmpf );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
+    ercd = cre_mpf( 99, &t_cmpf );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    // [first get a valid block from it for the freeing test later]
+    ercd = pget_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpf bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_mpf( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    // check it is deleted
+    ercd = rel_blf( 3, vp );            // vp did come from this pool
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blf bad ercd !E_NOEXS" );
+    ercd = pget_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
+    ercd = tget_blf( &vp, 3, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blf bad ercd !E_NOEXS" );
+    ercd = get_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
+    ercd = ref_mpf( &t_rmpf, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpf bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_mpf( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mpf bad ercd !E_PAR" );
+#endif
+    ercd = cre_mpf( 3, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mpf bad ercd !E_PAR" );
+    t_cmpf.mpfatr = 0xfff;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpf bad ercd !E_RSATR" );
+#endif // we can test bad param error returns
+    t_cmpf.mpfatr = 0;
+    t_cmpf.mpfcnt = 10000;
+    t_cmpf.blfsz = 100;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
+    t_cmpf.mpfcnt = 100;
+    t_cmpf.blfsz = 100000;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
+    // now create it well
+    t_cmpf.mpfatr = 0;
+    t_cmpf.mpfcnt = 10;
+    t_cmpf.blfsz = 100;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
+    // and check we can use it
+    ercd = pget_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = tget_blf( &vp, 3, 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
+    ercd = get_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
+    ercd = rel_blf( 3, vp );            // vp did come from new pool
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = rel_blf( 3, vp );            // vp already freed
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
+    ercd = ref_mpf( &t_rmpf, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blf( &vp, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blf( &vp, 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = get_blf( &vp, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
+    ercd = pget_blf( &vp, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
+
+    // re-create and do it again
+    t_cmpf.mpfcnt = 90;
+    t_cmpf.blfsz = 20;
+    ercd = cre_mpf( 1, &t_cmpf );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
+    t_cmpf.mpfcnt = 5;
+    t_cmpf.blfsz = 200;
+    ercd = cre_mpf( 2, &t_cmpf );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blf( &vp, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blf( &vp, 2, 10 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = tget_blf( &vp, 1, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
+    ercd = get_blf( &vp, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete fixed mempools");
+#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_mpl( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
+    ercd = del_mpl( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
+    ercd = cre_mpl( -6, &t_cmpl );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
+    ercd = cre_mpl( 99, &t_cmpl );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    // [first get a valid block from it for the freeing test later]
+    ercd = pget_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpl bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_mpl( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    // check it is deleted
+    ercd = rel_blk( 3, vp );            // vp did come from this pool
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blk bad ercd !E_NOEXS" );
+    ercd = pget_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
+    ercd = tget_blk( &vp, 3, 100, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blk bad ercd !E_NOEXS" );
+    ercd = get_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
+    ercd = ref_mpl( &t_rmpl, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpl bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_mpl( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mpl bad ercd !E_PAR" );
+#endif
+    ercd = cre_mpl( 3, NADR );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mpl bad ercd !E_PAR" );
+    t_cmpl.mplatr = 0xfff;
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpl bad ercd !E_RSATR" );
+#endif // we can test bad param error returns
+    t_cmpl.mplatr = 0;
+    t_cmpl.mplsz = 100000000;
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpl bad ercd" );
+    // now create it well
+    t_cmpl.mplatr = 0;
+    t_cmpl.mplsz = 1000;
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
+    // and check we can use it
+    ercd = pget_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = pget_blk( &vp, 3, 100000000 ); // way too large
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &vp, 3, 100, 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
+    ercd = get_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
+    ercd = rel_blk( 3, vp );            // vp did come from new pool
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = rel_blk( 3, vp );            // vp already freed
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
+    ercd = ref_mpl( &t_rmpl, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blk( &vp, 1, 100 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blk( &vp, 2, 100, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blk( &vp, 1, 200 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blk( &vp, 2, 100, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = get_blk( &vp, 1, 200 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
+    ercd = pget_blk( &vp, 2, 20 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
+
+    // re-create and do it again
+    ercd = cre_mpl( 1, &t_cmpl );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
+    ercd = cre_mpl( 2, &t_cmpl );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blk( &vp, 1, 20 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blk( &vp, 2, 400, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blk( &vp, 1, 200 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blk( &vp, 2, 500, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = tget_blk( &vp, 1, 200, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
+    ercd = get_blk( &vp, 2, 20 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete variable mempools");
+#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    ercd = dly_tsk( 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    // all done
+    if ( 0 == tests ) {
+        CYG_TEST_NA( "No objects have create/delete enabled" );
+    }
+    else {
+        CYG_TEST_EXIT( "All done" );
+    }
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+    ercd = del_mpf( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpf( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpf( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpf( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+    ercd = del_mpl( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpl( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpl( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpl( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+    // we expect task2 to be killed here
+    CYG_TEST_FAIL( "Task 2 ran to completion!" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF test9.c
diff --git a/packages/compat/uitron/v2_0/tests/testcx2.cxx b/packages/compat/uitron/v2_0/tests/testcx2.cxx
new file mode 100644 (file)
index 0000000..f528e62
--- /dev/null
@@ -0,0 +1,937 @@
+//===========================================================================
+//
+//      testcx2.cxx
+//
+//      uITRON "C++" test program two
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+int intercom = 0;
+int intercount = 0;
+INT scratch = 0;
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+
+    T_RSEM sem_info;
+    T_RFLG flg_info;
+    T_RMBX mbx_info;
+    T_RMPF mpf_info;
+    T_RMPL mpl_info;
+    UINT flagptn;
+    static char foo[] = "Test message";
+    T_MSG *msgptr = (T_MSG *)foo;
+    T_MSG *rxptr = NULL;
+    VP blfptr = (VP)foo;
+    VP blkptr = (VP)foo;
+
+    int delay = 10;
+    if (cyg_test_is_simulator)
+        delay = 3;
+
+    CYG_TEST_INFO( "Task 1 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+    
+    // start a lower prio task to interact with
+    intercom = 1;
+    ercd = sta_tsk( 2, 222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    // Semaphores; all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing semaphore ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = sig_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
+    ercd = sig_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sig_sem bad ercd !E_ID" );
+    ercd = wai_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
+    ercd = wai_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_sem bad ercd !E_ID" );
+    ercd = preq_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
+    ercd = preq_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "preq_sem bad ercd !E_ID" );
+    ercd = twai_sem( -6, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
+    ercd = twai_sem( 99, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_sem bad ercd !E_ID" );
+    ercd = twai_sem( 2, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_sem bad ercd !E_PAR" );
+    ercd = ref_sem( &sem_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
+    ercd = ref_sem( &sem_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_sem bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_sem( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_sem bad ercd !E_PAR" );
+#endif
+    CYG_TEST_PASS( "bad calls: sig_sem, [t]wai_sem, preq_sem, ref_sem" );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = wai_sem( 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "wai_sem bad ercd !E_CTX" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_sem bad ercd !E_CTX" );
+    ercd = twai_sem( 2, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_sem(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = twai_sem( 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: wai_sem, twai_sem with dis_dsp" );
+
+    // check ref_sem with various states
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
+    ercd = preq_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 2 == sem_info.semcnt, "semcnt should be 2" );
+    ercd = wai_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
+    ercd = twai_sem( 2, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    intercom = 0;
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 != sem_info.wtsk, "sem.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be non0" );
+#if 1
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+#else // old, non-uITRON semantics
+    CYG_TEST_CHECK( 1 == sem_info.semcnt, "semcnt should be 1" );
+#endif
+    ercd = dly_tsk( delay );               // let task 2 pick up the signal
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_sem( &sem_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+    CYG_TEST_CHECK( 0 == sem_info.wtsk, "sem.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == sem_info.semcnt, "semcnt should be 0" );
+    CYG_TEST_PASS( "good calls: sig_sem, [t]wai,preq_sem with ref_sem" );
+
+    // Flags; all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing flag ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = set_flg( -6, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
+    ercd = set_flg( 99, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "set_flg bad ercd !E_ID" );
+    ercd = clr_flg( -6, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "clr_flg bad ercd !E_ID" );
+    ercd = clr_flg( 99, 1 );
+    CYG_TEST_CHECK( E_ID == ercd, "sig_flg bad ercd !E_ID" );
+    ercd = wai_flg( &flagptn, -6, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
+    ercd = wai_flg( &flagptn, 99, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "wai_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = wai_flg( NULL, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
+#endif
+    ercd = wai_flg( &flagptn, 2, 7, 34657 );
+    CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
+    ercd = wai_flg( &flagptn, 2, 0, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "wai_flg bad ercd !E_PAR" );
+    ercd = pol_flg( &flagptn, -6, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
+    ercd = pol_flg( &flagptn, 99, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_ID == ercd, "pol_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = pol_flg( NULL, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
+#endif
+    ercd = pol_flg( &flagptn, 2, 7, 34657 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
+    ercd = pol_flg( &flagptn, 2, 0, TWF_ANDW );
+    CYG_TEST_CHECK( E_PAR == ercd, "pol_flg bad ercd !E_PAR" );
+    ercd = twai_flg( &flagptn, -6, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
+    ercd = twai_flg( &flagptn, 99, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "twai_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = twai_flg( NULL, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+#endif
+    ercd = twai_flg( &flagptn, 2, 7, 34657, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+    ercd = twai_flg( &flagptn, 2, 0, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "twai_flg bad ercd !E_PAR" );
+    ercd = ref_flg( &flg_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
+    ercd = ref_flg( &flg_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_flg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_flg( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_flg bad ercd !E_PAR" );
+#endif
+    CYG_TEST_PASS( "bad calls: set_flg, clr_flg, [t]wai,pol_flg, ref_flg" );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = wai_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_CTX == ercd, "wai_flg bad ercd !E_CTX" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_flg bad ercd !E_CTX" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "twai_flg(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
+    ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pol_flg( &flagptn, 2, 7, TWF_ANDW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &flagptn, 2, 7, TWF_ANDW, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: wai_flg, twai_flg with dis_dsp" );
+
+    // check ref_flg with various states
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == flg_info.flgptn, "flgptn should be 0" );
+    ercd = set_flg( 2, 0x5555 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0x5555 == flg_info.flgptn, "flgptn should be 0x5555" );
+    ercd = clr_flg( 2, 0xF0F0 );
+    CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 != flg_info.wtsk, "flg.wtsk should be non0" );
+    CYG_TEST_CHECK( 0x5050 == flg_info.flgptn, "flgptn should be 0x5050" );
+    ercd = set_flg( 2, 0xFFFF );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_flg bad ercd" );
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_flg( &flg_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == flg_info.wtsk, "flg.wtsk should be 0" );
+    CYG_TEST_CHECK( 0xFFFF == flg_info.flgptn, "flgptn should be 0xFFFF" );
+    CYG_TEST_PASS( "good calls: clr_flg, set_flg, wai_flg with ref_flg" );
+
+    // Mailboxes; all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing mailbox ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = snd_msg( -6, msgptr );
+    CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
+    ercd = snd_msg( 99, msgptr );
+    CYG_TEST_CHECK( E_ID == ercd, "snd_msg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = snd_msg( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "snd_msg bad ercd !E_PAR" );
+#endif
+    ercd = rcv_msg( &rxptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
+    ercd = rcv_msg( &rxptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "rcv_msg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = rcv_msg( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "rcv_msg bad ercd !E_PAR" );
+#endif
+    ercd = prcv_msg( &rxptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
+    ercd = prcv_msg( &rxptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "prcv_msg bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = prcv_msg( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "prcv_msg bad ercd !E_PAR" );
+#endif
+    ercd = trcv_msg( &rxptr, -6, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
+    ercd = trcv_msg( &rxptr, 99, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "trcv_msg bad ercd !E_ID" );
+    ercd = trcv_msg( &rxptr, 2, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = trcv_msg( NULL, 2, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "trcv_msg bad ercd !E_PAR" );
+#endif
+    ercd = ref_mbx( &mbx_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
+    ercd = ref_mbx( &mbx_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mbx bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_mbx( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mbx bad ercd !E_PAR" );
+#endif
+    CYG_TEST_PASS( "bad calls: snd_msg, [pt]rcv_msg, ref_mbx" );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = prcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "rcv_msg bad ercd !E_CTX" );
+    ercd = trcv_msg( &rxptr, 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg bad ercd !E_CTX" );
+    ercd = trcv_msg( &rxptr, 2, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "trcv_msg(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = trcv_msg( &rxptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
+    ercd = prcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = prcv_msg( &rxptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
+    ercd = trcv_msg( &rxptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: rcv_msg, trcv_msg with dis_dsp" );
+
+    // check ref_mbx with various states
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 != mbx_info.wtsk, "mbx.wtsk should be non0" );
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+    ercd = snd_msg( 2, msgptr );
+    CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
+#if 1
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+#else // old, non-uITRON semantics
+    CYG_TEST_CHECK( msgptr == mbx_info.pk_msg, "mbx peek should be msgptr" );
+#endif
+    ercd = dly_tsk( delay );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_mbx( &mbx_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+    CYG_TEST_CHECK( 0 == mbx_info.wtsk, "mbx.wtsk should be 0" );
+    CYG_TEST_CHECK( NADR == mbx_info.pk_msg, "mbx peek should be NADR" );
+    // fill the message box, expect E_QOVR
+    for ( scratch = 0 ; scratch < 100 ; scratch++ ) {
+        if ( E_OK != ( ercd = snd_msg( 2, msgptr ) ) )
+            break;
+    }
+    CYG_TEST_CHECK( (100 == scratch) || (E_QOVR == ercd),
+                    "snd_msg bad ercd !E_QOVR/E_OK" );
+    // empty the message box, expect the right number and E_TMOUT
+    for (             ;     1         ; scratch-- ) {
+        if ( E_OK != ( ercd = prcv_msg( &rxptr, 2 ) ) )
+            break;
+    }
+    CYG_TEST_CHECK( 0 == scratch, "rcv_msg count bad scratch!=0" );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "rcv_msg bad ercd !E_TMOUT" );
+
+    CYG_TEST_PASS( "good calls: rcv_msg, snd_msg with ref_msg" );
+
+    // Fixed block memory pools: all the illegal argument combinations first
+    CYG_TEST_INFO( "Testing fixed block memory ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_blf( -6, blfptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
+    ercd = rel_blf( 99, blfptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = rel_blf( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
+#endif
+#endif // we can test bad param error returns
+    ercd = rel_blf( 2, blfptr );        // it did not come from a mpf
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blf( &blfptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
+    ercd = get_blf( &blfptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = get_blf( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_blf bad ercd !E_PAR" );
+#endif
+    ercd = pget_blf( &blfptr, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
+    ercd = pget_blf( &blfptr, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = pget_blf( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pget_blf bad ercd !E_PAR" );
+#endif
+    ercd = tget_blf( &blfptr, -6, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
+    ercd = tget_blf( &blfptr, 99, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blf bad ercd !E_ID" );
+    ercd = tget_blf( &blfptr, 2, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = tget_blf( NULL, 2, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blf bad ercd !E_PAR" );
+#endif
+    ercd = ref_mpf( &mpf_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
+    ercd = ref_mpf( &mpf_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpf bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_mpf( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mpf bad ercd !E_PAR" );
+#endif
+    CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf, ref_mpf " );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    // consume the whole thing then do it again, expecting E_TMOUT
+    while ( E_OK == (ercd = pget_blf( &blfptr, 2 ) ) )
+        continue;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blf bad ercd !E_CTX" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blf bad ercd !E_CTX" );
+    ercd = tget_blf( &blfptr, 2, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blf(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = tget_blf( &blfptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blf( &blfptr, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    ercd = tget_blf( &blfptr, 2, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: rel_blf, [pt]get_blf with ena_dsp" );
+
+    // check ref_mpf with various states
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 != mpf_info.wtsk, "mpf.wtsk should be non0" );
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+    ercd = rel_blf( 2, blfptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
+#if 1
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+#else // old, non-uITRON semantics
+    CYG_TEST_CHECK( 0 != mpf_info.frbcnt, "mpf.frbcnt should be non0" );
+#endif
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_mpf( &mpf_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+    CYG_TEST_CHECK( 0 == mpf_info.wtsk, "mpf.wtsk should be 0" );
+    CYG_TEST_CHECK( 0 == mpf_info.frbcnt, "mpf.frbcnt should be 0" );
+    CYG_TEST_PASS( "good calls: rel_blf, get_blf with ref_mpf" );
+
+    // Variable block memory pools; illegal arguments
+    CYG_TEST_INFO( "Testing variable block memory ops" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_blk( -6, blkptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
+    ercd = rel_blk( 99, blkptr );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_blk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = rel_blk( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
+#endif
+#endif // we can test bad param error returns
+    ercd = rel_blk( 2, blkptr );        // it did not come from a mpl
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blk( &blkptr, -6, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
+    ercd = get_blk( &blkptr, 99, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "get_blk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = get_blk( NULL, 2, 100 );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_blk bad ercd !E_PAR" );
+#endif
+    ercd = pget_blk( &blkptr, -6, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
+    ercd = pget_blk( &blkptr, 99, 100 );
+    CYG_TEST_CHECK( E_ID == ercd, "pget_blk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = pget_blk( NULL, 2, 100 );
+    CYG_TEST_CHECK( E_PAR == ercd, "pget_blk bad ercd !E_PAR" );
+#endif
+    ercd = tget_blk( &blkptr, -6, 100, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
+    ercd = tget_blk( &blkptr, 99, 100, delay );
+    CYG_TEST_CHECK( E_ID == ercd, "tget_blk bad ercd !E_ID" );
+    ercd = tget_blk( &blkptr, 2, 100, -999 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = tget_blk( NULL, 2, 100, delay );
+    CYG_TEST_CHECK( E_PAR == ercd, "tget_blk bad ercd !E_PAR" );
+#endif
+    ercd = ref_mpl( &mpl_info, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
+    ercd = ref_mpl( &mpl_info, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_mpl bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_mpl( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_mpl bad ercd !E_PAR" );
+#endif
+    CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk, ref_mpl " );
+#endif // we can test bad param error returns
+
+    // check the waitable functions versus dispatch disable
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    // consume the whole thing then do it again, expecting E_TMOUT
+    while ( E_OK == (ercd = pget_blk( &blkptr, 2, 100 ) ) )
+        continue;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = get_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_CTX == ercd, "get_blk bad ercd !E_CTX" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blk bad ercd !E_CTX" );
+    ercd = tget_blk( &blkptr, 2, 100, TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "tget_blk(FEVR) bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = pget_blk( &blkptr, 2, 100 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, delay );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &blkptr, 2, 100, TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk(POL) bad ercd !E_TMOUT" );
+    CYG_TEST_PASS( "bad calls: rel_blk, [pt]get_blk with ena_dsp" );
+
+    // check ref_mpl with various states
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
+    CYG_TEST_CHECK( mpl_info.maxsz <= mpl_info.frsz,
+                    "mpl.maxsz not < mpl.frsz" );
+    intercom = 0;
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    intercom = 1;
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 != mpl_info.wtsk, "mpl.wtsk should be non0" );
+    ercd = rel_blk( 2, blkptr );
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
+    ercd = dly_tsk( delay );               // let task 2 start waiting
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_mpl( &mpl_info, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+    CYG_TEST_CHECK( 0 == mpl_info.wtsk, "mpl.wtsk should be 0" );
+    CYG_TEST_PASS( "good calls: rel_blk, get_blk with ref_mpl" );
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    T_MSG *msgp = NULL;
+    UINT flgval = 0;
+    VP blfp = NULL;
+    VP blkp = NULL;
+
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
+    if ( 222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 222" );
+
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = wai_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = wai_flg( &flgval, 2, 99, TWF_ANDW );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
+    CYG_TEST_CHECK( 99 == (99 & flgval), "flg value no good" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = rcv_msg( &msgp, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
+    CYG_TEST_CHECK( NULL != msgp, "no msg received" );
+    CYG_TEST_CHECK( NADR != msgp, "no msg received" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = get_blf( &blfp, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
+    CYG_TEST_CHECK( NULL != blfp, "no blf allocated" );
+    CYG_TEST_CHECK( NADR != blfp, "no blf allocated" );
+    while ( intercom ) {
+        ercd = rot_rdq( 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    }
+    ercd = get_blk( &blkp, 2, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
+    CYG_TEST_CHECK( NULL != blkp, "no blk allocated" );
+    CYG_TEST_CHECK( NADR != blkp, "no blk allocated" );
+
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 2 failed to exit" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK "
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx2.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcx3.cxx b/packages/compat/uitron/v2_0/tests/testcx3.cxx
new file mode 100644 (file)
index 0000000..d8d6978
--- /dev/null
@@ -0,0 +1,262 @@
+//===========================================================================
+//
+//      testcx3.cxx
+//
+//      uITRON "C++" test program three
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+int t2done = 0;
+int t3done = 0;
+int t4done = 0;
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 1 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+    
+    // start lower prio tasks to interact with
+    ercd = sta_tsk( 2, 222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = sta_tsk( 3, 333 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = sta_tsk( 4, 444 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+
+    // now start the test
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    CYG_TEST_INFO( "T1 awoken" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    CYG_TEST_INFO( "T1 signalled" );
+    
+    // let the others complete, so we get the status back
+    ercd = dly_tsk( 50 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    
+    CYG_TEST_CHECK( t2done, "t2 not done" );
+    CYG_TEST_CHECK( t3done, "t3 not done" );
+    CYG_TEST_CHECK( t4done, "t4 not done" );
+
+    CYG_TEST_PASS( "Immediate-dispatch producer/consumer test OK" );
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
+    if ( 222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 222" );
+
+    // now start the test
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    CYG_TEST_INFO( "T2 awoken" );
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = wup_tsk( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+
+    CYG_TEST_INFO( "T2 completing" );
+    t2done++;
+
+    ercd = slp_tsk();
+    CYG_TEST_FAIL( "Task 2 sleep came back" );
+}
+
+void task3( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 3 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
+    if ( 333 != arg )
+        CYG_TEST_FAIL( "Task 3 arg not 333" );
+
+    // now start the test
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    CYG_TEST_INFO( "T3 awoken" );
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    
+    CYG_TEST_INFO( "T3 completing" );
+    t3done++;
+
+    ercd = slp_tsk();
+    CYG_TEST_FAIL( "Task 3 sleep came back" );
+}
+
+void task4( unsigned int arg )
+{
+    ER ercd;
+    INT scratch;
+
+    CYG_TEST_INFO( "Task 4 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
+    if ( 444 != arg )
+        CYG_TEST_FAIL( "Task 4 arg not 444" );
+
+    // now start the test
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+
+    CYG_TEST_INFO( "T4 completing" );
+    t4done++;
+
+    ercd = slp_tsk();
+    CYG_TEST_FAIL( "Task 4 sleep came back" );
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx3.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcx4.cxx b/packages/compat/uitron/v2_0/tests/testcx4.cxx
new file mode 100644 (file)
index 0000000..b4c2367
--- /dev/null
@@ -0,0 +1,406 @@
+//===========================================================================
+//
+//      testcx4.cxx
+//
+//      uITRON "C++" test program four
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   dsm
+// Contributors:        dsm
+// Date:        1998-06-12
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough cyclic handlers */            \
+    defined( CYGPKG_UITRON_CYCLICS )                            && \
+    (CYGNUM_UITRON_CYCLICS >= 3)                                && \
+    (CYGNUM_UITRON_CYCLICS < 90)                                && \
+                                                                   \
+    /* test configuration for enough alarm handlers */             \
+    defined( CYGPKG_UITRON_ALARMS )                             && \
+    (CYGNUM_UITRON_ALARMS >= 3)                                 && \
+    (CYGNUM_UITRON_ALARMS < 90)                                 && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+INT scratch;
+
+void hand1(void)
+{
+    CYG_TEST_INFO("Handler 1 called");
+    intercount++;
+}
+
+void hand2(void)
+{
+    CYG_TEST_CHECK( 2 == intercount, "handler out of sync" );
+    CYG_TEST_INFO("Handler 2 called");
+    intercount++;
+}
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+
+    T_DCYC dcyc;
+    T_DALM dalm;
+    T_RCYC rcyc;
+    T_RALM ralm;
+
+    unsigned int tm;
+
+    static char foo[] = "Test message";
+    VP info = (VP)foo;
+
+    // Increase times when running on HW since overhead of GDB packet
+    // acknowledgements may cause tests of timing to fail.
+    if (cyg_test_is_simulator)
+        tm = 1;
+    else
+        tm = 4;
+
+    CYG_TEST_INFO( "Task 1 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+
+    dcyc.exinf  = (VP)info;
+    dcyc.cycatr = TA_HLNG;
+    dcyc.cychdr = (FP)&hand1;
+    dcyc.cycact = TCY_INI;              // bad
+    dcyc.cyctim = 2;
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dcyc.cycact = TCY_OFF;              // make good
+    dcyc.cyctim = 0;                    // bad
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dcyc.cyctim = 1;                    // make good
+
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );    
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_cyc(-6, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+    ercd = def_cyc(99, &dcyc);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_cyc bad ercd !E_PAR" );
+
+    ercd = act_cyc(-6, TCY_OFF);
+    CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
+    ercd = act_cyc(99, TCY_OFF);
+    CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
+    ercd = act_cyc( 3, ~0);
+    CYG_TEST_CHECK( E_PAR == ercd, "act_cyc bad ercd !E_PAR" );
+    
+    ercd = ref_cyc(&rcyc, -6);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
+    ercd = ref_cyc(&rcyc, 99);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_cyc(NULL,  3);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_cyc bad ercd !E_PAR" );
+#endif
+#endif // we can test bad param error returns
+
+    ercd = def_cyc(3, (T_DCYC *)NADR);
+    CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = ref_cyc(&rcyc,  3);
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );    
+#endif // we can test bad param error returns
+
+    CYG_TEST_PASS( "bad calls: def_cyc, act_cyc, ref_cyc" );
+
+    dalm.exinf  = (VP)info;
+    dalm.almatr = TA_HLNG;
+    dalm.almhdr = (FP)&hand2;
+    dalm.tmmode = ~0;                   // bad
+    dalm.almtim = 20;
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dalm.tmmode = TTM_REL;              // make good
+    dalm.almtim = 0;                    // bad
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_PAR == ercd, "def_alm bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+
+    dalm.almtim = 1000;                 // make good
+
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = ref_alm(&ralm, -6);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
+    ercd = ref_alm(&ralm, 99);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_alm(NULL,  3);
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_alm bad ercd !E_PAR" );
+#endif
+
+#endif // we can test bad param error returns
+    ercd = def_alm(3, (T_DALM *)NADR);
+    CYG_TEST_CHECK( E_OK == ercd, "def_cyc bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = ref_alm(&ralm,  3);
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_cyc bad ercd !E_NOEXS" );    
+#endif // we can test bad param error returns
+
+    CYG_TEST_PASS( "bad calls: def_alm, act_alm, ref_alm" );
+    
+    dcyc.exinf  = (VP)info;
+    dcyc.cycatr = TA_HLNG;
+    dcyc.cychdr = (FP)&hand1;
+    dcyc.cycact = TCY_ON;
+    dcyc.cyctim = 50*tm;
+    
+    ercd = def_cyc(3, &dcyc);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+    ercd = act_cyc(3, TCY_OFF);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
+    ercd = act_cyc(3, TCY_ON);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc bad ercd" );
+    
+    CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc");
+
+    dalm.exinf  = (VP)info;
+    dalm.almatr = TA_HLNG;
+    dalm.almhdr = (FP)&hand2;
+    dalm.tmmode = TTM_REL;
+    dalm.almtim = 120*tm;
+
+    ercd = def_alm(3, &dalm);
+    CYG_TEST_CHECK( E_OK == ercd, "def_alm bad ercd" );
+    ercd = ref_alm(&ralm, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_alm bad ercd" );
+    CYG_TEST_CHECK( info == ralm.exinf, "ralm.exinf should be info" );
+    CYG_TEST_CHECK( 115*tm < ralm.lfttim, "ralm.lfttim too small" );
+    CYG_TEST_CHECK( ralm.lfttim <= 120*tm, "ralm.lfttim too big" );
+
+    // Expect handlers to be called at approximate times
+    // time           intercount
+    // tm*50  hand1   0
+    // tm*100 hand1   1
+    // tm*120 hand2   2
+    // tm*150 hand1   3
+
+    ercd = dly_tsk(160*tm);
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 4 == intercount, "handlers not both called" );
+    
+    ercd = act_cyc(3, TCY_OFF);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(off) bad ercd" );
+
+    ercd = dly_tsk(60*tm);              // enough for at least one tick
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 4 == intercount, "cyclic not disabled" );
+
+    // approx time now 220, so we expect a cycle in about 30 ticks
+    ercd = act_cyc(3, TCY_ON);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 25*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 35*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+
+    // now resynchronize with right now:
+    ercd = act_cyc(3, TCY_ON|TCY_INI);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+
+    // wait a bit and check that time marches on, or even down
+    ercd = dly_tsk(10*tm);
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 35*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 45*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_ON == rcyc.cycact, "rcyc.cycact should be TCY_ON" );
+
+    // now turn it off and re-synch with right now:
+    ercd = act_cyc(3, TCY_OFF|TCY_INI);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+    ercd = ref_cyc(&rcyc, 3);
+    CYG_TEST_CHECK( E_OK == ercd, "ref_cyc bad ercd" );
+    CYG_TEST_CHECK( info == rcyc.exinf, "rcyc.exinf should be info" );
+    CYG_TEST_CHECK( 45*tm < rcyc.lfttim, "rcyc.lfttim too small" );
+    CYG_TEST_CHECK( rcyc.lfttim <= 50*tm, "rcyc.lfttim too big" );
+    CYG_TEST_CHECK( TCY_OFF == rcyc.cycact, "rcyc.cycact should be TCY_OFF" );
+
+    ercd = act_cyc(3, TCY_OFF);
+    CYG_TEST_CHECK( E_OK == ercd, "act_cyc(on) bad ercd" );
+
+    CYG_TEST_PASS("good calls: def_cyc, act_cyc, ref_cyc, def_alm, ref_alm");
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx4.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcx5.cxx b/packages/compat/uitron/v2_0/tests/testcx5.cxx
new file mode 100644 (file)
index 0000000..ee16e61
--- /dev/null
@@ -0,0 +1,363 @@
+//===========================================================================
+//
+//      testcx5.cxx
+//
+//      uITRON "C++" test program five
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   dsm
+// Contributors:        dsm
+// Date:        1998-06-12
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+
+UINT scratch;
+T_MSG *t_msg;
+VP vp;
+
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    T_RSYS rsys;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    // check initial state
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+    // disable intrs and check state
+    ercd = loc_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // try an illegal op
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
+#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // enable intrs and check state and a legal sleep
+    ercd = unl_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+    ercd = dly_tsk( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    // disable intrs and try scheduler illegal ops
+    ercd = loc_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_CTX == ercd, "dis_dsp bad ercd !E_CTX" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_CTX == ercd, "ena_dsp bad ercd !E_CTX" );
+#endif // CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // enable again and check state
+    ercd = unl_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+    // disable the scheduler and check state
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_DDSP == rsys.sysstat, "system state not TSS_DDSP" );
+    // disable intrs and check state
+    ercd = loc_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "loc_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_LOC == rsys.sysstat, "system state not TSS_LOC" );
+    // then unlock and check state
+    ercd = unl_cpu();
+    CYG_TEST_CHECK( E_OK == ercd, "unl_cpu bad ercd" );
+    ercd = ref_sys( &rsys );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sys bad ercd" );
+    CYG_TEST_CHECK( TSS_TSK == rsys.sysstat, "system state not TSS_TSK" );
+
+    CYG_TEST_PASS( "Interrupt dis/enabling and interactions" );
+
+    // and now we can do the rest of the test
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
+    ercd = rel_wai( 1 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
+    ercd = rel_wai( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
+    ercd = rel_wai( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "rel_wai bad ercd !E_ID" );
+#endif // we can test bad param error returns
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai bad ercd !E_OBJ" );
+    ercd = rel_wai( 1 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai(me) bad ercd !E_OBJ" );
+#endif // we can test bad param error returns
+
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "wai_sem bad ercd !E_RLWAI" );
+
+    ercd = twai_sem( 1, 20 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "twai_sem bad ercd !E_RLWAI" );
+
+    ercd = wai_flg( &scratch, 1, 9999, 0 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "wai_flg bad ercd !E_RLWAI" );
+
+    ercd = twai_flg( &scratch, 1, 9999, 0, 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "twai_flg bad ercd !E_RLWAI" );
+
+    ercd = rcv_msg( &t_msg, 1 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "rcv_msg bad ercd !E_RLWAI" );
+
+    ercd = trcv_msg( &t_msg, 1, 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "trcv_msg bad ercd !E_RLWAI" );
+
+    // these are loops so as to consume the whole of the mempool
+    // in order to wait at the end
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = get_blf( &vp, 3 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "get_blf bad ercd !E_RLWAI" );
+
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = tget_blf( &vp, 3, 10 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blf bad ercd !E_RLWAI" );
+
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = get_blk( &vp, 1, 1000 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "get_blk bad ercd !E_RLWAI" );
+
+    for ( i = 0; i < 10; i++ )
+        if ( E_OK != (ercd = tget_blk( &vp, 1, 1000, 10 ) ) )
+            break;
+    CYG_TEST_CHECK( E_RLWAI == ercd, "tget_blk bad ercd !E_RLWAI" );
+
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "dly_tsk bad ercd !E_RLWAI" );
+
+    ercd = tslp_tsk( 10 );
+    CYG_TEST_CHECK( E_RLWAI == ercd, "tslp_tsk bad ercd !E_RLWAI" );
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_RLWAI == ercd, "slp_tsk bad ercd !E_RLWAI" );
+
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    CYG_TEST_PASS("release wait: various waiting calls");
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    for ( i = 0 ; i < 100; i++ ) {
+        ercd = rel_wai( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+    }        
+    // we expect task2 to be killed here
+    CYG_TEST_FAIL( "Task 2 ran to completion!" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx5.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcx6.cxx b/packages/compat/uitron/v2_0/tests/testcx6.cxx
new file mode 100644 (file)
index 0000000..14c01c5
--- /dev/null
@@ -0,0 +1,600 @@
+//===========================================================================
+//
+//      testcx6.cxx
+//
+//      uITRON "C++" test program six
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-14
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+UINT scratch;
+T_MSG *t_msg = (T_MSG *)&scratch;
+T_MSG *msg;
+VP vp;
+
+T_CSEM t_csem = { NULL, 0, 0 };
+T_CMBX t_cmbx = { NULL, 0 };
+T_CFLG t_cflg = { NULL, 0, 0 };
+T_RSEM t_rsem;
+T_RMBX t_rmbx;
+T_RFLG t_rflg;
+
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    int tests = 0;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_sem( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
+    ercd = del_sem( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_sem bad ercd !E_ID" );
+    ercd = cre_sem( -6, &t_csem );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
+    ercd = cre_sem( 99, &t_csem );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_sem bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_sem( 3, &t_csem );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_sem bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_sem( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    // check it is deleted
+    ercd = sig_sem( 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    ercd = preq_sem( 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "preq_sem bad ercd !E_NOEXS" );
+    ercd = twai_sem( 3, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "twai_sem bad ercd !E_NOEXS" );
+    ercd = wai_sem( 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wai_sem bad ercd !E_NOEXS" );
+    ercd = ref_sem( &t_rsem, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_sem bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_sem( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_sem bad ercd !E_PAR" );
+#endif
+    t_csem.sematr = 0xfff;
+    ercd = cre_sem( 3, &t_csem );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_sem bad ercd !E_RSATR" );
+    t_csem.sematr = 0;
+#endif // we can test bad param error returns
+    ercd = cre_sem( 3, &t_csem );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+    // and check we can use it
+    ercd = sig_sem( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    ercd = wai_sem( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    ercd = preq_sem( 3 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "preq_sem bad ercd !E_TMOUT" );
+    ercd = twai_sem( 3, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_sem bad ercd !E_TMOUT" );
+    ercd = ref_sem( &t_rsem, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_sem bad ercd" );
+
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_sem( 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    // re-create and do it again
+    ercd = cre_sem( 1, &t_csem );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+    ercd = cre_sem( 2, &t_csem );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+
+    // now wait while task 2 deletes the wait objects again
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_sem bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_sem( 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_sem bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+    ercd = sig_sem( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sig_sem bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete semaphores");
+#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_flg( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
+    ercd = del_flg( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_flg bad ercd !E_ID" );
+    ercd = cre_flg( -6, &t_cflg );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
+    ercd = cre_flg( 99, &t_cflg );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_flg bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_flg bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_flg( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    // check it is deleted
+    ercd = set_flg( 3, 0x6789 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
+    ercd = clr_flg( 3, 0x9876 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
+    ercd = pol_flg( &scratch, 3, 0xdddd, TWF_ANDW );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pol_flg bad ercd !E_NOEXS" );
+    ercd = twai_flg( &scratch, 3, 0x4444, TWF_ORW, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "twai_flg bad ercd !E_NOEXS" );
+    ercd = wai_flg( &scratch, 3, 0xbbbb, TWF_ANDW | TWF_CLR );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wai_flg bad ercd !E_NOEXS" );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_flg bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_flg( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_flg bad ercd !E_PAR" );
+#endif
+    t_cflg.flgatr = 0xfff;
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_flg bad ercd !E_RSATR" );
+#endif // we can test bad param error returns
+    // now create it well
+    t_cflg.flgatr = 0;
+    t_cflg.iflgptn = 0;
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+    // and check we can use it
+    ercd = clr_flg( 3, 0x7256 );
+    CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd" );
+    ercd = set_flg( 3, 0xff );
+    CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
+    ercd = wai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
+    ercd = pol_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = twai_flg( &scratch, 3, 0xaa, TWF_ANDW | TWF_CLR, 2 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "twai_flg bad ercd !E_TMOUT" );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
+    // now create it again with a preset pattern and check that we can
+    // detect that pattern:
+    ercd = del_flg( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    t_cflg.flgatr = 0;
+    t_cflg.iflgptn = 0x1234;
+    ercd = cre_flg( 3, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+    // and check we can use it
+    ercd = wai_flg( &scratch, 3, 0x1200, TWF_ANDW );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
+    ercd = pol_flg( &scratch, 3, 0x0034, TWF_ANDW );
+    CYG_TEST_CHECK( E_OK == ercd, "pol_flg bad ercd" );
+    ercd = twai_flg( &scratch, 3, 0x1004, TWF_ANDW, 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "twai_flg bad ercd" );
+    ercd = pol_flg( &scratch, 3, 0xffedcb, TWF_ORW );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pol_flg bad ercd !E_TMOUT" );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0x1234 == t_rflg.flgptn, "ref_flg bad ercd" );
+    ercd = clr_flg( 3, 0 );
+    ercd = ref_flg( &t_rflg, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_flg bad ercd" );
+    CYG_TEST_CHECK( 0 == t_rflg.flgptn, "ref_flg bad ercd" );
+
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_flg( &scratch, 1, 0xaa, TWF_ANDW );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_flg( &scratch, 2, 0x55, TWF_ANDW, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = set_flg( 1, 0x22 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
+    ercd = clr_flg( 2, 0xdd );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
+    // re-create and do it again
+    t_cflg.iflgptn = 0x5555;
+    ercd = cre_flg( 1, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+    t_cflg.iflgptn = 0;
+    ercd = cre_flg( 2, &t_cflg );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_flg bad ercd" );
+
+    // now wait while task 2 deletes the wait objects again
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wai_flg( &scratch, 1, 0xaaaa, TWF_ORW | TWF_CLR );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_flg bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = twai_flg( &scratch, 2, 0xffff, TWF_ORW, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_flg bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = clr_flg( 1, 0xd00d );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "clr_flg bad ercd !E_NOEXS" );
+    ercd = set_flg( 2, 0xfff00 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "set_flg bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete flags");
+#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_mbx( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
+    ercd = del_mbx( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mbx bad ercd !E_ID" );
+    ercd = cre_mbx( -6, &t_cmbx );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
+    ercd = cre_mbx( 99, &t_cmbx );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mbx bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_mbx( 3, &t_cmbx );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_mbx bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_mbx( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    // check it is deleted
+    ercd = snd_msg( 3, t_msg );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    ercd = rcv_msg( &msg, 3 );       
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rcv_msg bad ercd !E_NOEXS" );
+    ercd = trcv_msg( &msg, 3, 10 );   
+    CYG_TEST_CHECK( E_NOEXS == ercd, "trcv_msg bad ercd !E_NOEXS" );
+    ercd = prcv_msg( &msg, 3 );        
+    CYG_TEST_CHECK( E_NOEXS == ercd, "prcv_msg bad ercd !E_NOEXS" );
+    ercd = ref_mbx( &t_rmbx, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mbx bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_mbx( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mbx bad ercd !E_PAR" );
+#endif
+    t_cmbx.mbxatr = 0xfff;
+    ercd = cre_mbx( 3, &t_cmbx );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_mbx bad ercd !E_RSATR" );
+    t_cmbx.mbxatr = 0;
+#endif // we can test bad param error returns
+    ercd = cre_mbx( 3, &t_cmbx );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
+    // and check we can use it
+    ercd = snd_msg( 3, t_msg );
+    CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
+    ercd = rcv_msg( &msg, 3 );       
+    CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
+    ercd = trcv_msg( &msg, 3, 2 );   
+    CYG_TEST_CHECK( E_TMOUT == ercd, "trcv_msg bad ercd !E_TMOUT" );
+    ercd = prcv_msg( &msg, 3 );                            
+    CYG_TEST_CHECK( E_TMOUT == ercd, "prcv_msg bad ercd !E_TMOUT" );
+    ercd = ref_mbx( &t_rmbx, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mbx bad ercd" );
+
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rcv_msg( &msg, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = trcv_msg( &msg, 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = snd_msg( 1, t_msg );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    ercd = snd_msg( 2, t_msg );       
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    // re-create and do it again
+    ercd = cre_mbx( 1, &t_cmbx );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
+    ercd = cre_mbx( 2, &t_cmbx );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mbx bad ercd" );
+
+    // now wait while task 2 deletes the wait objects again
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rcv_msg( &msg, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "wai_mbx bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = trcv_msg( &msg, 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "twai_mbx bad ercd !E_DLT" );
+
+    // check they are deleted
+    ercd = snd_msg( 1, t_msg );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+    ercd = snd_msg( 2, t_msg );       
+    CYG_TEST_CHECK( E_NOEXS == ercd, "snd_msg bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete mboxes");
+#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
+
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    ercd = dly_tsk( 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    // all done
+    if ( 0 == tests ) {
+        CYG_TEST_NA( "No objects have create/delete enabled" );
+    }
+    else {
+        CYG_TEST_EXIT( "All done" );
+    }
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+    ercd = del_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_sem( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+    ercd = del_flg( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_flg( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_flg( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_flg( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+    ercd = del_mbx( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mbx( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mbx( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mbx( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
+
+    // we expect task2 to be killed here
+    CYG_TEST_FAIL( "Task 2 ran to completion!" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx6.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcx7.cxx b/packages/compat/uitron/v2_0/tests/testcx7.cxx
new file mode 100644 (file)
index 0000000..b50e968
--- /dev/null
@@ -0,0 +1,1101 @@
+//===========================================================================
+//
+//      testcx7.cxx
+//      
+//      uITRON "C++" test program seven
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-14
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough flag objects */               \
+    defined( CYGPKG_UITRON_FLAGS )                              && \
+    (CYGNUM_UITRON_FLAGS >= 3)                                  && \
+    (CYGNUM_UITRON_FLAGS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_FLAGS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_FLAGS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* test configuration for enough message boxes */              \
+    defined( CYGPKG_UITRON_MBOXES )                             && \
+    (CYGNUM_UITRON_MBOXES >= 3)                                 && \
+    (CYGNUM_UITRON_MBOXES < 90)                                 && \
+    ( !defined(CYGPKG_UITRON_MBOXES_CREATE_DELETE) ||              \
+      CYGNUM_UITRON_MBOXES_INITIALLY >= 3            )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+#include <cyg/kernel/test/stackmon.h>   // stack analysis tools
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+// ========================================================================
+
+enum {
+    START_WAITOP = 0,
+    SLEEP = 0,
+    DELAY,
+    SEMGET,
+    FLAGWAIT,
+    MSGGET,
+    MEMFIXEDGET,
+    MEMVARGET,
+    DONE_WAITOP
+};
+typedef int WAITOP;
+
+enum {
+    START_TYPE = 0,
+    PLAIN = 0,
+    TIMED = 1,
+    DONE_TYPE
+};
+typedef int WAITTYPE;
+
+enum {
+    START_KILLOP = 0,
+
+    // These are the 5 ways out of a wait that we perm
+    // with other circumstances:
+    SIGNAL = 0,                         // do the appropriate producer op
+    TIMEOUT,                            // wait for the timeout to fire
+    RELEASE,                            // do a rel_wai()
+    DELETE,                             // delete the object; del_xxx()
+    KILL,                               // do a ter_tsk() on the waiter
+
+    SUSPEND_SIGNAL_RESUME,
+    SUSPEND_TIMEOUT_RESUME,
+    SUSPEND_RELEASE_RESUME,
+    SUSPEND_DELETE_RESUME,
+    SUSPEND_KILL,                       // resume not applicable
+
+    SUSPEND_SIGNAL_KILL,
+    SUSPEND_TIMEOUT_KILL,
+    SUSPEND_RELEASE_KILL,
+    SUSPEND_DELETE_KILL,
+    // SUSPEND_KILL_KILL not applicable
+
+#if 0
+    // support these later if _really_ keen.
+    SUSPEND_SIGNAL_DELETE_RESUME,
+    SUSPEND_TIMEOUT_DELETE_RESUME,
+    SUSPEND_RELEASE_DELETE_RESUME,
+    // SUSPEND_DELETE_DELETE_RESUME not applicable
+    // SUSPEND_KILL_DELETE_RESUME not applicable
+
+    SUSPEND_SIGNAL_DELETE_KILL,
+    SUSPEND_TIMEOUT_DELETE_KILL,
+    SUSPEND_RELEASE_DELETE_KILL,
+    // SUSPEND_DELETE_DELETE_KILL,
+    SUSPEND_KILL_DELETE                 // 2nd kill not applicable
+#endif
+          
+    DONE_KILLOP
+};
+typedef int KILLOP;
+        
+// ========================================================================
+
+char * waitstrings[] =
+{ "Sleep ", "Delay ", "Sema  ", "Flag  ", "Mbox  ", "MemFix", "MemVar" };
+
+char * typestrings[] =
+{ " (Plain) : ", " (Timed) : " };
+
+char * killstrings[] =
+{ "Signal",
+  "Wait-for-timeout",
+  "Release-wait",
+  "Delete-object",
+  "Kill-task",
+
+  "Suspend/Signal/Resume",
+  "Suspend/Wait-for-timeout/Resume",
+  "Suspend/Release-wait/Resume",
+  "Suspend/Delete-object/Resume",
+  "Suspend/Kill-task",
+
+  "Suspend/Signal/Kill-task",
+  "Suspend/Wait-for-timeout/Kill-task",
+  "Suspend/Release-wait/Kill-task",
+  "Suspend/Delete-object/Kill-task",
+  
+
+};
+
+// ========================================================================
+
+inline int task2arg( WAITOP wait, WAITTYPE waittype, KILLOP kill )
+{
+    return waittype + (wait << 1) + (kill << 8);
+}
+
+inline void decodearg( int arg, WAITOP *pwait, WAITTYPE *pwaittype, KILLOP *pkill )
+{
+    *pwaittype = (arg & 1) ? TIMED : PLAIN;
+    *pwait  = (arg >> 1) & 0x7f;
+    *pkill  = (arg >> 8);
+}
+
+static char *strdog( char *p, char *q )
+{
+    while ( 0 != (*p++ = *q++) );
+    return p - 1;
+}
+
+static char *
+makemsg( char *z, WAITOP wait, WAITTYPE waittype, KILLOP kill )
+{
+    static char buf[ 1000 ];
+    char *p = buf;
+    p = strdog( p, z );
+    p = strdog( p, waitstrings[ wait ] );
+    p = strdog( p, typestrings[ waittype ] );
+    p = strdog( p, killstrings[ kill ] );
+    *p = 0;
+    return buf;
+}
+
+// ========================================================================
+
+volatile int intercom = 0;
+
+// ========================================================================
+
+T_RTSK rtsk;
+
+void
+do_suspend( void )
+{
+    ER ercd;
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat !TTS_WAI" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_WAS == rtsk.tskstat, "bad tskstat !TTS_WAS" );
+}
+
+void
+do_resume( void )
+{
+    ER ercd;
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_SUS == rtsk.tskstat, "bad tskstat !TTS_SUS" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = ref_tsk( &rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RDY == rtsk.tskstat, "bad tskstat !TTS_RDY" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+}
+
+// ========================================================================
+
+#define T1_WAIT (7)
+#define T2_WAIT (5)
+
+#define T1_MALLOC (110)
+#ifdef CYGSEM_KERNEL_MEMORY_COALESCE
+#define T2_MALLOC (100)
+#else
+#define T2_MALLOC T1_MALLOC
+#endif
+
+VP vptmp;
+VP vp = NULL;
+VP vp1 = NULL;
+VP t2vp = NULL;
+VP t2vp_backup = NULL;
+
+UINT scratch;
+
+T_MSG *msg = (T_MSG *)&scratch;
+T_MSG *msg1;
+
+void
+do_prep( WAITOP wait )
+{
+    ER ercd;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+    case SEMGET:
+    case FLAGWAIT:
+    case MSGGET:
+        // do nothing for all of those
+        break;
+    case MEMFIXEDGET:
+        // allocate all the memory in the pool; remember a couple
+        // for freeing as the signalling operation:
+        t2vp = NULL;
+        vp = vptmp = NULL;
+        do {
+            vp1 = vptmp;
+            vptmp = vp;
+            ercd = pget_blf( &vp, 1 );
+        } while ( E_OK == ercd );
+        CYG_TEST_CHECK( E_TMOUT == ercd, "get_blf bad ercd" );
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        break;
+    case MEMVARGET:
+        // allocate all the memory in the pool; remember a couple
+        // for freeing as the signalling operation:
+        t2vp = NULL;
+        vp = vptmp = NULL;
+        do {
+            vp1 = vptmp;
+            vptmp = vp;
+            ercd = pget_blk( &vp, 1, T1_MALLOC );
+        } while ( E_OK == ercd );
+        CYG_TEST_CHECK( E_TMOUT == ercd, "get_blk bad ercd" );
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void
+do_tidyup( WAITOP wait )
+{
+    ER ercd;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+    case SEMGET:
+    case MSGGET:
+        // do nothing for all of those
+        break;
+    case FLAGWAIT:
+        // clear the flag variable
+        ercd = clr_flg( 1, 0 );
+        CYG_TEST_CHECK( E_OK == ercd, "clr_flg bad ercd, tidy vp" );
+        break;
+    case MEMFIXEDGET:
+        if ( NULL != vp ) {
+            ercd = rel_blf( 1, vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp" );
+        }
+        if ( NULL != vp1 ) {
+            ercd = rel_blf( 1, vp1 );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy vp1" );
+        }
+        if ( NULL != t2vp ) {
+            ercd = rel_blf( 1, t2vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd, tidy t2vp" );
+        }
+        break;
+    case MEMVARGET:
+        if ( NULL != vp ) {
+            ercd = rel_blk( 1, vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp" );
+        }
+        if ( NULL != vp1 ) {
+            ercd = rel_blk( 1, vp1 );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy vp1" );
+        }
+        if ( NULL != t2vp ) {
+            ercd = rel_blk( 1, t2vp );
+            CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd, tidy t2vp" );
+        }
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void
+do_recreate( WAITOP wait )
+{ 
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+    static T_CSEM t_csem = { NULL, 0, 0 };
+#endif
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+    static T_CMBX t_cmbx = { NULL, 0 };
+#endif
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+    static T_CFLG t_cflg = { NULL, 0, 0 };
+#endif
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+    static T_CMPF t_cmpf = { NULL, 0, 20, 95 };
+#endif
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+    static T_CMPL t_cmpl = { NULL, 0, 2000 };
+#endif
+    ER ercd = E_OK;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+        // do nothing for all of those
+        break;
+    case SEMGET:
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+        // create the semaphore
+        ercd = cre_sem( 1, &t_csem );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate SEMGET" );
+#endif
+        break;
+    case FLAGWAIT:
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+        // create the flag
+        ercd = cre_flg( 1, &t_cflg );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate FLAGWAIT" );
+#endif
+        break;
+    case MSGGET:
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+        // create the mbox
+        ercd = cre_mbx( 1, &t_cmbx );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate MSGGET" );
+#endif
+        break;
+    case MEMFIXEDGET:
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+        // create the mempool
+        ercd = cre_mpf( 1, &t_cmpf );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate MEMFIXEDGET" );
+#endif
+        break;
+    case MEMVARGET:
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+        // create the mempool
+        ercd = cre_mpl( 1, &t_cmpl );
+        CYG_TEST_CHECK( E_OK == ercd, "cre_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_recreate MEMVARGET" );
+#endif
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+    // this is just to use ercd to prevent warnings
+    CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
+}
+
+
+
+void
+do_signal( WAITOP wait )
+{
+    ER ercd;
+    switch ( wait ) {
+    case SLEEP:
+        // send a wakeup
+        ercd = wup_tsk( 2 );
+        CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+        break;
+    case DELAY:
+        // simply wait for task 2's delay to complete
+        ercd = dly_tsk( T1_WAIT );
+        CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+        break;
+    case SEMGET:
+        // signal the semaphore
+        ercd = sig_sem( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+        break;
+    case FLAGWAIT:
+        // set the flag bits
+        ercd = set_flg( 1, 0xff );
+        CYG_TEST_CHECK( E_OK == ercd, "set_flg bad ercd" );
+        break;
+    case MSGGET:
+        // send a message
+        ercd = snd_msg( 1, msg );
+        CYG_TEST_CHECK( E_OK == ercd, "snd_msg bad ercd" );
+        break;
+    case MEMFIXEDGET:
+        // release a couple of blocks we allocated earlier.  I hope.
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        ercd = rel_blf( 1, vp );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+        vp = NULL;
+        ercd = rel_blf( 1, vp1 );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd1" );
+        vp1 = NULL;
+        break;
+    case MEMVARGET:
+        // release a couple of blocks we allocated earlier.  I hope.
+        CYG_TEST_CHECK( NULL != vp,  "no allocated block to free" );
+        CYG_TEST_CHECK( NULL != vp1, "no allocated block to free1" );
+        ercd = rel_blk( 1, vp );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+        vp = NULL;
+        ercd = rel_blk( 1, vp1 );
+        CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd1" );
+        vp1 = NULL;
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void
+do_delete( WAITOP wait )
+{
+    ER ercd = E_OK;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+        CYG_TEST_FAIL( "bad call to do_delete( SLEEP or DELAY )" );
+        break;
+    case SEMGET:
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+        // delete the semaphore
+        ercd = del_sem( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_sem bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( SEMGET )" );
+#endif
+        break;
+    case FLAGWAIT:
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+        // delete the flag
+        ercd = del_flg( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_flg bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( FLAGWAIT )" );
+#endif
+        break;
+    case MSGGET:
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+        // delete the mbox
+        ercd = del_mbx( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_mbx bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( MSGGET )" );
+#endif
+        break;
+    case MEMFIXEDGET:
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+        // delete the mempool
+        ercd = del_mpf( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( MEMFIXEDGET )" );
+#endif
+        break;
+    case MEMVARGET:
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+        // delete the mempool
+        ercd = del_mpl( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+#else
+        CYG_TEST_FAIL( "bad call to do_delete( MEMVARGET )" );
+#endif
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+    // this is just to use ercd to prevent warnings
+    CYG_TEST_CHECK( E_OK == ercd, "<blank> bad ercd" );
+}
+
+
+ER
+do_wait( WAITOP wait, WAITTYPE type )
+{
+    switch ( wait ) {
+    case SLEEP:
+        return ( PLAIN == type ) ? slp_tsk() : tslp_tsk( T2_WAIT );
+    case DELAY:
+        return dly_tsk( T2_WAIT );      // forget the type
+    case SEMGET:
+        return ( PLAIN == type ) ? wai_sem( 1 ) : twai_sem( 1, T2_WAIT );
+    case FLAGWAIT:
+        return ( PLAIN == type ) ?
+            wai_flg( &scratch, 1, 0x55, TWF_ANDW ) :
+           twai_flg( &scratch, 1, 0xaa, TWF_ANDW, T2_WAIT );
+    case MSGGET:
+        return ( PLAIN == type ) ?
+            rcv_msg( &msg1, 1 ) :
+           trcv_msg( &msg1, 1, T2_WAIT );
+    case MEMFIXEDGET:
+        return ( PLAIN == type ) ?
+            get_blf( &t2vp, 1 ) :
+           tget_blf( &t2vp, 1, T2_WAIT );
+    case MEMVARGET:
+        return ( PLAIN == type ) ?
+            get_blk( &t2vp, 1, T2_MALLOC ) :
+           tget_blk( &t2vp, 1, T2_MALLOC, T2_WAIT );
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+    CYG_TEST_FAIL( "Bad wait in do_wait" );
+    return E_SYS;
+}
+
+void
+check_waitstate( WAITOP wait, int waiting )
+{
+    ER ercd;
+    int waity = 0;
+    switch ( wait ) {
+    case SLEEP:
+    case DELAY:
+        return;                         // do nothing for these
+    case SEMGET: {
+        T_RSEM rsem;
+        ercd = ref_sem( &rsem, 1 );
+        waity = rsem.wtsk;
+        break;
+    }
+    case FLAGWAIT: {
+        T_RFLG rflg;
+        ercd = ref_flg( &rflg, 1 );
+        waity = rflg.wtsk;
+        break;
+    }
+    case MSGGET: {
+        T_RMBX rmbx;
+        ercd = ref_mbx( &rmbx, 1 );
+        waity = rmbx.wtsk;
+        break;
+    }
+    case MEMFIXEDGET: {
+        T_RMPF rmpf;
+        ercd = ref_mpf( &rmpf, 1 );
+        waity = rmpf.wtsk;
+        break;
+    }
+    case MEMVARGET: {
+        T_RMPL rmpl;
+        ercd = ref_mpl( &rmpl, 1 );
+        waity = rmpl.wtsk;
+        break;
+    }
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+    if ( waiting )
+        CYG_TEST_CHECK( waity, "Object has no task waiting!" );
+    else
+        CYG_TEST_CHECK( !waity, "Object had a task waiting!" );
+}
+
+// ========================================================================
+void task1( unsigned int arg )
+{
+    ER ercd;
+    WAITOP wait;
+    WAITTYPE type;
+    KILLOP kill;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    {
+        extern Cyg_Thread cyg_uitron_TASKS[];
+        cyg_test_dump_thread_stack_stats(
+            "Startup, task1", &cyg_uitron_TASKS[ 0 ] );
+        cyg_test_dump_thread_stack_stats(
+            "Startup, task2", &cyg_uitron_TASKS[ 1 ] );
+        cyg_test_dump_interrupt_stack_stats( "Startup" );
+        cyg_test_dump_idlethread_stack_stats( "Startup" );
+        cyg_test_clear_interrupt_stack();
+    }
+
+    ercd = chg_pri( 1, 8 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+
+    for ( wait = START_WAITOP; wait < DONE_WAITOP ; wait++) {
+        for ( type = START_TYPE; type < DONE_TYPE   ; type++ ) {
+            for ( kill = START_KILLOP; kill < DONE_KILLOP ; kill++ ) {
+                
+                // These clauses deal with a couple of special cases:
+                // [doing it this way helps keep the rest of the code
+                //  nicely general and orthogonal]
+                // 
+                // 1) DELAY: dly_tsk(): when this times out, the retcode is
+                // E_OK rather than E_TMOUT, and it always times out.  The
+                // "signalling" method here is just to wait yourself.  So we
+                // do not test DELAY with TIMED type.
+                //
+                // 2) PLAIN tests with TIMEOUT kill operations: a PLAIN test
+                // will not time out, it'll wait forever, so waiting for it
+                // so to do is pointless; further, we would check for the
+                // wrong error code.  So we do not test PLAIN tests with
+                // TIMOUT kill operations.
+                //
+                // 3) SLEEP or DELAY tests with DELETE operations: there is
+                // no synchronization to delete in those cases.
+                // 3a) Individual object types are tested for delete support,
+                // and if there is none, the test is skipped.
+
+                if ( DELAY == wait && TIMED == type )
+                    continue;
+
+                if ( PLAIN == type &&
+                     ( (        TIMEOUT        == kill) ||
+                       (SUSPEND_TIMEOUT_RESUME == kill) ||
+                       (SUSPEND_TIMEOUT_KILL   == kill) ) )
+                    continue;
+
+                if ( ( 
+#ifndef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+                    (SEMGET      == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+                    (FLAGWAIT    == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+                    (MSGGET      == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+                    (MEMFIXEDGET == wait) ||
+#endif
+#ifndef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+                    (MEMVARGET   == wait) ||
+#endif
+                    (SLEEP       == wait) ||
+                    (DELAY       == wait)
+                    ) &&
+                     ((DELETE                == kill) ||
+                      (SUSPEND_DELETE_RESUME == kill) ||
+                      (SUSPEND_DELETE_KILL   == kill)) )
+                    continue;
+
+
+                CYG_TEST_INFO( makemsg( "T1: ", wait, type, kill ) );
+
+                intercom = 0;
+
+                // prepare the synchronization objects
+                // (actually, just empty the mempools)
+                do_prep( wait );
+
+                // start task 2 at a higher priority than myself
+                ercd = dis_dsp();
+                CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+                ercd = sta_tsk( 2, task2arg( wait, type, kill ) );
+                CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+                ercd = chg_pri( 2, 5 );
+                CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+                ercd = ena_dsp();
+                CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+                // task 2 should run now, until it waits.
+
+                ercd = ref_tsk( &rtsk, 2 );
+                CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+                CYG_TEST_CHECK( TTS_WAI == rtsk.tskstat, "bad tskstat" );
+                CYG_TEST_CHECK( 5 == rtsk.tskpri, "bad tskpri" );
+
+                switch ( kill ) {
+                case SIGNAL:
+                    // signal the task appropriately
+                    do_signal( wait );
+                    // it should now have run to completion
+                    break;
+                case TIMEOUT:
+                    check_waitstate( wait, 1 );
+                    // wait for the timeout to occur
+                    ercd = dly_tsk( T1_WAIT );
+                    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+                    check_waitstate( wait, 0 );
+                    // it should now have run to completion
+                    break;
+                case RELEASE:
+                    // hit the task with a release-wait
+                    ercd = rel_wai( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+                    // it should now have run to completion
+                    break;
+                case DELETE:
+                    // delete the object appropriately
+                    do_delete( wait );
+                    // it should now have run to completion
+                    break;
+                case KILL:
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_SIGNAL_RESUME:
+                    // suspend the task
+                    do_suspend();
+                    // signal the task appropriately
+                    do_signal( wait );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_TIMEOUT_RESUME:
+                    check_waitstate( wait, 1 );
+                    // suspend the task
+                    do_suspend();
+                    check_waitstate( wait, 1 );
+                    // wait for the timeout to occur
+                    ercd = dly_tsk( T1_WAIT );
+                    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+                    check_waitstate( wait, 0 );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_RELEASE_RESUME:
+                    // suspend the task
+                    do_suspend();
+                    // hit the task with a release-wait
+                    ercd = rel_wai( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_DELETE_RESUME:
+                    // suspend the task
+                    do_suspend();
+                    // delete the object appropriately
+                    do_delete( wait );
+                    // resume the task
+                    do_resume();
+                    // it should now have run to completion
+                    break;
+                case SUSPEND_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_SIGNAL_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // signal the task appropriately
+                    do_signal( wait );
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_TIMEOUT_KILL:
+                    check_waitstate( wait, 1 );
+                    // suspend the task
+                    do_suspend();
+                    check_waitstate( wait, 1 );
+                    // wait for the timeout to occur
+                    ercd = dly_tsk( T1_WAIT );
+                    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+                    check_waitstate( wait, 0 );
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_RELEASE_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // hit the task with a release-wait
+                    ercd = rel_wai( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "rel_wai bad ercd" );
+                     // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                case SUSPEND_DELETE_KILL:
+                    // suspend the task
+                    do_suspend();
+                    // delete the object appropriately
+                    do_delete( wait );
+                    // kill the task
+                    ercd = ter_tsk( 2 );
+                    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+                    // it should now have terminated without running
+                    break;
+                default:
+                    CYG_TEST_FAIL( "bad switch" );
+                    break;
+                }
+                
+                // task 2 should be dormant now, however it got there
+                ercd = ref_tsk( &rtsk, 2 );
+                CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+                CYG_TEST_CHECK( TTS_DMT == rtsk.tskstat, "bad tskstat" );
+
+                if ( (SUSPEND_SIGNAL_KILL == kill) &&
+                     ((MEMFIXEDGET == wait) || (MEMVARGET == wait)) ) {
+                    // it was a killed successful memory alloc, so we have
+                    // lost the pointer to memory allocated; there is an
+                    // implicit storeleak problem when the task trying
+                    // to allocate is signalled then killed.
+                    // Recreate the pointer from an old version:
+                    CYG_TEST_CHECK( NULL == t2vp, "t2vp WAS allocated!" );
+                    t2vp = t2vp_backup;
+                }
+
+                switch ( kill ) {
+                case KILL:
+                case SUSPEND_KILL:
+                case SUSPEND_SIGNAL_KILL:
+                case SUSPEND_TIMEOUT_KILL:
+                case SUSPEND_RELEASE_KILL:
+                case SUSPEND_DELETE_KILL:
+                    // if task 2 was killed, expect only one increment
+                    CYG_TEST_CHECK( 1 == intercom, "intercom bad value !1" );
+                    break;
+                default:
+                    // otherwise expect two increments
+                    CYG_TEST_CHECK( 2 == intercom, "intercom bad value !2" );
+                    break;
+                }
+                
+                // tidy up or recreate the synchronization objects
+                if ( (DELETE                == kill) ||
+                     (SUSPEND_DELETE_RESUME == kill) ||
+                     (SUSPEND_DELETE_KILL   == kill) )
+                    do_recreate( wait );
+                else
+                    do_tidyup( wait );
+            }
+        }
+    }
+    CYG_TEST_PASS("synchronization interaction tests");
+
+    {
+        extern Cyg_Thread cyg_uitron_TASKS[];
+        cyg_test_dump_thread_stack_stats(
+            "All done, task1", &cyg_uitron_TASKS[ 0 ] );
+        cyg_test_dump_thread_stack_stats(
+            "All done, task2", &cyg_uitron_TASKS[ 1 ] );
+        cyg_test_dump_interrupt_stack_stats( "All done" );
+        cyg_test_dump_idlethread_stack_stats( "All done" );
+    }
+    // all done
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    WAITOP wait;
+    WAITTYPE waittype;
+    KILLOP kill;
+
+    decodearg( arg, &wait, &waittype, &kill );
+
+//    CYG_TEST_INFO( makemsg( " 2: ", wait, waittype, kill ) );
+
+    intercom++;
+    ercd = do_wait( wait, waittype );
+    intercom++;
+
+    switch ( kill ) {
+    case SIGNAL:
+    case SUSPEND_SIGNAL_RESUME:
+        // we expect to have been signalled correctly
+        CYG_TEST_CHECK( E_OK == ercd, "T2 wait bad ercd" );
+        // here we know that the op completed OK
+        if ( (MEMFIXEDGET == wait) || (MEMVARGET == wait) ) {
+            // it was a successful memory alloc of whichever type,
+            // so we can save away a copy of t2vp for working round an
+            // implicit storeleak problem when the task trying to allocate
+            // is signalled then killed:
+            CYG_TEST_CHECK( NULL != t2vp, "No t2vp allocated!" );
+            t2vp_backup = t2vp;
+        }
+        break;
+    case TIMEOUT:
+    case SUSPEND_TIMEOUT_RESUME:
+        // we expect to have timed out - if it's a timeout op.
+        CYG_TEST_CHECK( E_TMOUT == ercd, "T2 timeout bad ercd, !E_TMOUT" );
+        break;
+    case RELEASE:
+    case SUSPEND_RELEASE_RESUME:
+        // we expect to have suffered a release wait.
+        CYG_TEST_CHECK( E_RLWAI == ercd, "T2 release bad ercd, !E_RLWAI" );
+        break;
+    case DELETE:
+    case SUSPEND_DELETE_RESUME:
+        // we expect to be told the object is gone
+        CYG_TEST_CHECK( E_DLT == ercd, "T2 release bad ercd, !E_DLT" );
+        break;
+    case KILL:
+    case SUSPEND_KILL:
+    case SUSPEND_SIGNAL_KILL:
+    case SUSPEND_TIMEOUT_KILL:
+    case SUSPEND_RELEASE_KILL:
+    case SUSPEND_DELETE_KILL:
+        // we expect to have been killed here, ie. this won't execute!
+        CYG_TEST_FAIL( "Task 2 ran to completion!" );
+        break;
+    default:
+        CYG_TEST_FAIL( "bad switch" );
+        break;
+    }
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx7.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcx8.cxx b/packages/compat/uitron/v2_0/tests/testcx8.cxx
new file mode 100644 (file)
index 0000000..cb6eb41
--- /dev/null
@@ -0,0 +1,395 @@
+//===========================================================================
+//
+//      testcx8.cxx
+//
+//      uITRON "C++" test program eight
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-14
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough semaphores */                 \
+    defined( CYGPKG_UITRON_SEMAS )                              && \
+    (CYGNUM_UITRON_SEMAS >= 3)                                  && \
+    (CYGNUM_UITRON_SEMAS < 90)                                  && \
+    ( !defined(CYGPKG_UITRON_SEMAS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_SEMAS_INITIALLY >= 3             )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercount = 0;
+INT scratch;
+
+void newtask( unsigned int arg );
+
+T_CTSK t_ctsk = { NULL, 0, (FP)&newtask, 1, CYGNUM_UITRON_STACK_SIZE };
+T_RTSK t_rtsk;
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    // change us to prio 3 for flexibility
+    ercd = chg_pri( 0, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+    // first, check that we can delete a task:
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
+    ercd = del_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_tsk bad ercd !E_ID" );
+    ercd = cre_tsk( -6, &t_ctsk );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
+    ercd = cre_tsk( 99, &t_ctsk );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_tsk bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
+    // try a pre-existing object - ourselves!
+    ercd = cre_tsk( 1, &t_ctsk );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
+    // try deleting an active task
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    // Task 2 is now ready-to-run, lower prio than us
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    // Task 2 is now sleeping
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    // try deleting a running task - ourselves!
+    ercd = del_tsk( 1 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    // terminate task 2; should then be OK to delete it
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    // and check it is deleted
+    ercd = sta_tsk( 2, 99 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
+    ercd = chg_pri( 2, 6 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
+    // recreate task2, with the same function
+    t_ctsk.task = (FP)&task2;
+    t_ctsk.itskpri = 7;
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
+    CYG_TEST_CHECK( TTS_DMT == t_rtsk.tskstat,
+                    "Bad tskstat in new task2 !TTS_DMT" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    // now start the task and do the same lot again...
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_tsk bad ercd !E_OBJ" );
+    // try deleting an active task
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    // Task 2 is now ready-to-run, lower prio than us
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    CYG_TEST_CHECK( 1 == intercount, "bad intercount !1" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
+    // Task 2 is now sleeping
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 7 == t_rtsk.tskpri, "Bad tskpri in new task2 !7" );
+    CYG_TEST_CHECK( TTS_WAI == t_rtsk.tskstat,
+                    "Bad tskstat in new task2 !TTS_WAI" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "del_tsk bad ercd !E_OBJ" );
+    // up its priority
+    ercd = chg_pri( 2, 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    // awaken task 2; it will then exit-and-delete itself:
+    CYG_TEST_CHECK( 2 == intercount, "bad intercount !2" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    // and check it is deleted
+    ercd = sta_tsk( 2, 99 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sta_tsk bad ercd !E_NOEXS" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ter_tsk bad ercd !E_NOEXS" );
+    ercd = chg_pri( 2, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "chg_pri bad ercd !E_NOEXS" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_wai bad ercd !E_NOEXS" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "sus_tsk bad ercd !E_NOEXS" );
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rsm_tsk bad ercd !E_NOEXS" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "frsm_tsk bad ercd !E_NOEXS" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "wup_tsk bad ercd !E_NOEXS" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "can_wup bad ercd !E_NOEXS" );
+    ercd = ref_tsk( &t_rtsk, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    ercd = del_tsk( 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "del_tsk bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_tsk( 2, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_tsk bad ercd !E_PAR" );
+#endif
+    t_ctsk.stksz = 0x40000000;
+    ercd = cre_tsk( 2, &t_ctsk );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_tsk bad ercd !E_NOMEM" );
+    t_ctsk.stksz = CYGNUM_UITRON_STACK_SIZE;
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+#endif // we can test bad param error returns
+
+    ercd = del_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
+    t_ctsk.task = (FP)&task4;
+    t_ctsk.itskpri = 9;
+    ercd = cre_tsk( 3, &t_ctsk );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    // check we can delete it again immediately
+    ercd = del_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_tsk bad ercd" );
+    ercd = ref_tsk( &t_rtsk, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_tsk bad ercd !E_NOEXS" );
+    t_ctsk.task = (FP)&newtask;
+    t_ctsk.itskpri = 1;
+    ercd = cre_tsk( 3, &t_ctsk );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "bad intercount !3" );
+    ercd = sta_tsk( 3, 999 );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    // it should have run now, and exited
+    CYG_TEST_CHECK( 5 == intercount, "bad intercount !5" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    // and check that it will just run again...
+    ercd = sta_tsk( 3, 999 );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_tsk bad ercd" );
+    // it should have run now, and exited
+    CYG_TEST_CHECK( 7 == intercount, "bad intercount !7" );
+    ercd = wai_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+    // all done.
+
+    CYG_TEST_PASS("create/delete tasks");
+
+    // all done
+    CYG_TEST_EXIT( "All done" );
+#else // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
+    CYG_TEST_NA( "Tasks do not have create/delete enabled" );
+#endif // ! CYGPKG_UITRON_TASKS_CREATE_DELETE
+    ext_tsk();
+}
+
+
+
+void newtask( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Newtask running" );
+    CYG_TEST_CHECK( 999 == arg, "Bad arg to newtask() !999" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 3 == i, "tid not 3" );
+    intercount++;
+    ercd = sig_sem( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "sig_sem bad ercd" );
+    intercount++;
+    // and just return
+}
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    intercount++;
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+
+    intercount++;
+
+    exd_tsk(); // if we are not killed first
+
+    intercount++; // shouldn't happen
+}
+
+void task3( unsigned int arg )
+{
+    CYG_TEST_FAIL( "How come I'm being run?" );
+}
+
+void task4( unsigned int arg )
+{
+    CYG_TEST_FAIL( "How come I'm being run?" );
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx8.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcx9.cxx b/packages/compat/uitron/v2_0/tests/testcx9.cxx
new file mode 100644 (file)
index 0000000..d8c38c2
--- /dev/null
@@ -0,0 +1,492 @@
+//===========================================================================
+//
+//      testcx9.cxx
+//
+//      uITRON "C++" test program nine
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-10-16
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* test configuration for enough fixed memory pools */         \
+    defined( CYGPKG_UITRON_MEMPOOLFIXED )                       && \
+    (CYGNUM_UITRON_MEMPOOLFIXED >= 3)                           && \
+    (CYGNUM_UITRON_MEMPOOLFIXED < 90)                           && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE) ||        \
+      CYGNUM_UITRON_MEMPOOLFIXED_INITIALLY >= 3       )         && \
+                                                                   \
+    /* test configuration for enough variable mempools */          \
+    defined( CYGPKG_UITRON_MEMPOOLVAR )                         && \
+    (CYGNUM_UITRON_MEMPOOLVAR >= 3)                             && \
+    (CYGNUM_UITRON_MEMPOOLVAR < 90)                             && \
+    ( !defined(CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE) ||          \
+      CYGNUM_UITRON_MEMPOOLVAR_INITIALLY >= 3       )           && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+VP vp;
+
+T_CMPL t_cmpl = { NULL, 0, 1000 };
+T_RMPL t_rmpl;
+T_CMPF t_cmpf = { NULL, 0, 10, 100 };
+T_RMPF t_rmpf;
+
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    int tests = 0;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 2, 22222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_mpf( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
+    ercd = del_mpf( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpf bad ercd !E_ID" );
+    ercd = cre_mpf( -6, &t_cmpf );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
+    ercd = cre_mpf( 99, &t_cmpf );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpf bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    // [first get a valid block from it for the freeing test later]
+    ercd = pget_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpf bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_mpf( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    // check it is deleted
+    ercd = rel_blf( 3, vp );            // vp did come from this pool
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blf bad ercd !E_NOEXS" );
+    ercd = pget_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
+    ercd = tget_blf( &vp, 3, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blf bad ercd !E_NOEXS" );
+    ercd = get_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
+    ercd = ref_mpf( &t_rmpf, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpf bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_mpf( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mpf bad ercd !E_PAR" );
+#endif
+    t_cmpf.mpfatr = 0xfff;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpf bad ercd !E_RSATR" );
+#endif // we can test bad param error returns
+    t_cmpf.mpfatr = 0;
+    t_cmpf.mpfcnt = 10000;
+    t_cmpf.blfsz = 100;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
+    t_cmpf.mpfcnt = 100;
+    t_cmpf.blfsz = 100000;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpf bad ercd" );
+    // now create it well
+    t_cmpf.mpfatr = 0;
+    t_cmpf.mpfcnt = 10;
+    t_cmpf.blfsz = 100;
+    ercd = cre_mpf( 3, &t_cmpf );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
+    // and check we can use it
+    ercd = pget_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blf bad ercd" );
+    ercd = tget_blf( &vp, 3, 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blf bad ercd" );
+    ercd = get_blf( &vp, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blf bad ercd" );
+    ercd = rel_blf( 3, vp );            // vp did come from new pool
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blf bad ercd" );
+    ercd = rel_blf( 3, vp );            // vp already freed
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blf bad ercd !E_PAR" );
+    ercd = ref_mpf( &t_rmpf, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpf bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blf( &vp, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blf( &vp, 2, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = get_blf( &vp, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
+    ercd = pget_blf( &vp, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
+
+    // re-create and do it again
+    t_cmpf.mpfcnt = 90;
+    t_cmpf.blfsz = 20;
+    ercd = cre_mpf( 1, &t_cmpf );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
+    t_cmpf.mpfcnt = 5;
+    t_cmpf.blfsz = 200;
+    ercd = cre_mpf( 2, &t_cmpf );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpf bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blf( &vp, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blf bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blf( &vp, 2, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blf bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blf( &vp, 1 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blf bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blf( &vp, 2, 10 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blf bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = tget_blf( &vp, 1, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blf bad ercd !E_NOEXS" );
+    ercd = get_blf( &vp, 2 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blf bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete fixed mempools");
+#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+    tests++;
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = del_mpl( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
+    ercd = del_mpl( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "del_mpl bad ercd !E_ID" );
+    ercd = cre_mpl( -6, &t_cmpl );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
+    ercd = cre_mpl( 99, &t_cmpl );
+    CYG_TEST_CHECK( E_ID == ercd, "cre_mpl bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // try a pre-existing object
+    // [first get a valid block from it for the freeing test later]
+    ercd = pget_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_OBJ == ercd, "cre_mpl bad ercd !E_OBJ" );
+    // delete it so we can play
+    ercd = del_mpl( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    // check it is deleted
+    ercd = rel_blk( 3, vp );            // vp did come from this pool
+    CYG_TEST_CHECK( E_NOEXS == ercd, "rel_blk bad ercd !E_NOEXS" );
+    ercd = pget_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
+    ercd = tget_blk( &vp, 3, 100, 10 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "tget_blk bad ercd !E_NOEXS" );
+    ercd = get_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
+    ercd = ref_mpl( &t_rmpl, 3 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "ref_mpl bad ercd !E_NOEXS" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    // now try creating it (badly)
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = cre_mpl( 3, NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "cre_mpl bad ercd !E_PAR" );
+#endif
+    t_cmpl.mplatr = 0xfff;
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_RSATR == ercd, "cre_mpl bad ercd !E_RSATR" );
+#endif // we can test bad param error returns
+    t_cmpl.mplatr = 0;
+    t_cmpl.mplsz = 100000000;
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_NOMEM == ercd, "cre_mpl bad ercd" );
+    // now create it well
+    t_cmpl.mplatr = 0;
+    t_cmpl.mplsz = 1000;
+    ercd = cre_mpl( 3, &t_cmpl );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
+    // and check we can use it
+    ercd = pget_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "pget_blk bad ercd" );
+    ercd = pget_blk( &vp, 3, 100000000 ); // way too large
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    ercd = tget_blk( &vp, 3, 100, 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "tget_blk bad ercd" );
+    ercd = get_blk( &vp, 3, 100 );
+    CYG_TEST_CHECK( E_OK == ercd, "get_blk bad ercd" );
+    ercd = rel_blk( 3, vp );            // vp did come from new pool
+    CYG_TEST_CHECK( E_OK == ercd, "rel_blk bad ercd" );
+    ercd = rel_blk( 3, vp );            // vp already freed
+    CYG_TEST_CHECK( E_PAR == ercd, "rel_blk bad ercd !E_PAR" );
+    ercd = ref_mpl( &t_rmpl, 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_mpl bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blk( &vp, 1, 100 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blk( &vp, 2, 100, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blk( &vp, 1, 200 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blk( &vp, 2, 100, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = get_blk( &vp, 1, 200 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
+    ercd = pget_blk( &vp, 2, 20 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
+
+    // re-create and do it again
+    ercd = cre_mpl( 1, &t_cmpl );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
+    ercd = cre_mpl( 2, &t_cmpl );
+    CYG_TEST_CHECK( E_OK == ercd, "cre_mpl bad ercd" );
+
+    // In order to wait on the pools, we must first consume all they have:
+    while ( E_OK == (ercd = pget_blk( &vp, 1, 20 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "pget_blk bad ercd !E_TMOUT" );
+    while ( E_OK == (ercd = tget_blk( &vp, 2, 400, 1 )) ) /* nothing */;
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tget_blk bad ercd !E_TMOUT" );
+    // now wait while task 2 deletes the wait objects
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = get_blk( &vp, 1, 200 );
+    CYG_TEST_CHECK( E_DLT == ercd, "get_blk bad ercd !E_DLT" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = tget_blk( &vp, 2, 500, 20 );
+    CYG_TEST_CHECK( E_DLT == ercd, "tget_blk bad ercd !E_DLT" );
+    // check they are deleted
+    ercd = tget_blk( &vp, 1, 200, 1 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "get_blk bad ercd !E_NOEXS" );
+    ercd = get_blk( &vp, 2, 20 );
+    CYG_TEST_CHECK( E_NOEXS == ercd, "pget_blk bad ercd !E_NOEXS" );
+
+    CYG_TEST_PASS("create/delete variable mempools");
+#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+    ercd = ter_tsk( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ter_tsk bad ercd" );
+    ercd = dly_tsk( 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    // all done
+    if ( 0 == tests ) {
+        CYG_TEST_NA( "No objects have create/delete enabled" );
+    }
+    else {
+        CYG_TEST_EXIT( "All done" );
+    }
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    int i;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &i );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == i, "tid not 2" );
+    if ( 22222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 22222" );
+
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+    ercd = del_mpf( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpf( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpf( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpf( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpf bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+    ercd = del_mpl( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpl( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpl( 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+    ercd = del_mpl( 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "del_mpl bad ercd" );
+    ercd = slp_tsk();
+    CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+    // we expect task2 to be killed here
+    CYG_TEST_FAIL( "Task 2 ran to completion!" );
+}
+
+void task3( unsigned int arg )
+{
+}
+
+void task4( unsigned int arg )
+{
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcx9.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testcxx.cxx b/packages/compat/uitron/v2_0/tests/testcxx.cxx
new file mode 100644 (file)
index 0000000..b19051c
--- /dev/null
@@ -0,0 +1,817 @@
+//===========================================================================
+//
+//      testcxx.cxx
+//
+//      uITRON "C++" test program
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:        hmt
+// Date:        1998-03-13
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    cyg_uitron_start();
+}
+
+volatile int intercom = 0;
+volatile int intercount = 0;
+INT scratch = 0;
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+
+#ifndef CYGSEM_KERNEL_SCHED_TIMESLICE
+#define TIMESLICEMSG "Assuming no kernel timeslicing"
+#define TSGO()          (1)
+#define TSRELEASE()     CYG_EMPTY_STATEMENT
+#define TSSTOP()        CYG_EMPTY_STATEMENT
+#define TSLOCK()        CYG_EMPTY_STATEMENT
+#define TSUNLOCK()      CYG_EMPTY_STATEMENT
+#define ICWAIT( _i_ )   CYG_EMPTY_STATEMENT
+
+#else
+// Now follow some nasty bodges to control the scheduling when basically it
+// isn't controlled ie. timeslicing is on.  It's bodgy because we're
+// testing normal synchronization methods, so we shouldn't rely on them for
+// comms between threads here.  Instead there's a mixture of communicating
+// via a flag (ts_interlock) which stops the "controlled" thread running
+// away, and waiting for the controlled thread to run enough for us.
+//
+// Tasks 3 and 4 are waited for by the control task: task 3 locks the
+// scheduler so is immediately descheduled when it unlocks it, task 4 does
+// waiting-type operations, so we must give it chance to run by yielding a
+// few times ourselves.  Note the plain constant in ICWAIT() below.
+
+#define TIMESLICEMSG "Assuming kernel timeslicing ENABLED"
+volatile int ts_interlock = 0;
+#define TSGO()          (ts_interlock)
+#define TSRELEASE()     ts_interlock = 1
+#define TSSTOP()        ts_interlock = 0
+
+#define TSLOCK()        CYG_MACRO_START                                 \
+    ER ercd2 = dis_dsp();                                               \
+    CYG_TEST_CHECK( E_OK == ercd2, "dis_dsp (TSLOCK) bad ercd2" );      \
+CYG_MACRO_END
+
+#define TSUNLOCK()      CYG_MACRO_START                                 \
+    ER ercd3 = ena_dsp();                                               \
+    CYG_TEST_CHECK( E_OK == ercd3, "ena_dsp (TSUNLOCK) bad ercd3" );    \
+CYG_MACRO_END
+
+#define ICWAIT( _i_ )   CYG_MACRO_START                                 \
+    int loops;                                                          \
+    for ( loops = 3; (0 < loops) || ((_i_) > intercount); loops-- ) {   \
+        ER ercd4 = rot_rdq( 0 ); /* yield */                            \
+        CYG_TEST_CHECK( E_OK == ercd4, "rot_rdq (ICWAIT) bad ercd4" );  \
+    }                                                                   \
+CYG_MACRO_END
+#endif // CYGSEM_KERNEL_SCHED_TIMESLICE
+
+/*
+#define IC() \
+CYG_MACRO_START \
+  static char *msgs[] = { "ZERO", "ONE", "TWO", "THREE", "FOUR", "LOTS" }; \
+  CYG_TEST_INFO( msgs[ intercount > 5 ? 5 : intercount ] ); \
+CYG_MACRO_END
+*/
+
+// #define CYG_TEST_UITRON_TEST1_LOOPING 1
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    T_RTSK ref_tskd;
+
+#ifdef CYG_TEST_UITRON_TEST1_LOOPING
+    while ( 1 ) {
+#endif // CYG_TEST_UITRON_TEST1_LOOPING
+
+    CYG_TEST_INFO( "Task 1 running" );
+    CYG_TEST_INFO( TIMESLICEMSG );
+
+    intercom = 0;
+    intercount = 0;
+
+    CYG_TEST_INFO( "Testing get_tid and ref_tsk" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = get_tid( NULL );
+    CYG_TEST_CHECK( E_PAR == ercd, "get_tid bad ercd !E_PAR" );
+#endif
+    ercd = ref_tsk( &ref_tskd, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
+    ercd = ref_tsk( &ref_tskd, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "ref_tsk bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = ref_tsk( NULL, 1 );
+    CYG_TEST_CHECK( E_PAR == ercd, "ref_tsk bad ercd !E_PAR" );
+#endif
+#endif // we can test bad param error returns
+    ercd = ref_tsk( &ref_tskd, 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 1" );
+    ercd = ref_tsk( &ref_tskd, 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RUN == ref_tskd.tskstat, "Bad task status 0" );
+    ercd = ref_tsk( &ref_tskd, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
+    CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
+
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
+
+    CYG_TEST_PASS( "get_tid, ref_tsk" );
+
+    CYG_TEST_INFO( "Testing prio change and start task" );
+    ercd = sta_tsk( 2, 99 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+
+    // drop pri of task 2
+    ercd = chg_pri( 2, 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ref_tsk( &ref_tskd, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( TTS_RDY == ref_tskd.tskstat, "Bad task status 2" );
+    CYG_TEST_CHECK( 4 == ref_tskd.tskpri, "Bad task prio 2" );
+
+    // drop our pri below task 2
+    ercd = chg_pri( 0, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+
+    ercd = ref_tsk( &ref_tskd, 1 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 1" );
+    ercd = ref_tsk( &ref_tskd, 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    CYG_TEST_CHECK( 5 == ref_tskd.tskpri, "Bad task prio 0" );
+    ercd = ref_tsk( &ref_tskd, 2 );
+    CYG_TEST_CHECK( E_OK == ercd, "ref_tsk bad ercd" );
+    // it will have run to completion and regained its original prio
+    CYG_TEST_CHECK( 2 == ref_tskd.tskpri, "Bad task prio 2" );
+    CYG_TEST_CHECK( TTS_DMT == ref_tskd.tskstat, "Bad task status 2" );
+
+    // retest these now that the task has executed once
+    ercd = rsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = frsm_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk DMT bad ercd !E_OBJ" );
+    ercd = rel_wai( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "rel_wai DMT bad ercd !E_OBJ" );
+    ercd = sus_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "sus_tsk DMT bad ercd !E_OBJ" );
+    ercd = wup_tsk( 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk DMT bad ercd !E_OBJ" );
+    ercd = can_wup( &scratch, 2 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "can_wup DMT bad ercd !E_OBJ" );
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = chg_pri( -6, 9 );
+    CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
+    ercd = chg_pri( 99, 9 );
+    CYG_TEST_CHECK( E_ID == ercd, "chg_pri bad ercd !E_ID" );
+    ercd = sta_tsk( -6, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
+    ercd = sta_tsk( 99, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sta_tsk bad ercd !E_ID" );
+#endif // we can test bad param error returns
+
+    CYG_TEST_PASS( "sta_tsk, chg_pri" );
+
+    CYG_TEST_INFO( "Testing delay and dispatch disabling" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_CTX == ercd, "dly_tsk bad ercd !E_CTX" );
+#endif // we can test bad param error returns
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = dly_tsk( 10 );
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    CYG_TEST_PASS( "dly_tsk, ena_dsp, dis_dsp" );
+    
+    CYG_TEST_INFO( "Testing ready queue manipulation" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ercd = rot_rdq( 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ercd = rot_rdq( 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = rot_rdq( -6 );
+    CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
+    ercd = rot_rdq( 99 );
+    CYG_TEST_CHECK( E_PAR == ercd, "rot_rdq bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    
+    CYG_TEST_PASS( "rot_rdq" );
+
+    CYG_TEST_INFO( "Testing suspend/resume" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = sus_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
+    ercd = sus_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "sus_tsk bad ercd !E_ID" );
+    ercd = rsm_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
+    ercd = rsm_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "rsm_tsk bad ercd !E_ID" );
+    ercd = frsm_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
+    ercd = frsm_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "frsm_tsk bad ercd !E_ID" );
+#endif // we can test bad param error returns
+    // drop task 3 pri to same as us
+    CYG_TEST_CHECK( 0 == intercount, "intercount != 0" );
+
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 3, 66 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 3, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 1 );
+    CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
+    ercd = sus_tsk( 3 );
+    TSRELEASE();
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    intercom = 0;                       // bad data to T3
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = rsm_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 2 );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+
+    CYG_TEST_INFO( "Command task 3 inner loop stop" );
+    intercom = 2 + 4;
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    
+    ercd = sus_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    intercom = 0;                       // bad data to T3
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ercd = sus_tsk( 3 );                // suspend AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    ercd = sus_tsk( 3 );                //     AND AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    ercd = rsm_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = rsm_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = rsm_tsk( 3 );                // expect restart this time
+    CYG_TEST_CHECK( E_OK == ercd, "rsm_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 3 );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+
+    CYG_TEST_INFO( "Command task 3 inner loop stop 2" );
+    intercom = 2 + 4;
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    
+    ercd = sus_tsk( 3 );
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    intercom = 0;                       // bad data to T3
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    ercd = sus_tsk( 3 );                // suspend AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    ercd = sus_tsk( 3 );                //     AND AGAIN
+    CYG_TEST_CHECK( E_OK == ercd, "sus_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    intercom = 3;                       // tell T3 to loop
+    TSRELEASE();
+    ercd = frsm_tsk( 3 );               // expect restart this time
+    CYG_TEST_CHECK( E_OK == ercd, "frsm_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 4 );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+
+    TSRELEASE();
+    ercd = rsm_tsk( 3 );               // try it again
+    CYG_TEST_CHECK( E_OBJ == ercd, "rsm_tsk bad ercd !E_OBJ" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 5 );
+    CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
+
+    TSRELEASE();
+    ercd = frsm_tsk( 3 );               // try it again
+    CYG_TEST_CHECK( E_OBJ == ercd, "frsm_tsk bad ercd !E_OBJ" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 6 );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+
+    CYG_TEST_INFO( "Command task 3 all loops stop" );
+    intercom = 4 + 8;
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+    
+    intercom = intercount = 0;
+
+    CYG_TEST_PASS( "sus_tsk, rsm_tsk, frsm_tsk" );
+
+    CYG_TEST_INFO( "Testing sleep/wakeup stuff" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = wup_tsk( -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
+    ercd = wup_tsk( 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
+    ercd = can_wup( &scratch, -6 );
+    CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
+    ercd = can_wup( &scratch, 99 );
+    CYG_TEST_CHECK( E_ID == ercd, "can_wup bad ercd !E_ID" );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    ercd = can_wup( NULL, 2 );
+    CYG_TEST_CHECK( E_PAR == ercd, "can_wup bad ercd !E_PAR" );
+#endif
+    
+    ercd = wup_tsk( 0 );                // not ourself
+    CYG_TEST_CHECK( E_ID == ercd, "wup_tsk bad ercd !E_ID" );
+    ercd = wup_tsk( 1 );                // ourself
+    CYG_TEST_CHECK( E_OBJ == ercd, "wup_tsk bad ercd !E_OBJ" );
+#endif // we can test bad param error returns
+
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = tslp_tsk( -6 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    ercd = tslp_tsk( TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+    ercd = tslp_tsk( 5 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = tslp_tsk( TMO_FEVR );
+    CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
+     ercd = tslp_tsk( TMO_POL );
+    CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
+    ercd = tslp_tsk( 5 );
+    CYG_TEST_CHECK( E_CTX == ercd, "tslp_tsk bad ercd !E_CTX" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+    ercd = tslp_tsk( -6 );
+    CYG_TEST_CHECK( E_PAR == ercd, "tslp_tsk bad ercd !E_PAR" );
+#endif // we can test bad param error returns
+    ercd = tslp_tsk( TMO_POL );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+    ercd = tslp_tsk( 5 );
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+
+    // drop task 4 pri to same as us
+    intercount = 0;
+    intercom = 1;                       // test plain slp_tsk
+    TSRELEASE();
+    ercd = chg_pri( 4, 5 );
+    CYG_TEST_CHECK( E_OBJ == ercd, "chg_pri bad ercd" );
+
+    ercd = dis_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "dis_dsp bad ercd" );
+    ercd = sta_tsk( 4, 77 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk bad ercd" );
+    ercd = chg_pri( 4, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri bad ercd" );
+    ercd = ena_dsp();
+    CYG_TEST_CHECK( E_OK == ercd, "ena_dsp bad ercd" );
+
+    ercd = wup_tsk( 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 1 );
+    CYG_TEST_CHECK( 1 == intercount, "intercount != 1" );
+    intercom = 2;                       // test tslp_tsk
+    TSRELEASE();
+    ercd = wup_tsk( 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 2 );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    intercom = 3;                       // test tslp_tsk
+    TSRELEASE();
+    ercd = rot_rdq( 0 );
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 2 == intercount, "intercount != 2" );
+    intercom = 1;                       // test slp_tsk next...
+    ercd = dly_tsk( 20 );               // without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    ICWAIT( 3 );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+
+    intercom = 1;                       // ...test slp_tsk
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // without a wup (yet)
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    TSRELEASE();
+    ercd = tslp_tsk( 20 );              // yield again
+    CYG_TEST_CHECK( E_TMOUT == ercd, "tslp_tsk bad ercd !E_TMOUT" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // and again
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 3 == intercount, "intercount != 3" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );                // and yield
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 4 );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+
+    intercom = 1;                       // test slp_tsk
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // without a wup (yet)
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+
+    // this wup will restart it when we yield:
+    TSLOCK();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    // these will count up:
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    scratch = -1;
+    ercd = can_wup( &scratch, 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "Cancelled wups not 2" );
+    CYG_TEST_CHECK( 4 == intercount, "intercount != 4" );
+    TSUNLOCK();
+
+    intercom = 4;                       // do nothing
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // and yield
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 5 );
+    CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // let it do nothing
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = dly_tsk( 20 );               // lots of wups but no sleep
+    CYG_TEST_CHECK( E_OK == ercd, "dly_tsk bad ercd" );
+    CYG_TEST_CHECK( 5 == intercount, "intercount != 5" );
+    scratch = -1;
+    ercd = can_wup( &scratch, 4 );
+    CYG_TEST_CHECK( E_OK == ercd, "can_wup bad ercd" );
+    CYG_TEST_CHECK( 3 == scratch, "Cancelled wups not 3" );
+    // now check that they are cancelled by doing a wait again
+    intercom = 1;                       // test slp_tsk
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // still without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // still without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    intercom = 4;                       // do nothing next
+    TSRELEASE();
+    ICWAIT( 6 );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+    ercd = rot_rdq( 0 );                // still without a wup
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 6 == intercount, "intercount != 6" );
+    TSRELEASE();
+    ercd = wup_tsk( 4 );                // now issue a wup
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    ercd = rot_rdq( 0 );                // it will run now
+    CYG_TEST_CHECK( E_OK == ercd, "wup_tsk bad ercd" );
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // it will run now
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 7 );
+    CYG_TEST_CHECK( 7 == intercount, "intercount != 7" );
+
+    TSRELEASE();
+    intercom = 99;                      // exit, all done
+    ercd = rot_rdq( 0 );                // let it run
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    ICWAIT( 8 );
+    CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
+
+    TSRELEASE();
+    ercd = rot_rdq( 0 );                // let it run
+    CYG_TEST_CHECK( E_OK == ercd, "rot_rdq bad ercd" );
+    CYG_TEST_CHECK( 8 == intercount, "intercount != 8" );
+   
+    CYG_TEST_PASS( "wup_tsk, can_wup, slp_tsk, tslp_tsk" );
+
+#ifdef CYG_TEST_UITRON_TEST1_LOOPING
+    chg_pri( 1, 1 );
+    rot_rdq( 0 );
+    ter_tsk( 2 );
+    rot_rdq( 0 );
+    ter_tsk( 3 );
+    rot_rdq( 0 );
+    ter_tsk( 4 );
+    rot_rdq( 0 );
+    }
+#endif // CYG_TEST_UITRON_TEST1_LOOPING
+
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    CYG_TEST_PASS( "Task 2 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
+    if ( 99 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 99" );
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 2 failed to exit" );
+}
+
+void task3( unsigned int arg )
+{
+    ER ercd;
+    TSLOCK();
+    CYG_TEST_PASS("Task3 running");
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
+    if ( 66 != arg )
+        CYG_TEST_FAIL( "Task 3 arg not 66" );
+
+    while ( 2 & intercom ) {
+        while ( 1 & intercom ) {
+            intercount++;
+            TSSTOP();
+            do {
+                TSUNLOCK();
+                ercd = rot_rdq( 0 );        // yield()
+                TSLOCK();
+                CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 1 (task3) bad ercd" );
+            } while ( !TSGO() );
+        }
+        CYG_TEST_CHECK( 4 & intercom, "should not have got here yet 1" );
+        TSSTOP();
+        do {
+            TSUNLOCK();
+            ercd = rot_rdq( 0 );            // yield()
+            TSLOCK();
+            CYG_TEST_CHECK( E_OK == ercd, "rot_rdq 2 (task3) bad ercd" );
+        } while ( !TSGO() );
+    }
+    CYG_TEST_CHECK( 8 & intercom, "should not have got here yet 2" );
+    
+    TSUNLOCK();
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 3 failed to exit" );
+}
+
+void task4( unsigned int arg )
+{
+    ER ercd;
+    CYG_TEST_PASS("Task4 running");
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
+    if ( 77 != arg )
+        CYG_TEST_FAIL( "Task 4 arg not 77" );
+    while ( 1 ) {
+        switch ( intercom ) {
+        case 1:
+            ercd = slp_tsk();
+            CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
+            break;
+        case 2:
+            ercd = tslp_tsk( 10 );
+            CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (task4) bad ercd" );
+            break;
+        case 3:
+            ercd = tslp_tsk( 10 );
+            CYG_TEST_CHECK( E_TMOUT == ercd,
+                            "slp_tsk (task4) bad ercd !E_TMOUT" );
+            break;
+        case 4:
+            // busily do nothing
+            while ( 4 == intercom ) {
+                ercd = rot_rdq( 0 );
+                CYG_TEST_CHECK( E_OK == ercd,
+                                "rot_rdq (task4 idle) bad ercd" );
+            }
+            break;
+        case 99:
+            goto out;
+        default:
+            CYG_TEST_FAIL( "Task 4 bad intercom" );
+            goto out;
+        }
+        intercount++;
+        TSSTOP();
+        do {
+            ercd = rot_rdq( 0 );            // yield()
+            CYG_TEST_CHECK( E_OK == ercd, "rot_rdq (task4) bad ercd" );
+        } while ( !TSGO() );
+    }
+out:
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 4 failed to exit" );
+}
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testcxx.cxx
diff --git a/packages/compat/uitron/v2_0/tests/testintr.cxx b/packages/compat/uitron/v2_0/tests/testintr.cxx
new file mode 100644 (file)
index 0000000..7eb509b
--- /dev/null
@@ -0,0 +1,892 @@
+//===========================================================================
+//
+//      testintr.c
+//
+//      uITRON "C" test program for ixxx_yyy interrupt safe operators
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   hmt
+// Contributors:hmt
+// Date:        1998-08-20
+// Purpose:     uITRON API testing
+// Description: 
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/uitron.h>             // uITRON setup CYGNUM_UITRON_SEMAS
+                                        // CYGPKG_UITRON et al
+#include <cyg/infra/testcase.h>         // testing infrastructure
+
+#ifdef CYGPKG_UITRON                    // we DO want the uITRON package
+
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE      // we DO want prioritized threads
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER      // we DO want timout-able calls
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK     // we DO want the realtime clock
+
+// we're OK if it's C++ or neither of those two is defined:
+#if defined( __cplusplus ) || \
+    (!defined( CYGIMP_UITRON_INLINE_FUNCS ) && \
+     !defined( CYGIMP_UITRON_CPP_OUTLINE_FUNCS) )
+
+// =================== TEST CONFIGURATION ===================
+#if \
+    /* test configuration for enough tasks */                      \
+    (CYGNUM_UITRON_TASKS >= 4)                                  && \
+    (CYGNUM_UITRON_TASKS < 90)                                  && \
+    (CYGNUM_UITRON_START_TASKS == 1)                            && \
+    ( !defined(CYGPKG_UITRON_TASKS_CREATE_DELETE) ||               \
+      CYGNUM_UITRON_TASKS_INITIALLY >= 4             )          && \
+                                                                   \
+    /* the end of the large #if statement */                       \
+    1 
+
+// ============================ END ============================
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_intr.h>
+
+#include <cyg/infra/diag.h>
+
+#include <cyg/compat/uitron/uit_func.h> // uITRON
+#include <cyg/compat/uitron/uit_ifnc.h> // uITRON interrupt funcs
+
+void set_interrupt_number( void );
+
+unsigned int clock_interrupt = 0;
+
+externC void
+cyg_package_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_INFO( "Calling cyg_uitron_start()" );
+    set_interrupt_number();
+    cyg_uitron_start();
+}
+
+extern "C" {
+    void task1( unsigned int arg );
+    void task2( unsigned int arg );
+    void task3( unsigned int arg );
+    void task4( unsigned int arg );
+}
+
+volatile int intercom = 0;
+INT scratch = 0;
+
+// Plan: replace (by direct intervention) the ISR and DSR of the regular
+// timer interrupt; be sure to ack the clock intr using the appropriate hal
+// macros.
+// 
+// The new ISR(s) will simply use the interrupt-safe signalling functions
+// to control a 2nd task.  Main task will check on the state thereof.
+//
+// We must test the ixxx_yyy() funcs with the scheduler already locked
+// also, by direct sched calls on the KAPI.  This must verify that the
+// signal only happens when the scheduler unlocks.
+// 
+// The 4 producer ops are:
+//     iwup_tsk ( ID tskid );
+//     isig_sem ( ID semid );
+//     iset_flg ( ID flgid, UINT setptn );
+//     isnd_msg ( ID mbxid, T_MSG *pk_msg );
+//
+// and return macros are:
+//     ret_wup( ID tskid );
+//     ret_int();
+//
+// These ISRs perform the producer ops on all available objects in turn.
+// Tasks 2-4
+// Semas 1-4
+// Flags 1-4 with marching bit data; they'll all be set to 0x1ff eventually
+// Mboxes 1-4 with an arbitrary pointer
+
+enum {
+    NOTHING = 0,
+    SLP,
+    SEM,
+    FLG,
+    MBX,
+    EXIT
+};
+
+#define ACK_CLOCK() CYG_MACRO_START                             \
+    HAL_CLOCK_RESET( CYGNUM_HAL_INTERRUPT_RTC,                  \
+                     CYGNUM_KERNEL_COUNTERS_RTC_PERIOD );       \
+    HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_RTC );      \
+CYG_MACRO_END
+
+#define CHECK_TID() CYG_MACRO_START                     \
+    int my_tid;                                         \
+    ER ercd;                                            \
+    ercd = get_tid( &my_tid );                          \
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" ); \
+    CYG_TEST_CHECK( 0 == my_tid, "tid not 0 in ISR" );  \
+CYG_MACRO_END
+
+
+unsigned int
+isr_wup_tsk( unsigned int vector, unsigned int data )
+{
+    // Hit TASKS in range 2..4
+    static int wtid = 2;
+    ACK_CLOCK();
+    CHECK_TID();
+    iwup_tsk( wtid );
+    wtid++;
+    if ( 5 == wtid ) wtid = 2;
+    ret_int();
+}
+
+unsigned int
+isr_ret_wup( unsigned int vector, unsigned int data )
+{
+    // Hit TASKS in range 2..4
+    static int rwid = 2;
+    ACK_CLOCK();
+    CHECK_TID();
+    rwid++;
+    if ( 6 == rwid ) rwid = 3;
+    ret_wup( rwid - 1 );
+}
+
+unsigned int
+isr_sig_sem( unsigned int vector, unsigned int data )
+{
+    // Hit SEMAS in range 1..3
+    static int ssid = 1;
+    ACK_CLOCK();
+    CHECK_TID();
+    isig_sem( ssid );
+    ssid++;
+    if ( ssid == 4 ) ssid = 1;
+    ret_int();
+}
+
+unsigned int
+isr_set_flg( unsigned int vector, unsigned int data )
+{
+    // Hit FLAGS in range 1..4
+    static int sfid = 1;
+    static int sfdata = 0xff;
+    ACK_CLOCK();
+    CHECK_TID();
+    iset_flg( sfid, sfdata );
+    sfid++;
+    if ( sfid == 5 ) sfid = 1;
+//    sfdata <<= 1;
+//    if ( sfdata == 0x20 ) sfdata = 1; // so that eventually all 0x1f set
+    ret_int();
+}
+
+unsigned int
+isr_snd_msg( unsigned int vector, unsigned int data )
+{
+    // Hit MBOXES in range 1..4
+    static int smid = 1;
+    ACK_CLOCK();
+    CHECK_TID();
+    isnd_msg( smid, (T_MSG *)&smid );
+    smid++;
+    if ( smid == 5 ) smid = 1;
+    ret_int();
+}
+
+
+void attach_isr( unsigned int (*isr)(unsigned int, unsigned int) );
+void detach_isr( unsigned int (*isr)(unsigned int, unsigned int) );
+
+void lock_sched( void );
+void unlock_sched( void );
+
+volatile int count = -1;
+
+/*
+#define BIGDELAY  50000000
+#define SMALLDELAY (BIGDELAY/SMALLLOOPS)
+#define SMALLLOOPS 3
+
+#define xxxLONGDELAY()                                     \
+do {                                                    \
+    int i;                                              \
+    for ( i = 0; i < BIGDELAY; i++ )                    \
+        if ( wakeups[ 4 ] > prewups[ 4 ] + 99 ) break;  \
+} while ( 0 )
+   
+#define xxxDELAYLOCKSCHED()                                        \
+do {                                                            \
+    int i,j;                                                    \
+    for ( j = 0; j < SMALLLOOPS; j++ ) {                        \
+        lock_sched();                                           \
+        for ( i = 0; i < SMALLDELAY; i++ )                      \
+            if ( wakeups[ 4 ] > prewups[ 4 ] + 99 ) break;      \
+        unlock_sched();                                         \
+        if ( wakeups[ 4 ] > prewups[ 4 ] + 99 ) break;          \
+    }                                                           \
+} while ( 0 )
+*/
+
+#define SMALLDELAYHW  (5000000)
+#define EVENTSHW      (     20)
+#define SMALLDELAYSIM ( 100000)
+#define EVENTSSIM     (      4)
+
+#define SMALLDELAY (smalldelay)
+#define EVENTS     (events)
+
+static int smalldelay = SMALLDELAYHW;
+static int events     = EVENTSHW;
+
+#define LONGDELAY() do {                                        \
+    count = 0;                                                  \
+    do count++; while ( wakeups[ 4 ] < prewups[ 4 ] + EVENTS ); \
+} while ( 0 )
+
+
+#define DELAYLOCKSCHED()                                              \
+do {                                                                  \
+    count = 0;                                                        \
+    int i;                                                            \
+    do {                                                              \
+        lock_sched();                                                 \
+        for ( i = 0; i < SMALLDELAY; i++ ) {                          \
+            count++;                                                  \
+            if ( wakeups[ 4 ] >= prewups[ 4 ] + EVENTS )              \
+                break;                                                \
+        }                                                             \
+        unlock_sched();                                               \
+        CYG_TEST_INFO("  [Still iterating, please wait....]  ");      \
+    } while ( wakeups[ 4 ] < prewups[ 4 ] + EVENTS );                 \
+} while ( 0 )
+
+#define DELAY()                                 \
+if ( 1 & loops )                                \
+    DELAYLOCKSCHED();                           \
+else                                            \
+    LONGDELAY();
+    
+
+volatile int wakeups[ 5 ] = { 0,0,0,0,0 };
+volatile int prewups[ 5 ] = { 0,0,0,0,0 };
+
+
+void task1( unsigned int arg )
+{
+    ER ercd;
+    int loops;
+
+    CYG_TEST_INFO( "Task 1 running" );
+
+    if ( cyg_test_is_simulator ) {
+        // take less time
+        events     = EVENTSSIM;
+    }
+
+
+    // First test that dis_int() and ena_int() work for the clock interrupt
+#ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+    ercd = ena_int( 123456789 ); // Hope this is large enough to error
+    CYG_TEST_CHECK( E_PAR == ercd, "ena_int bad ercd !E_PAR" );
+    ercd = dis_int( 123456789 );
+    CYG_TEST_CHECK( E_PAR == ercd, "dis_int bad ercd !E_PAR" );
+#endif
+
+    // This may take too long on a sim...
+    // On the synthetic target this test cannot run reliably - the
+    // loop counting assumes exclusive access to the processor.
+#ifndef CYGPKG_HAL_SYNTH    
+    if ( ! cyg_test_is_simulator ) {
+        SYSTIME t1, t2;
+
+        CYG_TEST_INFO( "Testing masking of clock interrupt" );
+
+        ercd = get_tim( &t1 );
+        CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+
+        // Wait for a tick. This loop acts as a synchronizer for the loop
+        // below, ensuring that it starts just after a tick.
+        for ( loops = 0; loops < 10000000; loops++ ) {
+            ercd = get_tim( &t2 );
+            CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+            if ( t2 != t1 )
+                break;
+        }
+        // Wait for next tick. Reset loops counter so we get the
+        // approximate loop count of one clock tick.
+        for ( loops = 0; loops < 10000000; loops++ ) {
+            ercd = get_tim( &t1 );
+            CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+            if ( t2 != t1 )
+                break;
+        }
+
+        // save how many loops could be executed in one tick. Multiply
+        // with 3 : we run loops in pairs below and add the time of
+        // one extra to avoid small variations to trigger failures.
+        intercom = loops * 3;
+
+        ercd = ena_int( clock_interrupt ); // was initialized already
+        CYG_TEST_CHECK( E_OK == ercd, "ena_int bad ercd" );
+
+        ercd = get_tim( &t1 );
+        CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+
+        // Wait for a tick
+        for ( loops = intercom; loops > 0; loops-- ) {
+            ercd = get_tim( &t2 );
+            CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+            if ( t2 != t1 )
+                break;
+        }
+        CYG_TEST_CHECK( 0 < loops, "No first tick" );
+        // and a second one
+        for (                 ; loops > 0; loops-- ) {
+            ercd = get_tim( &t1 );
+            CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+            if ( t2 != t1 )
+                break;
+        }
+        CYG_TEST_CHECK( 0 < loops, "No second tick" );
+        
+        // The PowerPC cannot disable the timer interrupt (separately).
+#ifndef CYGPKG_HAL_POWERPC
+        ercd = dis_int( clock_interrupt ); // was initialized already
+        CYG_TEST_CHECK( E_OK == ercd, "dis_int bad ercd" );
+
+        ercd = get_tim( &t1 );
+        CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+
+        // Wait for a tick (should not happen)
+        for ( loops = intercom; loops > 0; loops-- ) {
+            ercd = get_tim( &t2 );
+            CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+            if ( t2 != t1 )
+                break;
+        }
+        CYG_TEST_CHECK( 0 == loops, "A tick occured - should be masked" );
+        CYG_TEST_CHECK( t1 == t2, "Times are different" );
+
+        // Now enable it again and ensure all is well:
+        ercd = ena_int( clock_interrupt );
+        CYG_TEST_CHECK( E_OK == ercd, "ena_int bad ercd" );
+#endif
+        
+        ercd = get_tim( &t1 );
+        CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+
+        // Wait for a tick
+        for ( loops = intercom; loops > 0; loops-- ) {
+            ercd = get_tim( &t2 );
+            CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+            if ( t2 != t1 )
+                break;
+        }
+        CYG_TEST_CHECK( 0 < loops, "No first tick" );
+        // and a second one
+        for (                 ; loops > 0; loops-- ) {
+            ercd = get_tim( &t1 );
+            CYG_TEST_CHECK( E_OK == ercd, "get_tim bad ercd" );
+            if ( t2 != t1 )
+                break;
+        }
+        CYG_TEST_CHECK( 0 < loops, "No second tick" );
+
+        CYG_TEST_PASS( "dis_int(), ena_int() OK" );
+    }
+#endif
+    
+    intercom = 0;
+
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 1 == scratch, "tid not 1" );
+
+    // start all other tasks (our prio is 1 by default)
+    ercd = sta_tsk( 2, 222 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk 2 bad ercd" );
+    ercd = sta_tsk( 3, 333 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk 3 bad ercd" );
+    ercd = sta_tsk( 4, 444 );
+    CYG_TEST_CHECK( E_OK == ercd, "sta_tsk 4 bad ercd" );
+    // drop pri of other tasks all to 5
+    ercd = chg_pri( 2, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri 2 bad ercd" );
+    ercd = chg_pri( 3, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri 3 bad ercd" );
+    ercd = chg_pri( 4, 5 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri 4 bad ercd" );
+
+    // Test sleep/wakeup
+    intercom = SLP;
+    // Drop our prio to lower; they will run in turn until asleep
+    ercd = chg_pri( 1, 6 );
+    CYG_TEST_CHECK( E_OK == ercd, "chg_pri 1 (self) bad ercd" );
+    
+    loops = 4;
+    do {
+
+        if ( 1 & loops )
+            CYG_TEST_INFO( " (toggling scheduler lock) " );
+        else
+            CYG_TEST_INFO( " (unlocked scheduler) " );
+
+
+        CYG_TEST_CHECK(          0 == wakeups[0], "init: Wakeups[0] hit" );
+        CYG_TEST_CHECK(          0 == wakeups[1], "init: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] == wakeups[2], "init: Wakeups[2] hit" );
+        CYG_TEST_CHECK( prewups[3] == wakeups[3], "init: Wakeups[3] hit" );
+        CYG_TEST_CHECK( prewups[4] == wakeups[4], "init: Wakeups[4] hit" );
+
+        // -------- TIMERS AND TIMESLICING DISABLED ---------
+        // install an isr that will wake them all up in turn
+        attach_isr( isr_wup_tsk );
+        DELAY();
+        detach_isr( isr_wup_tsk );
+        // -------- timers and timeslicing ENABLED ---------
+        
+        CYG_TEST_CHECK(         0 == wakeups[0], "iwup_tsk: Wakeups[0] hit" );
+        CYG_TEST_CHECK(         0 == wakeups[1], "iwup_tsk: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] < wakeups[2], "iwup_tsk: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] < wakeups[3], "iwup_tsk: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] < wakeups[4], "iwup_tsk: Wakeups[4] not hit" );
+        diag_printf( "INFO:<(fg loops %10d) thread wakeups : %2d %2d %2d >\n", count,
+                     wakeups[2] - prewups[2],
+                     wakeups[3] - prewups[3],
+                     wakeups[4] - prewups[4] );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+        
+        // -------- TIMERS AND TIMESLICING DISABLED ---------
+        // install an isr that will wake them all up in turn
+        attach_isr( isr_ret_wup );
+        DELAY();
+        detach_isr( isr_ret_wup );
+        // -------- timers and timeslicing ENABLED ---------
+        
+        CYG_TEST_CHECK(         0 == wakeups[0], "ret_wup: Wakeups[0] hit" );
+        CYG_TEST_CHECK(         0 == wakeups[1], "ret_wup: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] < wakeups[2], "ret_wup: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] < wakeups[3], "ret_wup: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] < wakeups[4], "ret_wup: Wakeups[4] not hit" );
+        diag_printf( "INFO:<(fg loops %10d) thread ret_wups: %2d %2d %2d >\n", count,
+                     wakeups[2] - prewups[2],
+                     wakeups[3] - prewups[3],
+                     wakeups[4] - prewups[4] );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+        
+        // move them on to waiting for a semaphore
+        intercom = SEM;
+        ercd = wup_tsk( 2 );
+        CYG_TEST_CHECK( E_OK == ercd, "wup_tsk(2) bad ercd" );
+        ercd = wup_tsk( 3 );
+        CYG_TEST_CHECK( E_OK == ercd, "wup_tsk(3) bad ercd" );
+        ercd = wup_tsk( 4 );
+        CYG_TEST_CHECK( E_OK == ercd, "wup_tsk(4) bad ercd" );
+        
+        CYG_TEST_CHECK(              0 == wakeups[0], "wup_tsk: Wakeups[0] hit" );
+        CYG_TEST_CHECK(              0 == wakeups[1], "wup_tsk: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "wup_tsk: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "wup_tsk: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "wup_tsk: Wakeups[4] not hit" );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+        
+        // -------- TIMERS AND TIMESLICING DISABLED ---------
+        // install an isr that will wake them all up in turn
+        attach_isr( isr_sig_sem );
+        DELAY();
+        detach_isr( isr_sig_sem );
+        // -------- timers and timeslicing ENABLED ---------
+        
+        CYG_TEST_CHECK(         0 == wakeups[0], "isig_sem: Wakeups[0] hit" );
+        CYG_TEST_CHECK(         0 == wakeups[1], "isig_sem: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] < wakeups[2], "isig_sem: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] < wakeups[3], "isig_sem: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] < wakeups[4], "isig_sem: Wakeups[4] not hit" );
+        diag_printf( "INFO:<(fg loops %10d) semaphore waits: %2d %2d %2d >\n", count,
+                     wakeups[2] - prewups[2],
+                     wakeups[3] - prewups[3],
+                     wakeups[4] - prewups[4] );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+
+        // move them on to waiting for a flag
+        intercom = FLG;
+        ercd = sig_sem( 1 );
+        CYG_TEST_CHECK( E_OK == ercd, "sig_sem(1) bad ercd" );
+        ercd = sig_sem( 2 );
+        CYG_TEST_CHECK( E_OK == ercd, "sig_sem(2) bad ercd" );
+        ercd = sig_sem( 3 );
+        CYG_TEST_CHECK( E_OK == ercd, "sig_sem(3) bad ercd" );
+
+        CYG_TEST_CHECK(              0 == wakeups[0], "sig_sem: Wakeups[0] hit" );
+        CYG_TEST_CHECK(              0 == wakeups[1], "sig_sem: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "sig_sem: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "sig_sem: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "sig_sem: Wakeups[4] not hit" );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+        
+        // -------- TIMERS AND TIMESLICING DISABLED ---------
+        // install an isr that will wake them all up in turn
+        attach_isr( isr_set_flg );
+        DELAY();
+        detach_isr( isr_set_flg );
+        // -------- timers and timeslicing ENABLED ---------
+        
+        CYG_TEST_CHECK(         0 == wakeups[0], "iset_flg: Wakeups[0] hit" );
+        CYG_TEST_CHECK(         0 == wakeups[1], "iset_flg: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] < wakeups[2], "iset_flg: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] < wakeups[3], "iset_flg: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] < wakeups[4], "iset_flg: Wakeups[4] not hit" );
+        diag_printf( "INFO:<(fg loops %10d) flag waits/sets: %2d %2d %2d >\n", count,
+                     wakeups[2] - prewups[2],
+                     wakeups[3] - prewups[3],
+                     wakeups[4] - prewups[4] );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+
+        // move them on to waiting for a message box
+        intercom = MBX;
+        ercd = set_flg( 2, 0xfff );
+        CYG_TEST_CHECK( E_OK == ercd, "set_flg(2) bad ercd" );
+        ercd = set_flg( 3, 0xfff );
+        CYG_TEST_CHECK( E_OK == ercd, "set_flg(3) bad ercd" );
+        ercd = set_flg( 4, 0xfff );
+        CYG_TEST_CHECK( E_OK == ercd, "set_flg(4) bad ercd" );
+        
+        CYG_TEST_CHECK(              0 == wakeups[0], "set_flg: Wakeups[0] hit" );
+        CYG_TEST_CHECK(              0 == wakeups[1], "set_flg: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "set_flg: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "set_flg: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "set_flg: Wakeups[4] not hit" );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+        
+        // -------- TIMERS AND TIMESLICING DISABLED ---------
+        // install an isr that will wake them all up in turn
+        attach_isr( isr_snd_msg );
+        DELAY();
+        detach_isr( isr_snd_msg );
+        // -------- timers and timeslicing ENABLED ---------
+
+        CYG_TEST_CHECK(         0 == wakeups[0], "isnd_msg: Wakeups[0] hit" );
+        CYG_TEST_CHECK(         0 == wakeups[1], "isnd_msg: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] < wakeups[2], "isnd_msg: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] < wakeups[3], "isnd_msg: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] < wakeups[4], "isnd_msg: Wakeups[4] not hit" );
+        diag_printf( "INFO:<(fg loops %10d) message rec'pts: %2d %2d %2d >\n", count,
+                     wakeups[2] - prewups[2],
+                     wakeups[3] - prewups[3],
+                     wakeups[4] - prewups[4] );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+
+        // move them on to exiting, all done
+        if ( 1 == loops )
+            // then we are about to exit
+            intercom = EXIT;
+        else
+            intercom = SLP;
+        ercd = snd_msg( 2, (T_MSG *)&intercom );
+        CYG_TEST_CHECK( E_OK == ercd, "snd_msg(2) bad ercd" );
+        ercd = snd_msg( 3, (T_MSG *)&intercom );
+        CYG_TEST_CHECK( E_OK == ercd, "snd_msg(3) bad ercd" );
+        ercd = snd_msg( 4, (T_MSG *)&intercom );
+        CYG_TEST_CHECK( E_OK == ercd, "snd_msg(4) bad ercd" );
+
+        CYG_TEST_CHECK(              0 == wakeups[0], "snd_msg: Wakeups[0] hit" );
+        CYG_TEST_CHECK(              0 == wakeups[1], "snd_msg: Wakeups[1] hit" );
+        CYG_TEST_CHECK( prewups[2] + 1 == wakeups[2], "snd_msg: Wakeups[2] not hit" );
+        CYG_TEST_CHECK( prewups[3] + 1 == wakeups[3], "snd_msg: Wakeups[3] not hit" );
+        CYG_TEST_CHECK( prewups[4] + 1 == wakeups[4], "snd_msg: Wakeups[4] not hit" );
+        prewups[2] = wakeups[2];
+        prewups[3] = wakeups[3];
+        prewups[4] = wakeups[4];
+
+        CYG_TEST_PASS( "Tested ISR invoked uITRON functions" );
+
+    } while ( 0 < --loops );
+
+    CYG_TEST_EXIT( "All done" );
+    ext_tsk();
+}
+
+
+void body( int n )
+{
+    unsigned int z;
+    ER ercd;
+    T_MSG *pk_msg;
+
+    do {
+        switch ( intercom ) {
+        case NOTHING:
+            ercd = slp_tsk();
+            CYG_TEST_CHECK( E_OK == ercd, "slp_tsk (doing nothing)" );
+            continue;
+        case SLP:
+            ercd = slp_tsk();
+            CYG_TEST_CHECK( E_OK == ercd, "slp_tsk bad ercd" );
+            wakeups[ n ]++;
+            break;
+        case SEM:
+            ercd = wai_sem( n-1 ); // 1..3 for semas
+            CYG_TEST_CHECK( E_OK == ercd, "wai_sem bad ercd" );
+            wakeups[ n ]++;
+            break;
+        case FLG:
+            ercd = wai_flg( &z, n, (1<<n), TWF_CLR | TWF_ANDW );
+            CYG_TEST_CHECK( E_OK == ercd, "wai_flg bad ercd" );
+            CYG_TEST_CHECK( z & (1<<n), "Flag bit not set" );
+            wakeups[ n ]++;
+            break;
+        case MBX:
+            ercd = rcv_msg( &pk_msg, n );
+            CYG_TEST_CHECK( E_OK == ercd, "rcv_msg bad ercd" );
+            CYG_TEST_CHECK( pk_msg, "rcv_msg NULL msg" );
+            wakeups[ n ]++;
+            break;
+        case EXIT:
+            return;
+        }
+    } while ( 1 );
+}
+
+void task2( unsigned int arg )
+{
+    ER ercd;
+    CYG_TEST_INFO( "Task 2 running" );
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 2 == scratch, "tid not 2" );
+    if ( 222 != arg )
+        CYG_TEST_FAIL( "Task 2 arg not 222" );
+    body(2);
+    CYG_TEST_INFO( "Task 2 exiting" );
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 2 failed to exit" );
+}
+
+void task3( unsigned int arg )
+{
+    ER ercd;
+    CYG_TEST_INFO("Task 3 running");
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 3 == scratch, "tid not 3" );
+    if ( 333 != arg )
+        CYG_TEST_FAIL( "Task 3 arg not 333" );
+    body(3);
+    CYG_TEST_INFO( "Task 3 exiting" );
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 3 failed to exit" );
+}
+
+void task4( unsigned int arg )
+{
+    ER ercd;
+    CYG_TEST_INFO("Task 4 running");
+    ercd = get_tid( &scratch );
+    CYG_TEST_CHECK( E_OK == ercd, "get_tid bad ercd" );
+    CYG_TEST_CHECK( 4 == scratch, "tid not 4" );
+    if ( 444 != arg )
+        CYG_TEST_FAIL( "Task 4 arg not 444" );
+    body(4);
+    CYG_TEST_INFO( "Task 4 exiting" );
+    ext_tsk();
+    CYG_TEST_FAIL( "Task 4 failed to exit" );
+}
+
+// ------------------------------------------------------------------------
+// Start of C++ aware portion, so to speak.
+//
+
+#include <cyg/hal/hal_intr.h>
+#include <cyg/kernel/intr.hxx>
+#include <cyg/kernel/clock.hxx>
+#include <cyg/kernel/sched.hxx>
+#include <cyg/kernel/sched.inl>
+
+void set_interrupt_number( void )
+{
+    clock_interrupt = CYGNUM_HAL_INTERRUPT_RTC;
+}
+
+// This snippet stolen from kernel/.../clock.cxx to be able to detach
+// the RTC from its interrupt source.
+class Cyg_RealTimeClock
+    : public Cyg_Clock
+{
+public:
+    Cyg_Interrupt       interrupt;
+
+    static cyg_uint32 isr(cyg_vector vector, CYG_ADDRWORD data);
+
+    static void dsr(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data);
+
+    Cyg_RealTimeClock();
+};
+
+
+static Cyg_Interrupt uit_intr(
+        (unsigned)CYGNUM_HAL_INTERRUPT_RTC, // Vector to attach to
+        0,                              // Queue priority
+        (unsigned)0,                    // Data pointer
+        &isr_wup_tsk,                   // Interrupt Service Routine
+        &cyg_uitron_dsr                 // Deferred Service Routine
+);
+
+void
+attach_isr( unsigned int (*isr)(unsigned int, unsigned int) )
+{
+    int inuse;
+    int old_ints;
+    Cyg_RealTimeClock *prtc = (Cyg_RealTimeClock *)Cyg_Clock::real_time_clock;
+    HAL_DISABLE_INTERRUPTS(old_ints);
+    HAL_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC );
+    prtc->interrupt.detach();
+#ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN
+    // Only check that the vector was cleared when there's a specific
+    // vector for the RTC.  In chain mode, other interrupt handlers
+    // may prevent the shared vector from being cleared when detaching
+    // the RTC ISR, and this assertion fails.
+    HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
+    CYG_TEST_CHECK( !inuse, "Failed to detach clock ISR" );
+#endif
+    uit_intr = Cyg_Interrupt( 
+        CYGNUM_HAL_INTERRUPT_RTC,       // Vector to attach to
+        1,                              // Queue priority
+        0,                              // Data pointer
+        isr,                            // Interrupt Service Routine
+        cyg_uitron_dsr                  // Deferred Service Routine
+        );    
+    uit_intr.attach();
+    HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
+    CYG_TEST_CHECK( inuse, "Failed to attach new ISR" );
+    ACK_CLOCK();
+    HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
+    HAL_RESTORE_INTERRUPTS(old_ints);
+}
+
+void
+detach_isr( unsigned int (*isr)(unsigned int, unsigned int) )
+{
+    int inuse;
+    int old_ints;
+    Cyg_RealTimeClock *prtc = (Cyg_RealTimeClock *)Cyg_Clock::real_time_clock;
+    HAL_DISABLE_INTERRUPTS(old_ints);
+    HAL_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC );
+    uit_intr.detach();
+#ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN
+    // See comment above in attach_isr.
+    HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
+    CYG_TEST_CHECK( !inuse, "Failed to detach my ISR" );
+#endif
+    prtc->interrupt.attach();
+    HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse );
+    CYG_TEST_CHECK( inuse, "Failed to attach clock ISR" );
+    ACK_CLOCK();
+    HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
+    HAL_RESTORE_INTERRUPTS(old_ints);
+}
+
+
+void
+lock_sched( void )
+{
+    cyg_uint32 l;
+    Cyg_Scheduler::lock();
+    l = Cyg_Scheduler::get_sched_lock();
+    CYG_TEST_CHECK( 0 < l, "lock: Sched not locked" );
+    CYG_TEST_CHECK( 2 > l, "lock: Sched already locked" );
+}
+
+void
+unlock_sched( void )
+{
+    cyg_uint32 l;
+    l = Cyg_Scheduler::get_sched_lock();
+    CYG_TEST_CHECK( 0 < l, "unlock: Sched not locked" );
+    CYG_TEST_CHECK( 2 > l, "unlock: Sched already locked" );
+    Cyg_Scheduler::unlock();
+}
+
+
+#else // not enough (or too many) uITRON objects configured in
+#define N_A_MSG "not enough uITRON objects to run test"
+#endif // not enough (or too many) uITRON objects configured in
+#else  // not C++ and some C++ specific options enabled
+#define N_A_MSG "C++ specific options selected but this is C"
+#endif  // not C++ and some C++ specific options enabled
+#else // ! CYGVAR_KERNEL_COUNTERS_CLOCK   - can't test without it
+#define N_A_MSG "no CYGVAR_KERNEL_COUNTERS_CLOCK"
+#endif // ! CYGVAR_KERNEL_COUNTERS_CLOCK  - can't test without it
+#else  // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#define N_A_MSG "no CYGFUN_KERNEL_THREADS_TIMER"
+#endif // ! CYGFUN_KERNEL_THREADS_TIMER   - can't test without it
+#else  // ! CYGIMP_THREAD_PRIORITY        - can't test without it
+#define N_A_MSG "no CYGSEM_KERNEL_SCHED_MLQUEUE"
+#endif // ! CYGSEM_KERNEL_SCHED_MLQUEUE   - can't test without it
+#else  // ! CYGPKG_UITRON
+#define N_A_MSG "uITRON Compatibility layer disabled"
+#endif // CYGPKG_UITRON
+
+#ifdef N_A_MSG
+externC void
+cyg_start( void )
+{
+    CYG_TEST_INIT();
+    CYG_TEST_NA( N_A_MSG );
+}
+#endif // N_A_MSG defined ie. we are N/A.
+
+// EOF testintr.c
diff --git a/packages/cygmon/v2_0/ChangeLog b/packages/cygmon/v2_0/ChangeLog
new file mode 100644 (file)
index 0000000..f52afba
--- /dev/null
@@ -0,0 +1,252 @@
+2000-12-04  Drew Moseley  <dmoseley@redhat.com>
+
+       * misc/monitor_cmd.c (breakpoint_cmd): Fix typo in printf
+       formatting for error message.
+
+2000-11-20  Drew Moseley  <dmoseley@redhat.com>
+
+       * cdl/cygmon.cdl: Make sure we don't specify vectors.o and target.ld twice.
+
+2000-11-03  Jonathan Larmour  <jlarmour@redhat.com>
+
+       * cdl/cygmon.cdl: Improve cygmon.elf make dependencies
+
+2000-10-17  Drew Moseley  <dmoseley@redhat.com>
+
+       * misc/utils.c: Fix a typo.  Also make sure we are ignoring the
+       '+' characters from gdb.
+
+       * misc/monitor_cmd.c: Add a few cache flushes.
+
+       * misc/monitor.h: Use the debug port for xvprintf.
+
+2000-08-14  Drew Moseley  <dmoseley@redhat.com>
+
+       * misc/ecos_bsp.c: Added some include files to fix some build
+       failures on partially unsupported systems. (ie non-cygmon, etc).
+
+2000-08-12  Drew Moseley  <dmoseley@redhat.com>
+
+       * misc/bsp/common/debug-io.c (bsp_debug_write): Use
+       output_gdb_string when stub_is_active.
+
+2000-08-10  Drew Moseley  <dmoseley@redhat.com>
+
+       * misc/utils.c: Removed some unused functions.  Also handle
+       printing invalid registers.
+
+       * misc/monitor_cmd.c: Handle some unprintable characters better.
+       Also handle displaying of invalid memory locations better.
+       Add handling for register validity checking.
+
+       * misc/monitor.h: Add a conditional field "reg_valid" to struct
+       regstruct.
+
+       * misc/monitor.c: Added a call to a conditionally defined routine
+       INITIALIZE_MON_EACH_TIME().  This is called everytime the monitor
+       is invoked.  For instance, this is used to determine which
+       registers have actually been read.
+
+       * misc/generic_mem.c: Allow Cygmon to use the Safe memory routines
+       in the HAL.
+
+       * misc/board.h: Added MN10300 basic support.
+       * misc/cpu-mon.c: Ditto.
+       * misc/cpu_info.h: Ditto.
+       * misc/bsp/cpu.h: Ditto.
+       * misc/bsp/mn10300/gdb-cpu.c: Ditto. New file.
+       * misc/bsp/mn10300/gdb-cpu.h: Ditto. New file.
+       * misc/bsp/mn10300/gdb.h: Ditto. New file.
+       * misc/bsp/mn10300/insn.h: Ditto. New file.
+       * misc/bsp/mn10300/singlestep.c: Ditto. New file.
+       * misc/mn10300/board.h: Ditto. New file.
+       * misc/mn10300/cpu.h: Ditto. New file.
+       * misc/mn10300/cpu_info.h: Ditto. New file.
+       * misc/mn10300/mn10300-mon.c: Ditto. New file.
+
+       * cdl/cygmon.cdl: Removed dependency on the kernel and Serial I/O.
+       * misc/ecos_bsp.c: Ditto.
+       * misc/ecos_dummy.c: Ditto.
+
+2000-07-21  Drew Moseley  <dmoseley@redhat.com>
+
+       * misc/ecos_bsp.c: Rearrange the linkage between Cygmon and HAL so
+       that Cygmon needs HAL but not vice-versa.  ie HAL no longer calls
+       any Cygmon functions.
+       * misc/monitor.c: Ditto.
+
+2000-07-14  Drew Moseley  <dmoseley@redhat.com>
+
+       * misc/bsp/mips/gdb-cpu.c: New files. Mips based Cygmon now running on top of eCos HAL.
+       * misc/bsp/mips/gdb-cpu.h: Ditto.
+       * misc/bsp/mips/gdb.h: Ditto.
+       * misc/bsp/mips/insn.h: Ditto.
+       * misc/bsp/mips/singlestep.c: Ditto.
+       * misc/mips/board.h: Ditto.
+       * misc/mips/cpu.h: Ditto.
+       * misc/mips/cpu_info.h: Ditto.
+       * misc/mips/mips-mon.c: Ditto.
+
+       * misc/bsp/common/syscall.c: Added SYS_meminfo call to find out
+       how much RAM we have.
+       * misc/bsp/common/syscall.h: Ditto.
+
+       * misc/bsp/common/breakpoint.c: Added __ECOS__ support.
+
+       * misc/monitor_cmd.c: Cleanup.  Added some more error handling.
+       * misc/utils.c: Ditto.
+
+       * misc/monitor.c: Added basic syscall handling to support libgloss.
+       Added support for using more features of the HAL (ie breakpoints
+       and exceptions).
+       * misc/monitor.h: Ditto.
+       * misc/tservice.h: Ditto.
+       * misc/bsp/bsp.h: Ditto.
+       * misc/arm/cpu_info.h: Ditto.
+
+       * misc/ledit.c: Cleanup.
+
+       * misc/ecos_dummy.c: Support for reset through the HAL.
+
+       * misc/ecos_bsp.c: Filled in uart_control function for setting baud rate
+       through the HAL.  Also added VIRTUAL_VECTOR_SUPPORT and support of the
+       low-level HAL-based serial driver.  Also added set_memsize() support.
+
+       * misc/bplist-dynamic.c: Added option for using breakpoints in the HAL.
+       Also, various cleanups of build warnings, etc.  
+       * misc/breakpoints.c: Ditto.
+
+       * cdl/cygmon.cdl: Allow cygmon to be built for either Arm or Mips.
+       
+       * misc/board.h: Move architecture-dependent things out.
+       * misc/cpu-mon.c: Ditto.
+       * misc/cpu_info.h: Ditto.
+       * misc/bsp/cpu.h: Ditto.
+       * misc/bsp/common/gdb-cpu.c: Ditto.
+       * misc/bsp/common/gdb-cpu.h: Ditto.
+       * misc/bsp/common/singlestep.c: Ditto.
+
+2000-01-28  Jesper Skov  <jskov@redhat.com>
+
+       * misc/Notes_CygMon_PID: Added.
+
+2000-01-27  Jesper Skov  <jskov@redhat.com>
+
+       * cdl/cygmon.cdl: Include hal.h config for CygMon options defined
+       by platform CDL.
+
+2000-01-26  Jonathan Larmour  <jlarmour@redhat.co.uk>
+
+       * cdl/cygmon.cdl: Remove CYGDAT_CYGMON_ENABLE - no longer required
+
+2000-01-25  Jesper Skov  <jskov@cygnus.co.uk>
+
+       * cdl/cygmon.cdl: Moved console device config to target CDL.
+       Let target CDL handle binary conversion.
+
+1999-12-17  Bart Veer  <bartv@cygnus.co.uk>
+
+       * cdl/cygmon.cdl:
+       Fix a requires property, getting the quoting right
+
+1999-12-14  John Dallaway  <jld@cygnus.co.uk>
+
+       * cdl/cygmon.cdl: Add custom make rule to build CygMon.
+
+1999-12-06  Gary Thomas  <gthomas@cygnus.co.uk>
+
+       * misc/arm/arm-mon.c (machine_syscall): 
+       * misc/ecos_bsp.c (_bsp_handle_exception): 
+       * misc/PKGconf.mak: Adding 'syscall' support.
+
+       * misc/CygMon_PID.cfg: 
+       * misc/bsp/common/syscall.h:
+       * misc/bsp/common/syscall.c: New file(s).
+
+1999-11-26  Jonathan Larmour  <jlarmour@cygnus.co.uk>
+
+       * misc/CygMon_EDB7211.cfg: Rename to misc/CygMon/EDB7xxx.cfg
+       * misc/CygMon_EDB7xxx.cfg: New file
+
+1999-11-26  Gary Thomas  <gthomas@cygnus.co.uk>
+
+       * misc/ecos_bsp.c (_bsp_board_init): Use/define HAL symbols
+       for board/cpu information.
+       (_bsp_memory_list): Use MLT information here.
+
+       * misc/CygMon_EDB7211.cfg: Fix typo.  Change startup to be
+       ROM which gives more useful RAM information.
+
+1999-11-19  Gary Thomas  <gthomas@cygnus.co.uk>
+
+       * misc/CygMon_EDB7211.cfg: Add platform parameter.  Update
+       patch for latest changes.
+
+1999-11-03  Jesper Skov  <jskov@cygnus.co.uk>
+
+       * cdl/cygmon.cdl: Added.
+
+1999-10-27  Gary Thomas  <gthomas@cygnus.co.uk>
+
+       * misc/PKGconf.mak: Add new targets (.bin .srec images).
+
+       * include/pkgconf/cygmon.h: Update strings to be more conformant.
+
+       * misc/CygMon_EDB7211.cfg: New file for building CygMon.
+
+       * include/pkgconf/cygmon.h: Add work-around because packages
+       can't be disabled by default.
+
+1999-10-26  Gary Thomas  <gthomas@cygnus.co.uk>
+
+       * include/pkgconf/cygmon.h: Fix typo 'CYGPKC_LIBC'=>'CYGPKG_LIBC'
+       Also, node type was wrong ('radio' instead of 'boolean')
+
+1999-10-25  Gary Thomas  <gthomas@cygnus.co.uk>
+
+       * include/pkgconf/cygmon.h: Add configuration options for
+       console device [name] and extended help.  Remove duplicate
+       boilerplate.
+
+       * misc/board.h: Enable "help" via configuration option.
+
+       * misc/ecos_bsp.c: Cleanup/remove extra (debug) code.
+       Add support for console port configuration.
+
+       * misc/monitor.c: 
+       * misc/monitor_cmd.c: Cleanup/remove some debug code.
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
diff --git a/packages/cygmon/v2_0/cdl/cygmon.cdl b/packages/cygmon/v2_0/cdl/cygmon.cdl
new file mode 100644 (file)
index 0000000..04f4645
--- /dev/null
@@ -0,0 +1,140 @@
+# ====================================================================
+#
+#      cygmon.cdl
+#
+#      CygMon package configuration data
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      jskov
+# Original data:  gthomas
+# Contributors:   dmoseley
+# Date:           1999-11-03
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+cdl_package CYGPKG_CYGMON {
+    display  "CygMon ROM monitor"
+    requires CYGPKG_LIBC_STRING
+    include_dir   cyg/cygmon
+    define_header cygmon.h
+    description   "
+           This package supports the CygMon \[stand-alone debug monitor\]
+           using eCos as the underlying board support mechanism."
+
+
+    # Since the CYGDAT_CYGMON_CONSOLE_DEV setting ends up in the platform
+    # HAL header, we need to include that here (via hal.h).
+    define_proc {
+        puts $::cdl_header "#include <pkgconf/hal.h>"
+    }
+
+   cdl_option CYGDAT_CYGMON_USE_HELP {
+       display "Include detailed command help"
+       default_value 1
+       description "
+           When this option is selected, the CygMon image will include
+           detailed help information for all built-in commands.  Without
+           it, only minimal help will be provided."
+   }
+
+    cdl_option CYGBLD_BUILD_CYGMON {
+        display "Build CygMon ROM ELF image"
+        default_value 0
+        requires { CYG_HAL_STARTUP == "ROM" }
+        requires CYGPKG_INFRA
+        requires CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+        requires ! CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
+        requires ! CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT
+        requires ! CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT
+        requires CYGPKG_LIBC_STRING
+        requires ! CYGFUN_LIBC_strtod
+        requires ! CYGPKG_LIBC_STDIO
+        requires ! CYGSEM_LIBC_SIGNALS_THREAD_SAFE
+        requires ! CYGIMP_LIBC_SIGNALS_RAISE_INLINE
+        requires ! CYGIMP_LIBC_SIGNALS_SIGNAL_INLINE
+        requires ! CYGSEM_LIBC_SIGNALS_RAISE_SETS_ERRNO
+        requires ! CYGSEM_LIBC_SIGNALS_SIGNAL_SETS_ERRNO
+        requires ! CYGFUN_LIBC_ATEXIT
+        requires ! CYGSEM_LIBC_EXIT_CALLS_FFLUSH
+        requires ! CYGPKG_LIBC_ENVIRONMENT
+        requires ! CYGSEM_LIBC_PER_THREAD_ERRNO
+        requires ! CYGSEM_LIBC_TIME_TIME_WORKING
+        requires ! CYGSEM_LIBC_TIME_SETTIME_WORKING
+        requires { CYGPKG_HAL_ARM || CYGPKG_HAL_MIPS || CYGPKG_HAL_MN10300 }
+
+        no_define
+        description "This option enables the building of the CygMon ELF image.
+                     The image may require further relocation or symbol
+                     stripping before being converted to a binary image.
+                     This is handled by a rule in the target CDL."
+
+        make -priority 320 {
+            <PREFIX>/bin/cygmon.elf : $(PREFIX)/lib/target.ld $(PREFIX)/lib/vectors.o $(PREFIX)/lib/libtarget.a $(PREFIX)/lib/libextras.a <PACKAGE>/misc/ecos_bsp.c <PACKAGE>/misc/ecos_dummy.c <PACKAGE>/misc/cpu-mon.c <PACKAGE>/misc/monitor.c <PACKAGE>/misc/monitor_cmd.c <PACKAGE>/misc/ledit.c <PACKAGE>/misc/breakpoints.c <PACKAGE>/misc/bplist-dynamic.c <PACKAGE>/misc/utils.c <PACKAGE>/misc/generic_fmt32.c <PACKAGE>/misc/generic_mem.c <PACKAGE>/misc/bsp/common/bsp.c <PACKAGE>/misc/bsp/common/bsp_if.c <PACKAGE>/misc/bsp/common/shared-data.c <PACKAGE>/misc/bsp/common/sysinfo.c <PACKAGE>/misc/bsp/common/console-io.c <PACKAGE>/misc/bsp/common/debug-io.c <PACKAGE>/misc/bsp/common/sprintf.c <PACKAGE>/misc/bsp/common/syscall.c <PACKAGE>/misc/bsp/common/printf.c <PACKAGE>/misc/bsp/common/vprintf.c <PACKAGE>/misc/bsp/common/breakpoint.c <PACKAGE>/misc/bsp/common/singlestep.c <PACKAGE>/misc/bsp/common/generic-mem.c <PACKAGE>/misc/bsp/common/bsp_cache.c <PACKAGE>/misc/bsp/common/gdb-cpu.c <PACKAGE>/misc/bsp/common/hex-utils.c
+            @sh -c "mkdir -p misc/bsp/common $(dir $@)"
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/ecos_bsp.o $(REPOSITORY)/$(PACKAGE)/misc/ecos_bsp.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/ecos_dummy.o $(REPOSITORY)/$(PACKAGE)/misc/ecos_dummy.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/cpu-mon.o $(REPOSITORY)/$(PACKAGE)/misc/cpu-mon.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/monitor.o $(REPOSITORY)/$(PACKAGE)/misc/monitor.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/monitor_cmd.o $(REPOSITORY)/$(PACKAGE)/misc/monitor_cmd.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/ledit.o $(REPOSITORY)/$(PACKAGE)/misc/ledit.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/breakpoints.o $(REPOSITORY)/$(PACKAGE)/misc/breakpoints.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bplist-dynamic.o $(REPOSITORY)/$(PACKAGE)/misc/bplist-dynamic.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/utils.o $(REPOSITORY)/$(PACKAGE)/misc/utils.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/generic_fmt32.o $(REPOSITORY)/$(PACKAGE)/misc/generic_fmt32.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/generic_mem.o $(REPOSITORY)/$(PACKAGE)/misc/generic_mem.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/bsp.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/bsp.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/bsp_if.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/bsp_if.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/shared-data.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/shared-data.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/sysinfo.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/sysinfo.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/console-io.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/console-io.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/debug-io.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/debug-io.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/sprintf.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/sprintf.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/syscall.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/syscall.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/printf.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/printf.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/vprintf.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/vprintf.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/breakpoint.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/breakpoint.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/singlestep.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/singlestep.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/generic-mem.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/generic-mem.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/bsp_cache.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/bsp_cache.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/gdb-cpu.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/gdb-cpu.c
+            $(CC) -c -I$(REPOSITORY)/$(PACKAGE)/misc $(INCLUDE_PATH) $(CFLAGS) -DHAVE_BSP -D__ECOS__ -o misc/bsp/common/hex-utils.o $(REPOSITORY)/$(PACKAGE)/misc/bsp/common/hex-utils.c
+            $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -o $@ $(filter-out %.ld %vectors.o, $(patsubst $(REPOSITORY)/$(PACKAGE)/%.c,%.o,$^))
+        }
+    }
+}
diff --git a/packages/cygmon/v2_0/misc/Notes_CygMon_PID b/packages/cygmon/v2_0/misc/Notes_CygMon_PID
new file mode 100644 (file)
index 0000000..b1fed76
--- /dev/null
@@ -0,0 +1,168 @@
+===========================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+===========================================================================
+
+28 Jan 2000
+
+How to build and install CygMon on the PID
+
+Make CygMon image
+~~~~~~~~~~~~~~~~~
+
+Configure and build using the 'cygmon' template for the PID
+target. These are the necessary CLI instructions. It can also be done
+from the Configtool by selecting the appropriate templates.
+
+ % cd /tmp
+ % mkdir cygmon
+ % cd cygmon
+ % ecosconfig new pid cygmon
+ % ecosconfig tree
+ % make
+
+This will install some files in ./install/bin:
+
+ cygmon.elf:   The built CygMon image
+ cygmon.bin:   The image converted to binary (suitable for burning to ROM)
+ cygmon.img:   The relocated ELF image (suitable for FLASH writing, see below)
+ cygmon.srec:  The image converted to srecords
+
+Make FLASH tool
+~~~~~~~~~~~~~~~
+
+Again, these are the necessary CLI instructions. It can also be done
+from the Configtool by selecting the appropriate templates, and
+enabling the option.
+
+ % cd /tmp
+ % mkdir pid-flash
+ % cd pid-flash
+ % ecosconfig new pid
+ % <edit ecos.ecc, enabling the CYGBLD_BUILD_FLASH_TOOL option:>
+      --- ecos.ecc.orig       Fri Jan 28 11:21:43 2000
+      +++ ecos.ecc            Fri Jan 28 11:22:01 2000
+      @@ -150,7 +150,7 @@
+       cdl_option CYGBLD_BUILD_FLASH_TOOL {
+          # Flavor: bool
+          # No user value, uncomment the following line to provide one.
+      -    # user_value 0
+      +    user_value 1
+          # value_source default
+          # Default value: 0
+          # Requires:  CYG_HAL_STARTUP == "RAM" 
+ % ecosconfig resolve
+ % ecosconfig tree
+ % make
+
+The flash tool is installed in ./install/bin
+
+Prepare board for CygMon
+~~~~~~~~~~~~~~~~~~~~~~~~
+ 1. Set jumper 7-8 on LK6   [using the Angle code in the 16 bit EPROM]
+ 2. Set jumper 5-6 on LK6   [select 8bit ROM mode]
+ 3. Set jumper LK18         [ROM remap - this is also required for eCos]
+ 4. Set S1 to 0-0-1-1       [20MHz operation]
+
+
+Program FLASH
+~~~~~~~~~~~~~
+ 1. Download the CygMon relocated image onto the PID board:
+      % cd /tmp
+      % arm-elf-gdb -nw cygmon/install/bin/cygmon.img
+
+       (gdb) target rdi s=<serial device>
+       Angel Debug Monitor V1.04 (Advanced RISC Machines SDT 2.11a) for PID
+       Built with Serial(x1), Parallel, DCC
+       Rebuilt on Apr  7 1998 at 22:20:43
+       Serial Rate:   9600
+       Connected to ARM RDI target.
+       (gdb) load
+       Loading section .rom_vectors, size 0x60 lma 0x60000
+       Loading section .text, size 0xeea8 lma 0x60060
+       Loading section .rodata, size 0x304c lma 0x6ef08
+       Loading section .data, size 0x7f8 lma 0x71f54
+       Start address 0x60060 , load size 75596
+       Transfer rate: 5548 bits/sec.
+       (gdb) quit
+
+   This will download the stubs onto the board at 0x60000..0x80000
+
+   Use /dev/ttyS0, COM1 or similar for the <serial device> name.
+
+ 2. Now download the FLASH programmer tool
+      % arm-elf-gdb -nw pid-flash/install/bin/prog_flash.img
+
+       (gdb) target rdi s=<serial device>
+       Angel Debug Monitor V1.04 (Advanced RISC Machines SDT 2.11a) for PID
+       Built with Serial(x1), Parallel, DCC
+       Rebuilt on Apr  7 1998 at 22:20:43
+       Serial Rate:   9600
+       Connected to ARM RDI target.
+       (gdb) load
+       Loading section .rom_vectors, size 0x60 lma 0x4000
+       Loading section .text, size 0x4964 lma 0x4060
+       Loading section .rodata, size 0x384 lma 0x89c4
+       Loading section .data, size 0x28c lma 0x8d48
+       Start address 0x4060 , load size 20436
+       Transfer rate: 5449 bits/sec.
+       (gdb) cont
+
+ 3. The FLASH tool will output some text on the board serial port B at
+    38400 baud:
+
+       ARM eCos
+       FLASH here!
+       manuf: 8, device: 40
+       Error: Wrong Manufaturer: 08
+       ... Please change FLASH jumper
+
+ 4. This text is repeated until you remove the jumper 7-8 on LK6. Then
+    the output should be:
+
+       manuf: 1F, device: A4
+       AT29C040A recognised
+       About to program FLASH using data at 60000..80000
+       *** Press RESET now to abort!
+    
+ 5. You have about 10 seconds to abort the operation by pressing
+    reset. After this timeout, the FLASH programming happens:
+  
+      ...Programming FLASH
+      All done!
+
+ 6. Quit/kill the GDB process which will hang.
+
+ 7. Next time you reset the board, CygMon will be in control, communicating
+    on serial port A at 38400 baud. See documentation for further details
+    on how to connect with GDB.
diff --git a/packages/cygmon/v2_0/misc/arm/arm-mon.c b/packages/cygmon/v2_0/misc/arm/arm-mon.c
new file mode 100644 (file)
index 0000000..30283f7
--- /dev/null
@@ -0,0 +1,281 @@
+//==========================================================================
+//
+//      arm-mon.c
+//
+//      Support code to extend the generic monitor code to support
+//      ARM(R) processors.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Support code to extend the generic monitor code to support
+//               ARM(R) processors.
+// Description:  Further board specific support is in other files.
+//               This file contains:
+//                 register names lookup table
+//
+//               Empty Stubs:
+//                 Interval timer - This should really belong to the application
+//                 operating system.
+//
+//               Should not contain:
+//                 low level uart getchar and putchar functions
+//                 delay function to support uart
+//
+//               ARM is a Registered Trademark of Advanced RISC Machines
+//               Limited.
+//               Other Brands and Trademarks are the property of their
+//               respective owners.               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <setjmp.h>
+#include <bsp/bsp.h>
+#include <bsp/cpu.h>
+#ifdef DISASSEMBLER
+#include <dis-asm.h>
+#endif
+
+#include "cpu_info.h"
+#include "monitor.h"
+
+/* This module is required to provide many of the services defined
+   in tservice.h */
+
+static char *apcs_names[] = {
+  "a1", "a2", "a3", "a4",
+  "v1", "v2", "v3", "v4",
+  "v5", "v6", "sl", "fp",
+  "ip", "sp", "lr", "pc",
+#if HAVE_FLOAT_REGS
+  "f0", "f1", "f2", "f3",
+  "f4", "f5", "f6", "f7",
+  "fps",
+#endif
+  "ps"
+};
+
+static char *standard_names[] =
+{
+  "r0",  "r1",  "r2",  "r3",
+  "r4",  "r5",  "r6",  "r7",
+  "r8",  "r9",  "r10", "r11",
+  "r12", "r13", "r14", "pc",
+#if HAVE_FLOAT_REGS
+  "f0",  "f1",  "f2",  "f3",
+  "f4",  "f5",  "f6",  "f7",
+  "fps",
+#endif
+  "ps",
+};
+
+
+void arm_othernames (void);
+
+struct regstruct regtab[] =
+{
+  { 0, REG_R0,   REGTYPE_INT   },
+  { 0, REG_R1,   REGTYPE_INT   },
+  { 0, REG_R2,   REGTYPE_INT   },
+  { 0, REG_R3,   REGTYPE_INT   },
+  { 0, REG_R4,   REGTYPE_INT   },
+  { 0, REG_R5,   REGTYPE_INT   },
+  { 0, REG_R6,   REGTYPE_INT   },
+  { 0, REG_R7,   REGTYPE_INT   },
+  { 0, REG_R8,   REGTYPE_INT   },
+  { 0, REG_R9,   REGTYPE_INT   },
+  { 0, REG_R10,  REGTYPE_INT   },
+  { 0, REG_R11,  REGTYPE_INT   },
+  { 0, REG_R12,  REGTYPE_INT   },
+  { 0, REG_SP,   REGTYPE_INT   },
+  { 0, REG_LR,   REGTYPE_INT   },
+  { 0, REG_PC,   REGTYPE_INT   },
+#if HAVE_FLOAT_REGS
+  { 0, REG_F0,   REGTYPE_FLOAT },
+  { 0, REG_F1,   REGTYPE_FLOAT },
+  { 0, REG_F2,   REGTYPE_FLOAT },
+  { 0, REG_F3,   REGTYPE_FLOAT },
+  { 0, REG_F4,   REGTYPE_FLOAT },
+  { 0, REG_F5,   REGTYPE_FLOAT },
+  { 0, REG_F6,   REGTYPE_FLOAT },
+  { 0, REG_F6,   REGTYPE_FLOAT },
+  { 0, REG_FPS,  REGTYPE_FLOAT },
+#endif
+  { 0, REG_CPSR, REGTYPE_INT   },
+  { 0, 0,        0             } /* Terminating element must be last */
+} ;
+
+void
+initialize_mon(void)
+{
+  /* FIXME: Convert ALL variable initializations to assignments
+     in order to support ROMABLE CODE.
+     This includes the register table
+     */
+
+  /*
+   * Call arm_othernames to sync up Cygmon and the disassembler
+   * and ensure they are using the same set of registernames
+   */
+  arm_othernames();
+
+  /*
+   * Call arm_othernames again to revert to the assembler
+   * default names
+   */
+  arm_othernames();
+
+} /* initialize_mon */
+
+
+/*
+  read_memory
+  write_memory
+       Defaults to generic_mem.c
+       */
+
+
+/* SET_BREAKPOINT -
+   CLEAR_BREAKPOINT
+   Defaults to generic_bp32.c
+   */
+
+
+#ifndef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+/* Return the currently-saved value corresponding to register "regnum". */
+target_regval_t
+get_register (int regnum)
+{
+    struct regstruct *p;
+    target_regval_t reg;
+    int   offset, len;
+    char  *dest = (char*)0;
+
+    for (p = regtab; p->registername && p->registernumber != regnum; ++p)
+       ;
+
+    if (p->registername) {
+       len = bsp_regsize(p->registernumber);
+       offset = bsp_regbyte(p->registernumber);
+       switch (p->registertype) {
+         case REGTYPE_INT:
+           dest = (char*)&(reg.i);
+           break;
+#if HAVE_FLOAT_REGS
+        case REGTYPE_FLOAT:
+           dest = (char*)&(reg.f);
+           break;
+#endif
+#if HAVE_DOUBLE_REGS
+        case REGTYPE_DOUBLE:
+           dest = (char*)&(reg.d);
+           break;
+#endif
+       }
+        if (dest)
+            memcpy(dest, (char *)mon_saved_regs + offset, len);
+    } else
+       reg.i = 0;
+
+    return reg;
+}
+
+
+
+/* Store VALUE in the register corresponding to REGNUM. */
+void
+put_register (int regnum, target_regval_t value)
+{
+    int   offset, len;
+
+    len = bsp_regsize(regnum);
+    offset = bsp_regbyte(regnum);
+    memcpy((char *)mon_saved_regs + offset, &value, len);
+}
+
+#endif // !CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+
+/* Change to the alternate register set names */
+void
+arm_othernames (void)
+{
+    static int regset = 1;
+    char **name;
+    int  i;
+
+#ifdef DISASSEMBLER
+    /* Change the disassembler */
+    regset = arm_toggle_regnames();
+#else
+    regset = (regset == 0) ? 1 : 0;
+#endif
+
+    /* Change cygmon */
+    if (regset == 1)
+        /* Disassembler is using apcs names. */
+        name = apcs_names;
+    else
+        /* Disassembler is using standard names. */
+        name = standard_names;
+
+    for (i = 0; i < (sizeof(apcs_names)/sizeof(apcs_names[0])); i++)
+       regtab[i].registername = name[i];
+}
+
+#ifdef __ECOS__
+
+#include <pkgconf/hal.h>
+#include <cyg/hal/hal_arch.h>
+#include "bsp/common/bsp_if.h"
+
+int
+machine_syscall(HAL_SavedRegisters *regs)
+{
+    int res, err;
+    err = _bsp_do_syscall(regs->d[0], // Function
+                          regs->d[1], regs->d[2], regs->d[3], 0, // arguments,
+                          &res);
+    regs->d[0] = res;
+    regs->pc += 4;  // Advance PC
+    return err;
+}
+#endif
diff --git a/packages/cygmon/v2_0/misc/arm/board.h b/packages/cygmon/v2_0/misc/arm/board.h
new file mode 100644 (file)
index 0000000..f84b831
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef __CYGMON_ARM_BOARD_H__
+#define __CYGMON_ARM_BOARD_H__
+//==========================================================================
+//
+//      board.h
+//
+//      Cygmon board/platform configuration file
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+// Hardware/platform/configuration specifics
+
+#include <pkgconf/hal.h>
+#include <pkgconf/cygmon.h>
+
+#define HAVE_FLOAT_REGS         0
+#define HAVE_DOUBLE_REGS        0
+#define HAVE_CACHE              0 // FIXME
+#define HAVE_USAGE              0 // FIXME
+#define USE_CYGMON_PROTOTYPES   1
+#define NOMAIN                  1
+#define CYGMON_SYSTEM_SERVICES  0 // Not used, fall back to BSP support
+#ifdef CYGDAT_CYGMON_USE_HELP
+#define USE_HELP                1
+#endif
+
+// For breakpoint support
+#define NO_MALLOC               1
+#define MAX_BP_NUM              8
+#include "cpu_info.h"
+#define TRAP_SIZE               4
+#define __set_breakpoint        set_breakpoint
+#define __remove_breakpoint     clear_breakpoint
+#define __write_mem_safe        memcpy
+#define WRITE_MEM_IS_MEMCPY
+#define _breakinst              bsp_breakinsn
+
+#endif //  __CYGMON_ARM_BOARD_H__
diff --git a/packages/cygmon/v2_0/misc/arm/cpu.h b/packages/cygmon/v2_0/misc/arm/cpu.h
new file mode 100644 (file)
index 0000000..607f0d5
--- /dev/null
@@ -0,0 +1,978 @@
+#ifndef __ARM_CPU_H__
+#define __ARM_CPU_H__
+//==========================================================================
+//
+//      cpu.h
+//
+//      ARM specific processor defines
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      ARM specific processor defines 
+// Description:  ARM is a Registered Trademark of Advanced RISC Machines
+//               Limited.
+//               Other Brands and Trademarks are the property of their
+//               respective owners.               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <bsp/bsp.h>
+#include <bsp/defs.h>
+#ifdef __ECOS__
+#include <cyg/hal/hal_arch.h>
+#endif
+
+/*
+ * Only define __NEED_UNDERSCORE__ for arm-coff targets
+ */
+#if !defined(__ELF__)
+#  define __NEED_UNDERSCORE__
+#endif
+
+/*
+ * Macros to glue together two tokens.
+ */
+#  ifdef __STDC__
+#    define XGLUE(a,b) a##b
+#  else
+#    define XGLUE(a,b) a/**/b
+#  endif
+
+#  define GLUE(a,b) XGLUE(a,b)
+
+/*
+ * Symbol Names with leading underscore if necessary
+ */
+#  ifdef __NEED_UNDERSCORE__
+#    define SYM_NAME(name) GLUE(_,name)
+#  else
+#    define SYM_NAME(name) name
+#  endif /* __NEED_UNDERSCORE__ */
+
+/*
+ * Various macros to better handle assembler/object format differences
+ */
+#if defined(__ASSEMBLER__)
+
+/*
+ * Assembly function start definition
+ */
+#ifdef __NEED_UNDERSCORE__
+.macro FUNC_START name
+       .global _\name
+       .align  4
+    _\name:
+.endm
+#else
+.macro FUNC_START name
+       .global \name
+       .align  4
+    \name:
+.endm
+#endif
+
+/*
+ * Assembly function end definition
+ */
+#ifdef __NEED_UNDERSCORE__
+.macro FUNC_END name
+.endm
+#else
+.macro FUNC_END name
+.endm
+#endif
+
+/*
+ * Register Prefix
+ */
+#  ifndef __REGISTER_PREFIX__
+#    define __REGISTER_PREFIX__
+#  endif /* __REGISTER_PREFIX__ */
+
+/*
+ * Immediate Prefix
+ */
+#  ifndef __IMM_PREFIX__
+#    define __IMM_PREFIX__ #
+#  endif /* __IMM_PREFIX__ */
+
+/*
+ * use the right prefix for registers.
+ */
+#  define REG(x) GLUE(__REGISTER_PREFIX__,x)
+
+/*
+ * use the right prefix for immediate values.
+ */
+#  define IMM(x) GLUE(__IMM_PREFIX__,x)
+
+#endif /* defined(__ASSEMBLER__) */
+
+
+/*
+ * Setup register defines and such
+ */
+#if defined(__ASSEMBLER__)
+
+#  define r0   REG (r0)
+#  define r1   REG (r1)
+#  define r2   REG (r2)
+#  define r3   REG (r3)
+
+#  define r4   REG (r4)
+#  define r5   REG (r5)
+#  define r6   REG (r6)
+#  define r7   REG (r7)
+#  define r8   REG (r8)
+#  define r9   REG (r9)
+#  define r10  REG (r10)
+#  define r11  REG (r11)
+#  define r12  REG (r12)
+#  define r13  REG (r13)
+#  define sp   REG (sp)
+#  define r14  REG (r14)
+#  define lr   REG (lr)
+#  define pc   REG (pc)
+
+#  define f0   REG (f0)
+#  define f1   REG (f1)
+#  define f2   REG (f2)
+#  define f3   REG (f3)
+#  define f4   REG (f4)
+#  define f5   REG (f5)
+#  define f6   REG (f6)
+#  define f7   REG (f7)
+#  define fps  REG (fps)
+
+#  define cpsr REG (cpsr)
+#  define spsr REG (spsr)
+
+/*
+ * Register offset definitions
+ * These numbers are offsets into the ex_regs_t struct.
+ */
+#  define r0_o   0
+#  define r1_o   4
+#  define r2_o   8
+#  define r3_o   12
+#  define r4_o   16
+#  define r5_o   20
+#  define r6_o   24
+#  define r7_o   28
+#  define r8_o   32
+#  define r9_o   36
+#  define r10_o  40
+#  define r11_o  44
+#  define r12_o  48
+#  define r13_o  52
+#  define sp_o   r13_o
+#  define r14_o  56
+#  define lr_o   r14_o
+#  define pc_o   60
+
+#  define f0_o   64
+#  define f1_o   76
+#  define f2_o   88
+#  define f3_o   100
+#  define f4_o   112
+#  define f5_o   124
+#  define f6_o   136
+#  define f7_o   148
+#  define fps_o  160
+
+#  define cpsr_o 164
+#  define spsvc_o 168
+#  define ARM_EX_REGS_T_SIZE 172
+
+#else /* !defined(__ASSEMBLER__) */
+
+  /*
+   * Register name that is used in help strings and such
+   */
+# define REGNAME_EXAMPLE "r0"
+
+  /*
+   *  Register numbers. These are assumed to match the
+   *  register numbers used by GDB.
+   */
+  enum __regnames {
+      REG_R0,
+      REG_R1,
+      REG_R2,
+      REG_R3,
+      REG_R4,
+      REG_R5,
+      REG_R6,
+      REG_R7,
+      REG_R8,
+      REG_R9,
+      REG_R10,
+      REG_R11,
+      REG_R12,
+      REG_R13,
+      REG_SP=REG_R13,
+      REG_R14,
+      REG_LR=REG_R14,
+      REG_PC,
+
+      REG_F0,
+      REG_F1,
+      REG_F2,
+      REG_F3,
+      REG_F4,
+      REG_F5,
+      REG_F6,
+      REG_F7,
+      REG_FPS,
+
+      REG_CPSR,
+      REG_SPSVC,
+      REG_MAX=REG_SPSVC
+  };
+
+  /*
+   * 12-byte struct for storing Floating point registers
+   */
+  typedef struct
+  {
+      unsigned long high;
+      unsigned long middle;
+      unsigned long low;
+  } fp_reg;
+
+  /*
+   *  How registers are stored for exceptions.
+   */
+#ifdef __ECOS__
+#define ex_regs_t HAL_SavedRegisters
+#define _r0       d[0]
+#define _r1       d[1]
+#define _r2       d[2]
+#define _r3       d[3]
+#define _r4       d[4]
+#define _r5       d[5]
+#define _r6       d[6]
+#define _r7       d[7]
+#define _r8       d[8]
+#define _r9       d[9]
+#define _r10      d[10]
+#define _r11      fp
+#define _r12      ip
+#define _r13      sp
+#define _r14      lr
+#define _pc       pc
+#define _cpsr     cpsr
+#define _spsvc    msr
+#else
+  typedef struct
+  {
+    unsigned long _r0;
+    unsigned long _r1;
+    unsigned long _r2;
+    unsigned long _r3;
+    unsigned long _r4;
+    unsigned long _r5;
+    unsigned long _r6;
+    unsigned long _r7;
+    unsigned long _r8;
+    unsigned long _r9;
+    unsigned long _r10;
+    unsigned long _r11;
+    unsigned long _r12;
+    unsigned long _r13;
+    unsigned long _r14;
+    unsigned long _pc;
+
+    fp_reg        _f0;
+    fp_reg        _f1;
+    fp_reg        _f2;
+    fp_reg        _f3;
+    fp_reg        _f4;
+    fp_reg        _f5;
+    fp_reg        _f6;
+    fp_reg        _f7;
+    unsigned long _fps;
+    unsigned long _cpsr;
+
+    unsigned long _spsvc;  /* saved svc mode sp */
+
+  } ex_regs_t;
+#endif
+#   define   _sp  _r13
+#   define   _lr  _r14
+
+extern void __icache_flush(void *addr, int nbytes);
+extern void __dcache_flush(void *addr, int nbytes);
+
+#endif /* __ASSEMBLER__ */
+
+
+/*
+ * Program Status Register Definitions
+ */
+#if defined(__ASSEMBLER__)
+#  define ARM_PSR_NEGATIVE       0x80000000  /* Negative Bit                           */
+#  define ARM_PSR_ZERO           0x40000000  /* Zero Bit                               */
+#  define ARM_PSR_CARRY          0x20000000  /* Carry Bit                              */
+#  define ARM_PSR_OVERFLOW       0x10000000  /* Overflow Bit                           */
+#  define ARM_PSR_IRQ            0x00000080  /* IRQ Bit                                */
+#  define ARM_PSR_FIQ            0x00000040  /* FIQ Bit                                */
+#  define ARM_PSR_THUMB_STATE    0x00000020  /* Thumb/ARM(R) Execution                 */
+#  define ARM_PSR_MODE_MASK      0x0000001F  /* ARM(R) Processor Mode Mask             */
+#else /* ! defined(__ASSEMBLER__) */
+  struct psr_struct {
+      unsigned mode      : 5;
+      unsigned t_bit     : 1;
+      unsigned f_bit     : 1;
+      unsigned i_bit     : 1;
+      unsigned rsv1      : 20;  /* == 0x00000 */
+      unsigned v_bit     : 1;
+      unsigned c_bit     : 1;
+      unsigned z_bit     : 1;
+      unsigned n_bit     : 1;
+  };
+
+  union arm_psr {
+      unsigned long word;
+      struct psr_struct psr;
+  };
+#endif /* __ASSEMBLER__ */
+
+/*
+ * PSR Mode values
+ */
+#define ARM_PSR_MODE_USER      0x00000010  /* User mode                              */
+#define ARM_PSR_MODE_FIQ       0x00000011  /* FIQ mode                               */
+#define ARM_PSR_MODE_IRQ       0x00000012  /* IRQ mode                               */
+#define ARM_PSR_MODE_SVC       0x00000013  /* SVC mode                               */
+#define ARM_PSR_MODE_ABORT     0x00000017  /* ABORT mode                             */
+#define ARM_PSR_MODE_UNDEF     0x0000001B  /* UNDEF mode                             */
+#define ARM_PSR_MODE_SYSTEM    0x0000001F  /* System Mode                            */
+#define ARM_PSR_NUM_MODES      7
+
+/*
+ * Core Exception vectors.
+ */
+#define BSP_CORE_EXC_RESET                     0
+#define BSP_CORE_EXC_UNDEFINED_INSTRUCTION     1
+#define BSP_CORE_EXC_SOFTWARE_INTERRUPT        2
+#define BSP_CORE_EXC_PREFETCH_ABORT            3
+#define BSP_CORE_EXC_DATA_ABORT                4
+#define BSP_CORE_EXC_ADDRESS_ERROR_26_BIT      5
+#define BSP_CORE_EXC_IRQ                       6
+#define BSP_CORE_EXC_FIQ                       7
+#define BSP_MAX_EXCEPTIONS                     8
+#define BSP_CORE_EXC(vec_num)                  (unsigned long*)(vec_num << 2)
+
+#define BREAKPOINT_INSN                        0xE7FFDEFE   /* Illegal inst opcode */
+#define SYSCALL_SWI                            0x00180001
+
+#if defined(__ASSEMBLER__)
+  .macro BREAKPOINT
+         .word BREAKPOINT_INSN
+  .endm
+  .macro SYSCALL
+         swi  IMM(SYSCALL_SWI)
+  .endm
+  .macro __CLI
+         stmfd  sp!, {r0}
+         mrs    r0, cpsr
+         bic    r0, r0, IMM(ARM_PSR_IRQ | ARM_PSR_FIQ)
+         msr    cpsr, r0
+         ldmfd  sp!, {r0}
+  .endm
+  .macro __STI
+         stmfd  sp!, {r0}
+         mrs    r0, cpsr
+         orr    r0, r0, IMM(ARM_PSR_IRQ | ARM_PSR_FIQ)
+         msr    cpsr, r0
+         ldmfd  sp!, {r0}
+  .endm
+
+#  if 0
+  /*
+   * Use this code to verify a particular processing mode
+   */
+       mrs     r0, cpsr
+        and     r0, r0, IMM(ARM_PSR_MODE_MASK)
+        ldr     r1, =ARM_PSR_MODE_IRQ
+        cmps    r0, r1
+0:      bne     0b
+        PORT_TOGGLE_DEBUG
+#  endif /* 0 */
+
+#else /* !defined(__ASSEMBLER__) */
+
+#  define BREAKPOINT() asm volatile(" .word 0xE7FFDEFE")
+#  define SYSCALL()    asm volatile(" swi   %0" : /* No outputs */ : "i" (SYSCALL_SWI))
+#  define __cli()      asm volatile("
+         stmfd  sp!, {r0}
+         mrs    r0, cpsr
+         bic    r0, r0, #0x000000C0
+         msr    cpsr, r0
+         ldmfd  sp!, {r0}")
+#  define __sti()      asm volatile("
+         stmfd  sp!, {r0}
+         mrs    r0, cpsr
+         orr    r0, r0, #0x000000C0
+         msr    cpsr, r0
+         ldmfd  sp!, {r0}")
+#  define __mcr(cp_num, opcode1, Rd, CRn, CRm, opcode2) \
+     asm volatile (" mcr " cp_num  ", " \
+                           opcode1 ", " \
+                           "%0"    ", " \
+                           CRn     ", " \
+                           CRm     ", " \
+                           opcode2 : /* no outputs */ : "r" (Rd))
+#  define __mrc(cp_num, opcode1, Rd, CRn, CRm, opcode2) \
+     asm volatile (" mrc " cp_num  ", " \
+                           opcode1 ", " \
+                           "%0"    ", " \
+                           CRn     ", " \
+                           CRm     ", " \
+                           opcode2 : "=r" (Rd) : /* no inputs */)
+
+  static inline unsigned __get_cpsr(void)
+  {
+      unsigned long retval;
+      asm volatile (" mrs  %0, cpsr" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_cpsr(unsigned val)
+  {
+      asm volatile (" msr  cpsr, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_spsr(void)
+  {
+      unsigned long retval;
+      asm volatile (" mrs  %0, spsr" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_spsr(unsigned val)
+  {
+      asm volatile (" msr  spsr, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_sp(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, sp" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_sp(unsigned val)
+  {
+      asm volatile (" mov  sp, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_fp(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, fp" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_fp(unsigned val)
+  {
+      asm volatile (" mov  fp, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_pc(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, pc" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_pc(unsigned val)
+  {
+      asm volatile (" mov  pc, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_lr(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, lr" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_lr(unsigned val)
+  {
+      asm volatile (" mov  lr, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_r8(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, r8" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_r8(unsigned val)
+  {
+      asm volatile (" mov  r8, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_r9(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, r9" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_r9(unsigned val)
+  {
+      asm volatile (" mov  r9, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_r10(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, r10" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_r10(unsigned val)
+  {
+      asm volatile (" mov  r10, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_r11(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, r11" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_r11(unsigned val)
+  {
+      asm volatile (" mov  r11, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+  static inline unsigned __get_r12(void)
+  {
+      unsigned long retval;
+      asm volatile (" mov  %0, r12" : "=r" (retval) : /* no inputs */  );
+      return retval;
+  }
+
+  static inline void __set_r12(unsigned val)
+  {
+      asm volatile (" mov  r12, %0" : /* no outputs */ : "r" (val)  );
+  }
+
+#endif /* defined(__ASSEMBLER__) */
+
+#define GDB_BREAKPOINT_VECTOR BSP_CORE_EXC_UNDEFINED_INSTRUCTION
+#define GDB_SYSCALL_VECTOR    BSP_CORE_EXC_SOFTWARE_INTERRUPT
+
+#define ARM_INST_SIZE            sizeof(unsigned long)
+#define GDB_BREAKPOINT_INST_SIZE ARM_INST_SIZE
+
+#ifdef __CPU_LH77790A__
+#  include <bsp/lh77790a.h>
+#endif /* __CPU_LH77790A__ */
+
+#if !defined(__ASSEMBLER__)
+/*
+ * Define the CPU specific data
+ */
+#ifdef __CPU_LH77790A__
+  typedef struct {
+      unsigned char lh77790a_port_control_shadow;
+  } arm_cpu_data;
+#endif /* __CPU_LH77790A__ */
+#endif /* !defined(__ASSEMBLER__) */
+
+#ifdef __CPU_SA110__
+#include <bsp/sa-110.h>
+#endif /* __CPU_SA110__ */
+
+#ifdef __CPU_SA1100__
+#include <bsp/sa-1100.h>
+#endif /* __CPU_SA110__ */
+
+#ifdef __CPU_710T__
+#include <bsp/arm710t.h>
+#endif /* __CPU_710T__ */
+
+#ifdef MMU
+/*
+ * ARM(R) MMU Definitions
+ */
+
+#ifndef __ASSEMBLER__
+extern void *page1;
+#endif /* __ASSEMBLER__ */
+
+/*
+ * ARM(R) Cache and MMU Control Registers
+ *
+ * Accessed through coprocessor instructions.
+ */
+#ifdef __ASSEMBLER__
+#  define ARM_CACHE_COPROCESSOR_NUM             p15
+#  define ARM_COPROCESSOR_OPCODE_DONT_CARE      0x0
+#  define ARM_COPROCESSOR_RM_DONT_CARE          c0
+#else /* __ASSEMBLER__ */
+#  define ARM_CACHE_COPROCESSOR_NUM             "p15"
+#  define ARM_COPROCESSOR_OPCODE_DONT_CARE      "0x0"
+#  define ARM_COPROCESSOR_RM_DONT_CARE          "c0"
+#endif /* __ASSEMBLER__ */
+
+#ifdef __ASSEMBLER__
+#  define ARM_ID_REGISTER                        c0
+#  define ARM_CONTROL_REGISTER                   c1
+#  define ARM_TRANSLATION_TABLE_BASE_REGISTER    c2
+#  define ARM_DOMAIN_ACCESS_CONTROL_REGISTER     c3
+#  define ARM_FAULT_STATUS_REGISTER              c5
+#  define ARM_FAULT_ADDRESS_REGISTER             c6
+#  define ARM_CACHE_OPERATIONS_REGISTER          c7
+#  define ARM_TLB_OPERATIONS_REGISTER            c8
+#  define ARM_READ_BUFFER_OPERATIONS_REGISTER    c9
+#else /* __ASSEMBLER__ */
+#  define ARM_ID_REGISTER                        "c0"
+#  define ARM_CONTROL_REGISTER                   "c1"
+#  define ARM_TRANSLATION_TABLE_BASE_REGISTER    "c2"
+#  define ARM_DOMAIN_ACCESS_CONTROL_REGISTER     "c3"
+#  define ARM_FAULT_STATUS_REGISTER              "c5"
+#  define ARM_FAULT_ADDRESS_REGISTER             "c6"
+#  define ARM_CACHE_OPERATIONS_REGISTER          "c7"
+#  define ARM_TLB_OPERATIONS_REGISTER            "c8"
+#  define ARM_READ_BUFFER_OPERATIONS_REGISTER    "c9"
+#endif /* __ASSEMBLER__ */
+
+/*
+ * SA-1100 Cache and MMU ID Register value
+ */
+#define ARM_ID_MASK                              0xFFFFFFF0
+#define ARM_ID_VALUE                             0x4401a110
+
+/*
+ * SA-1100 Cache Control Register Bit Fields and Masks
+ */
+#define ARM_MMU_DISABLED                         0x00000000
+#define ARM_MMU_ENABLED                          0x00000001
+#define ARM_MMU_MASK                             0x00000001
+#define ARM_ADDRESS_FAULT_DISABLED               0x00000000
+#define ARM_ADDRESS_FAULT_ENABLED                0x00000002
+#define ARM_ADDRESS_FAULT_MASK                   0x00000002
+#define ARM_DATA_CACHE_DISABLED                  0x00000000
+#define ARM_DATA_CACHE_ENABLED                   0x00000004
+#define ARM_DATA_CACHE_MASK                      0x00000004
+#define ARM_WRITE_BUFFER_DISABLED                0x00000000
+#define ARM_WRITE_BUFFER_ENABLED                 0x00000008
+#define ARM_WRITE_BUFFER_MASK                    0x00000008
+#define ARM_LITTLE_ENDIAN                        0x00000000
+#define ARM_BIG_ENDIAN                           0x00000080
+#define ARM_ACCESS_CHECKS_NONE                   0x00000000
+#define ARM_ACCESS_CHECKS_SYSTEM                 0x00000100
+#define ARM_ACCESS_CHECKS_ROM                    0x00000200
+#define ARM_INSTRUCTION_CACHE_DISABLED           0x00000000
+#define ARM_INSTRUCTION_CACHE_ENABLED            0x00001000
+#define ARM_INSTRUCTION_CACHE_MASK               0x00001000
+#define ARM_VIRTUAL_IVR_BASE_00000000            0x00000000
+#define ARM_VIRTUAL_IVR_BASE_FFFF0000            0x00002000
+#define ARM_CONTROL_SBZ_MASK                     0x00001FFF
+
+/*
+ * SA-1100 Translation Table Base Bit Masks
+ */
+#define ARM_TRANSLATION_TABLE_MASK               0xFFFFC000
+
+/*
+ * SA-1100 Domain Access Control Bit Masks
+ */
+#define ARM_DOMAIN_0_MASK                        0x00000003
+#define ARM_DOMAIN_1_MASK                        0x0000000C
+#define ARM_DOMAIN_2_MASK                        0x00000030
+#define ARM_DOMAIN_3_MASK                        0x000000C0
+#define ARM_DOMAIN_4_MASK                        0x00000300
+#define ARM_DOMAIN_5_MASK                        0x00000C00
+#define ARM_DOMAIN_6_MASK                        0x00003000
+#define ARM_DOMAIN_7_MASK                        0x0000C000
+#define ARM_DOMAIN_8_MASK                        0x00030000
+#define ARM_DOMAIN_9_MASK                        0x000C0000
+#define ARM_DOMAIN_10_MASK                       0x00300000
+#define ARM_DOMAIN_11_MASK                       0x00C00000
+#define ARM_DOMAIN_12_MASK                       0x03000000
+#define ARM_DOMAIN_13_MASK                       0x0C000000
+#define ARM_DOMAIN_14_MASK                       0x30000000
+#define ARM_DOMAIN_15_MASK                       0xC0000000
+
+#define ARM_ACCESS_TYPE_NO_ACCESS(domain_num)    (0x0 << (domain_num))
+#define ARM_ACCESS_TYPE_CLIENT(domain_num)       (0x1 << (domain_num))
+#define ARM_ACCESS_TYPE_MANAGER(domain_num)      (0x3 << (domain_num))
+
+/*
+ * SA-1100 Fault Status Bit Masks
+ */
+#define ARM_FAULT_STATUS_MASK                    0x0000000F
+#define ARM_DOMAIN_MASK                          0x000000F0
+#define ARM_DATA_BREAKPOINT_MASK                 0x00000200
+
+/*
+ * SA-1100 Cache Control Operations Definitions
+ */
+#ifdef __ASSEMBLER__
+#  define ARM_FLUSH_CACHE_INST_DATA_OPCODE       0x0
+#  define ARM_FLUSH_CACHE_INST_DATA_RM           c7
+#  define ARM_FLUSH_CACHE_INST_OPCODE            0x0
+#  define ARM_FLUSH_CACHE_INST_RM                c5
+#  define ARM_FLUSH_CACHE_DATA_OPCODE            0x0
+#  define ARM_FLUSH_CACHE_DATA_RM                c6
+#  define ARM_FLUSH_CACHE_DATA_SINGLE_OPCODE     0x1
+#  define ARM_FLUSH_CACHE_DATA_SINGLE_RM         c6
+#  define ARM_CLEAN_CACHE_DATA_ENTRY_OPCODE      0x1
+#  define ARM_CLEAN_CACHE_DATA_ENTRY_RM          c10
+#  define ARM_DRAIN_CACHE_WRITE_BUFFER_OPCODE    0x4
+#  define ARM_DRAIN_CACHE_WRITE_BUFFER_RM        c10
+#else /* __ASSEMBLER__ */                        
+#  define ARM_FLUSH_CACHE_INST_DATA_OPCODE       "0x0"
+#  define ARM_FLUSH_CACHE_INST_DATA_RM           "c7"
+#  define ARM_FLUSH_CACHE_INST_OPCODE            "0x0"
+#  define ARM_FLUSH_CACHE_INST_RM                "c5"
+#  define ARM_FLUSH_CACHE_DATA_OPCODE            "0x0"
+#  define ARM_FLUSH_CACHE_DATA_RM                "c6"
+#  define ARM_FLUSH_CACHE_DATA_SINGLE_OPCODE     "0x1"
+#  define ARM_FLUSH_CACHE_DATA_SINGLE_RM         "c6"
+#  define ARM_CLEAN_CACHE_DATA_ENTRY_OPCODE      "0x1"
+#  define ARM_CLEAN_CACHE_DATA_ENTRY_RM          "c10"
+#  define ARM_DRAIN_CACHE_WRITE_BUFFER_OPCODE    "0x4"
+#  define ARM_DRAIN_CACHE_WRITE_BUFFER_RM        "c10"
+#endif /* __ASSEMBLER__ */
+
+/*                                               
+ * SA-1100 TLB Operations Definitions             
+ */                                              
+#ifdef __ASSEMBLER__
+#  define ARM_FLUSH_INST_DATA_TLB_OPCODE         0x0
+#  define ARM_FLUSH_INST_DATA_TLB_RM             c7
+#  define ARM_FLUSH_INST_TLB_OPCODE              0x0
+#  define ARM_FLUSH_INST_TLB_RM                  c5
+#  define ARM_FLUSH_DATA_TLB_OPCODE              0x0
+#  define ARM_FLUSH_DATA_TLB_RM                  c6
+#  define ARM_FLUSH_DATA_ENTRY_TLB_OPCODE        0x1
+#  define ARM_FLUSH_DATA_ENTRY_TLB_RM            c6
+#else /* __ASSEMBLER__ */
+#  define ARM_FLUSH_INST_DATA_TLB_OPCODE         "0x0"
+#  define ARM_FLUSH_INST_DATA_TLB_RM             "c7"
+#  define ARM_FLUSH_INST_TLB_OPCODE              "0x0"
+#  define ARM_FLUSH_INST_TLB_RM                  "c5"
+#  define ARM_FLUSH_DATA_TLB_OPCODE              "0x0"
+#  define ARM_FLUSH_DATA_TLB_RM                  "c6"
+#  define ARM_FLUSH_DATA_ENTRY_TLB_OPCODE        "0x1"
+#  define ARM_FLUSH_DATA_ENTRY_TLB_RM            "c6"
+#endif /* __ASSEMBLER__ */
+
+/*
+ * SA-1100 Read-Buffer Operations Definitions
+ */
+#ifdef __ASSEMBLER__
+#  define ARM_FLUSH_ALL_BUFFERS_OPCODE           0x0
+#  define ARM_FLUSH_ALL_BUFFERS_RM               c0
+#  define ARM_FLUSH_BUFFER_0_OPCODE              0x1
+#  define ARM_FLUSH_BUFFER_0_RM                  c0
+#  define ARM_FLUSH_BUFFER_1_OPCODE              0x1
+#  define ARM_FLUSH_BUFFER_1_RM                  c1
+#  define ARM_FLUSH_BUFFER_2_OPCODE              0x1
+#  define ARM_FLUSH_BUFFER_2_RM                  c2
+#  define ARM_FLUSH_BUFFER_3_OPCODE              0x1
+#  define ARM_FLUSH_BUFFER_3_RM                  c3
+#  define ARM_LOAD_BUFFER_0_1_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_0_1_WORD_RM            c0
+#  define ARM_LOAD_BUFFER_0_4_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_0_4_WORD_RM            c4
+#  define ARM_LOAD_BUFFER_0_8_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_0_8_WORD_RM            c8
+#  define ARM_LOAD_BUFFER_1_1_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_1_1_WORD_RM            c1
+#  define ARM_LOAD_BUFFER_1_4_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_1_4_WORD_RM            c5
+#  define ARM_LOAD_BUFFER_1_8_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_1_8_WORD_RM            c9
+#  define ARM_LOAD_BUFFER_2_1_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_2_1_WORD_RM            c2
+#  define ARM_LOAD_BUFFER_2_4_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_2_4_WORD_RM            c6
+#  define ARM_LOAD_BUFFER_2_8_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_2_8_WORD_RM            cA
+#  define ARM_LOAD_BUFFER_3_1_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_3_1_WORD_RM            c3
+#  define ARM_LOAD_BUFFER_3_4_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_3_4_WORD_RM            c7
+#  define ARM_LOAD_BUFFER_3_8_WORD_OPCODE        0x2
+#  define ARM_LOAD_BUFFER_3_8_WORD_RM            cB
+#  define ARM_DISABLE_USER_MCR_ACCESS_OPCODE     0x4
+#  define ARM_DISABLE_USER_MCR_ACCESS_RM         c0
+#  define ARM_ENABLE_USER_MCR_ACCESS_OPCODE      0x5
+#  define ARM_ENABLE_USER_MCR_ACCESS_RM          c0
+#else /* __ASSEMBLER__ */
+#  define ARM_FLUSH_ALL_BUFFERS_OPCODE           "0x0"
+#  define ARM_FLUSH_ALL_BUFFERS_RM               "c0"
+#  define ARM_FLUSH_BUFFER_0_OPCODE              "0x1"
+#  define ARM_FLUSH_BUFFER_0_RM                  "c0"
+#  define ARM_FLUSH_BUFFER_1_OPCODE              "0x1"
+#  define ARM_FLUSH_BUFFER_1_RM                  "c1"
+#  define ARM_FLUSH_BUFFER_2_OPCODE              "0x1"
+#  define ARM_FLUSH_BUFFER_2_RM                  "c2"
+#  define ARM_FLUSH_BUFFER_3_OPCODE              "0x1"
+#  define ARM_FLUSH_BUFFER_3_RM                  "c3"
+#  define ARM_LOAD_BUFFER_0_1_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_0_1_WORD_RM            "c0"
+#  define ARM_LOAD_BUFFER_0_4_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_0_4_WORD_RM            "c4"
+#  define ARM_LOAD_BUFFER_0_8_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_0_8_WORD_RM            "c8"
+#  define ARM_LOAD_BUFFER_1_1_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_1_1_WORD_RM            "c1"
+#  define ARM_LOAD_BUFFER_1_4_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_1_4_WORD_RM            "c5"
+#  define ARM_LOAD_BUFFER_1_8_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_1_8_WORD_RM            "c9"
+#  define ARM_LOAD_BUFFER_2_1_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_2_1_WORD_RM            "c2"
+#  define ARM_LOAD_BUFFER_2_4_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_2_4_WORD_RM            "c6"
+#  define ARM_LOAD_BUFFER_2_8_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_2_8_WORD_RM            "cA"
+#  define ARM_LOAD_BUFFER_3_1_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_3_1_WORD_RM            "c3"
+#  define ARM_LOAD_BUFFER_3_4_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_3_4_WORD_RM            "c7"
+#  define ARM_LOAD_BUFFER_3_8_WORD_OPCODE        "0x2"
+#  define ARM_LOAD_BUFFER_3_8_WORD_RM            "cB"
+#  define ARM_DISABLE_USER_MCR_ACCESS_OPCODE     "0x4"
+#  define ARM_DISABLE_USER_MCR_ACCESS_RM         "c0"
+#  define ARM_ENABLE_USER_MCR_ACCESS_OPCODE      "0x5"
+#  define ARM_ENABLE_USER_MCR_ACCESS_RM          "c0"
+#endif /* __ASSEMBLER__ */
+
+/*
+ * ARM(R) First Level Descriptor Format Definitions
+ */
+#ifndef __ASSEMBLER__
+struct ARM_MMU_FIRST_LEVEL_FAULT {
+    int id : 2;
+    int sbz : 30;
+};
+#define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0
+
+struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE {
+    int id : 2;
+    int imp : 2;
+    int domain : 4;
+    int sbz : 1;
+    int base_address : 23;
+};
+#define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1
+
+struct ARM_MMU_FIRST_LEVEL_SECTION {
+    int id : 2;
+    int b : 1;
+    int c : 1;
+    int imp : 1;
+    int domain : 4;
+    int sbz0 : 1;
+    int ap : 2;
+    int sbz1 : 8;
+    int base_address : 12;
+};
+#define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2
+
+struct ARM_MMU_FIRST_LEVEL_RESERVED {
+    int id : 2;
+    int sbz : 30;
+};
+#define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3
+
+#define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \
+            (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2))
+#define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base, cacheable, bufferable, perm) \
+    {                                                                                     \
+        register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc;                               \
+                                                                                          \
+        desc.word = 0;                                                                    \
+        desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID;                                 \
+        desc.section.domain = 0;                                                          \
+        desc.section.c = (cacheable);                                                     \
+        desc.section.b = (bufferable);                                                    \
+        desc.section.ap = (perm);                                                         \
+        desc.section.base_address = (actual_base);                                        \
+        *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) = desc.word;    \
+    }
+
+union ARM_MMU_FIRST_LEVEL_DESCRIPTOR {
+    unsigned long word;
+    struct ARM_MMU_FIRST_LEVEL_FAULT fault;
+    struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE page_table;
+    struct ARM_MMU_FIRST_LEVEL_SECTION section;
+    struct ARM_MMU_FIRST_LEVEL_RESERVED reserved;
+};
+
+#endif /* __ASSEMBLER__ */
+
+#define ARM_UNCACHEABLE                         0
+#define ARM_CACHEABLE                           1
+#define ARM_UNBUFFERABLE                        0
+#define ARM_BUFFERABLE                          1
+
+#define ARM_ACCESS_PERM_NONE_NONE               0
+#define ARM_ACCESS_PERM_RO_NONE                 0
+#define ARM_ACCESS_PERM_RO_RO                   0
+#define ARM_ACCESS_PERM_RW_NONE                 1
+#define ARM_ACCESS_PERM_RW_RO                   2
+#define ARM_ACCESS_PERM_RW_RW                   3
+
+#define ARM_SECTION_SIZE                        SZ_1M
+#define ARM_SMALL_PAGE_SIZE                     SZ_4K
+#define ARM_LARGE_PAGE_SIZE                     SZ_64K
+
+#define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE         SZ_16K
+#define ARM_SECOND_LEVEL_PAGE_TABLE_SIZE        SZ_1K
+
+#endif /* MMU */
+
+#endif // __ARM_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/arm/cpu_info.h b/packages/cygmon/v2_0/misc/arm/cpu_info.h
new file mode 100644 (file)
index 0000000..e7fff00
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef __ARM_CPU_INFO_H__
+#define __ARM_CPU_INFO_H__
+//==========================================================================
+//
+//      cpu_info.h
+//
+//      Architecture information for ARM processors
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  ARM is a Registered Trademark of Advanced RISC Machines
+//               Limited.
+//               Other Brands and Trademarks are the property of their
+//               respective owners.               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#define IS_ARM 1
+
+#ifndef __CYGMON_TYPES
+#define __CYGMON_TYPES
+typedef unsigned int uint32;
+typedef int          int32;
+#endif // __CYGMON_TYPES
+
+
+/* Temporary as long a multiple protypes are copied in multiple files */
+/* This variation does NOT clone the prototypes */
+#define NO_MALLOC 1
+#define MAX_NUM_BP 32
+#define MAX_HIST_ENTS 10
+
+/* big enuf to store a trap in the BP structure */
+
+#define BP_INST_T_DEFINED 1 
+typedef unsigned long bp_inst_t ;
+
+#define MEM_ADDR_DEFINED 1 
+typedef struct mem_addr {
+  unsigned long addr;
+} mem_addr_t ;
+
+#ifndef TARGET_REGISTER_T_DEFINED
+#define TARGET_REGISTER_T_DEFINED
+typedef unsigned long target_register_t;
+#endif
+
+#if defined(__ARMEB__)
+#define PRINT_INSN print_insn_big_arm
+#else
+#define PRINT_INSN print_insn_little_arm
+#endif
+
+#define OTHERNAMES_CMD arm_othernames
+extern void arm_othernames (void);
+
+#undef BFD_MACH
+#define BFD_MACH 0
+
+#endif // __ARM_CPU_INFO_H__
diff --git a/packages/cygmon/v2_0/misc/board.h b/packages/cygmon/v2_0/misc/board.h
new file mode 100644 (file)
index 0000000..f843f08
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef __CYGMON_BOARD_H__
+#define __CYGMON_BOARD_H__
+//==========================================================================
+//
+//      board.h
+//
+//      Cygmon board/platform configuration file
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+// Hardware/platform/configuration specifics
+
+#include <pkgconf/hal.h>
+#include <pkgconf/cygmon.h>
+
+#ifdef CYGPKG_HAL_ARM
+#include "arm/board.h"
+#endif
+
+#ifdef CYGPKG_HAL_MIPS
+#include "mips/board.h"
+#endif
+
+#ifdef CYGPKG_HAL_MN10300
+#include "mn10300/board.h"
+#endif
+
+#endif //  __CYGMON_BOARD_H__
diff --git a/packages/cygmon/v2_0/misc/bplist-dynamic.c b/packages/cygmon/v2_0/misc/bplist-dynamic.c
new file mode 100644 (file)
index 0000000..1c9a864
--- /dev/null
@@ -0,0 +1,234 @@
+//==========================================================================
+//
+//      bplist-dynamic.c
+//
+//      Breakpoint list using dynamic memory.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Breakpoint list using dynamic memory.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include "board.h"
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+
+#include <stdlib.h>
+
+#ifndef NO_MALLOC
+#ifndef NO_MALLOC_H
+#include "malloc.h"
+#else
+void free ();
+char *malloc ();
+#endif
+#endif
+
+#ifdef __ECOS__
+#include <cyg/hal/plf_stub.h>
+#endif /* __ECOS__ */
+
+/*
+ * A simple target breakpoint list using malloc.
+ * To use this package, you must define TRAP_SIZE to be the size
+ * in bytes of a trap instruction (max if there's more than one),
+ * and export a char array called _breakinst that contains a
+ * breakpoint trap.  This package will copy trap instructions
+ * from _breakinst into the breakpoint locations.
+ */
+
+static struct breakpoint_list {
+  target_register_t  addr;
+  char old_contents [TRAP_SIZE];
+  struct breakpoint_list *next;
+  char in_memory;
+} *breakpoint_list = NULL;
+
+#ifdef NO_MALLOC
+static struct breakpoint_list bp_list [MAX_BP_NUM];
+static struct breakpoint_list *free_bp_list = NULL;
+static int curr_bp_num = 0;
+#endif
+
+#ifndef BREAKINST_DEFINED
+#define BREAKINST_DEFINED
+extern unsigned char _breakinst[];
+#endif
+
+int
+__set_breakpoint (target_register_t addr)
+{
+  struct breakpoint_list **addent = &breakpoint_list;
+  struct breakpoint_list *l = breakpoint_list;
+  struct breakpoint_list *newent;
+
+  while (l != NULL && l->addr < addr)
+    {
+      addent = &l->next;
+      l =  l->next;
+    }
+
+  if (l != NULL && l->addr == addr)
+    return 2;
+
+#ifdef NO_MALLOC
+  if (free_bp_list != NULL)
+    {
+      newent = free_bp_list;
+      free_bp_list = free_bp_list->next;
+    }
+  else
+    {
+      if (curr_bp_num < MAX_BP_NUM)
+       {
+         newent = &bp_list[curr_bp_num++];
+       }
+      else
+       {
+         return 1;
+       }
+    }
+#else
+  newent = (struct breakpoint_list *) malloc (sizeof (struct breakpoint_list));
+#endif
+  newent->addr = addr;
+  newent->in_memory = 0;
+  newent->next = l;
+  *addent = newent;
+  return 0;
+}
+
+int
+__remove_breakpoint (target_register_t addr)
+{
+  struct breakpoint_list *l = breakpoint_list;
+  struct breakpoint_list *prev = NULL;
+
+  while (l != NULL && l->addr < addr)
+    {
+      prev = l;
+      l = l->next;
+    }
+
+  if (l == NULL)
+    return 1;
+
+  if (l->in_memory)
+    {
+      __write_mem_safe (&l->old_contents[0],
+                       (void*)l->addr,
+                       sizeof (l->old_contents));
+    }
+
+  if (prev == NULL)
+    breakpoint_list = l->next;
+  else
+    prev->next = l->next;
+
+#ifdef NO_MALLOC
+  l->next = free_bp_list;
+  free_bp_list = l;
+#else
+  free (l);
+#endif
+  return 0;
+}
+
+#include <cyg/hal/generic-stub.h>
+#include <cyg/hal/hal_stub.h>
+void
+__cygmon_install_breakpoints (void)
+{
+  struct breakpoint_list *l = breakpoint_list;
+
+  while (l != NULL)
+    {
+      if (! l->in_memory)
+       {
+         int len = sizeof (l->old_contents);
+
+         if (__read_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
+           {
+#ifdef WRITE_MEM_IS_MEMCPY
+             if (__write_mem_safe (_breakinst, (void*)l->addr, len) == (void*)l->addr)
+#else
+             if (__write_mem_safe (_breakinst, (void*)l->addr, len) == len)
+#endif
+               {
+                 l->in_memory = 1;
+               }
+           }
+       }
+      l = l->next;
+    }
+  flush_i_cache ();
+}
+
+void
+__cygmon_clear_breakpoints (void)
+{
+  struct breakpoint_list *l = breakpoint_list;
+
+  while (l != NULL)
+    {
+      if (l->in_memory)
+       {
+         int len = sizeof (l->old_contents);
+
+#ifdef WRITE_MEM_IS_MEMCPY
+      if (__write_mem_safe (_breakinst, (void*)l->addr, len) == (void*)l->addr)
+#else
+         if (__write_mem_safe (&l->old_contents[0], (void*)l->addr, len) == len)
+#endif
+           {
+             l->in_memory = 0;
+           }
+       }
+      l = l->next;
+    }
+  flush_i_cache ();
+}
+
+#endif // USE_ECOS_HAL_BREAKPOINTS
diff --git a/packages/cygmon/v2_0/misc/breakpoints.c b/packages/cygmon/v2_0/misc/breakpoints.c
new file mode 100644 (file)
index 0000000..0a489d3
--- /dev/null
@@ -0,0 +1,220 @@
+//==========================================================================
+//
+//      breakpoints.c
+//
+//      Support aribtrary set of breakpoints.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include "board.h"
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+
+#include <stdlib.h>
+#ifdef HAVE_BSP
+#include <bsp/bsp.h>
+#include <bsp/cpu.h>
+#endif
+
+#include "monitor.h"
+#include "tservice.h"
+#include "stub-tservice.h"
+
+#include "fmt_util.h"
+
+
+static struct bp *last_bp_ptr;
+static struct bp *first_bp_ptr;
+
+#ifdef NO_MALLOC
+static struct bp *free_bp_list;
+static struct bp bp_list[MAX_NUM_BP];
+static int       curr_bp_num;
+#endif
+
+int
+add_mon_breakpoint (mem_addr_t location)
+{
+  struct bp *ptr;
+  struct bp *new_bp_ptr;
+
+  for (ptr = first_bp_ptr; ptr != NULL; ptr = ptr->next)
+    {
+      if (MEM_ADDR_EQ_P (ptr->address, location))
+       return 1;
+    }
+#ifdef NO_MALLOC
+  if (free_bp_list != NULL)
+    {
+      new_bp_ptr = free_bp_list;
+      free_bp_list = new_bp_ptr->next;
+    }
+  else
+    {
+      if (curr_bp_num < MAX_NUM_BP)
+       {
+         new_bp_ptr = &bp_list[curr_bp_num++];
+       }
+      else
+       {
+         xprintf ("No more breakpoints\n");
+         return 1;
+       }
+    }
+#else
+  new_bp_ptr = (struct bp *)malloc (sizeof (struct bp));
+#endif
+
+  if (first_bp_ptr == NULL)
+    {
+      first_bp_ptr = new_bp_ptr;
+    }
+  else
+    {
+      last_bp_ptr->next = new_bp_ptr;
+    }
+  last_bp_ptr = new_bp_ptr;
+
+  last_bp_ptr->next = NULL;
+  last_bp_ptr->address = location;
+  last_bp_ptr->in_memory = 0;
+  return 0;
+}
+
+
+void
+install_breakpoints (void)
+{
+  struct bp *ptr = first_bp_ptr;
+  while (ptr != NULL)
+    {
+      set_breakpoint (ptr);
+      ptr = ptr->next;
+    }
+}
+
+
+void
+clear_breakpoints (void)
+{
+  struct bp *ptr = first_bp_ptr;
+
+  while (ptr != NULL)
+    {
+      clear_breakpoint (ptr);
+      ptr = ptr->next;
+    }
+}
+
+int
+show_breakpoints (void)
+{
+  struct bp *ptr;
+
+  for (ptr = first_bp_ptr; ptr != NULL; ptr = ptr->next)
+    {
+      char buf[20];
+
+      addr2str (&ptr->address, buf);
+      xprintf ("%s\n", buf);
+    }
+  
+  return 0;
+}
+
+
+
+int 
+clear_mon_breakpoint (mem_addr_t location)
+{
+  int error = 0;
+  struct bp *ptr = first_bp_ptr;
+  struct bp *prev_ptr = NULL;
+
+  /* Scan the list looking for the address to clear */
+  while (ptr != NULL && !MEM_ADDR_EQ_P (ptr->address, location))
+    {
+      /* keep a pointer one behind the current position */
+      prev_ptr = ptr;
+      ptr = ptr->next;
+    }
+  if (ptr == NULL)
+    {
+      xprintf ("That address has no breakpoint on it.\n");
+      error = 1;
+    }
+  else
+    {
+      /* Just in case it's still in memory. */
+      clear_breakpoint (ptr);
+
+      /* now we'll point the previous bp->next at the one after the one 
+        we're deleting, unless there is no previous bp. */
+      if (prev_ptr != NULL)
+       {
+         prev_ptr->next = ptr->next;
+       }
+
+      if (first_bp_ptr == ptr)
+       first_bp_ptr = ptr->next;
+
+      if (last_bp_ptr == ptr)
+       last_bp_ptr = prev_ptr;
+
+      /* eliminate the offending bp struct */
+#ifdef NO_MALLOC
+      ptr->next = free_bp_list;
+      free_bp_list = ptr;
+#else
+      free (ptr);
+#endif
+    }
+  return error;
+}      
+
+#endif /* USE_ECOS_HAL_BREAKPOINTS */
diff --git a/packages/cygmon/v2_0/misc/bsp/arm/gdb-cpu.c b/packages/cygmon/v2_0/misc/bsp/arm/gdb-cpu.c
new file mode 100644 (file)
index 0000000..0030982
--- /dev/null
@@ -0,0 +1,208 @@
+//==========================================================================
+//
+//      gdb-cpu.c
+//
+//      CPU specific support for GDB stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      CPU specific support for GDB stub.
+// Description:  ARM is a Registered Trademark of Advanced RISC Machines
+//               Limited.
+//               Other Brands and Trademarks are the property of their
+//               respective owners.
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <bsp/cpu.h>
+#include <bsp/bsp.h>
+#include "insn.h"
+#include "gdb.h"
+
+/*
+ * Return byte offset within the saved register area of the
+ * given register.
+ */
+int
+bsp_regbyte(int regno)
+{
+    switch(regno)
+    {
+    case REG_R0:   return (int)&(((ex_regs_t*)0)->_r0);   break;
+    case REG_R1:   return (int)&(((ex_regs_t*)0)->_r1);   break;
+    case REG_R2:   return (int)&(((ex_regs_t*)0)->_r2);   break;
+    case REG_R3:   return (int)&(((ex_regs_t*)0)->_r3);   break;
+    case REG_R4:   return (int)&(((ex_regs_t*)0)->_r4);   break;
+    case REG_R5:   return (int)&(((ex_regs_t*)0)->_r5);   break;
+    case REG_R6:   return (int)&(((ex_regs_t*)0)->_r6);   break;
+    case REG_R7:   return (int)&(((ex_regs_t*)0)->_r7);   break;
+    case REG_R8:   return (int)&(((ex_regs_t*)0)->_r8);   break;
+    case REG_R9:   return (int)&(((ex_regs_t*)0)->_r9);   break;
+    case REG_R10:  return (int)&(((ex_regs_t*)0)->_r10);  break;
+    case REG_R11:  return (int)&(((ex_regs_t*)0)->_r11);  break;
+    case REG_R12:  return (int)&(((ex_regs_t*)0)->_r12);  break;
+    case REG_SP:   return (int)&(((ex_regs_t*)0)->_sp);   break;
+    case REG_LR:   return (int)&(((ex_regs_t*)0)->_lr);   break;
+    case REG_PC:   return (int)&(((ex_regs_t*)0)->_pc);   break;
+
+#ifndef __ECOS__
+    case REG_F0:   return (int)&(((ex_regs_t*)0)->_f0);   break;
+    case REG_F1:   return (int)&(((ex_regs_t*)0)->_f1);   break;
+    case REG_F2:   return (int)&(((ex_regs_t*)0)->_f2);   break;
+    case REG_F3:   return (int)&(((ex_regs_t*)0)->_f3);   break;
+    case REG_F4:   return (int)&(((ex_regs_t*)0)->_f4);   break;
+    case REG_F5:   return (int)&(((ex_regs_t*)0)->_f5);   break;
+    case REG_F6:   return (int)&(((ex_regs_t*)0)->_f6);   break;
+    case REG_F7:   return (int)&(((ex_regs_t*)0)->_f7);   break;
+    case REG_FPS:  return (int)&(((ex_regs_t*)0)->_fps);  break;
+#endif
+
+    case REG_CPSR: return (int)&(((ex_regs_t*)0)->_cpsr);  break;
+    case REG_SPSVC: return (int)&(((ex_regs_t*)0)->_spsvc);  break;
+    }
+
+    return 0;
+}
+
+
+/*
+ * Return size in bytes of given register.
+ */
+int
+bsp_regsize(int regno)
+{
+    switch(regno)
+    {
+    case REG_R0:   return (sizeof (((ex_regs_t*)0)->_r0));   break;
+    case REG_R1:   return (sizeof (((ex_regs_t*)0)->_r1));   break;
+    case REG_R2:   return (sizeof (((ex_regs_t*)0)->_r2));   break;
+    case REG_R3:   return (sizeof (((ex_regs_t*)0)->_r3));   break;
+    case REG_R4:   return (sizeof (((ex_regs_t*)0)->_r4));   break;
+    case REG_R5:   return (sizeof (((ex_regs_t*)0)->_r5));   break;
+    case REG_R6:   return (sizeof (((ex_regs_t*)0)->_r6));   break;
+    case REG_R7:   return (sizeof (((ex_regs_t*)0)->_r7));   break;
+    case REG_R8:   return (sizeof (((ex_regs_t*)0)->_r8));   break;
+    case REG_R9:   return (sizeof (((ex_regs_t*)0)->_r9));   break;
+    case REG_R10:  return (sizeof (((ex_regs_t*)0)->_r10));  break;
+    case REG_R11:  return (sizeof (((ex_regs_t*)0)->_r11));  break;
+    case REG_R12:  return (sizeof (((ex_regs_t*)0)->_r12));  break;
+    case REG_SP:   return (sizeof (((ex_regs_t*)0)->_sp));   break;
+    case REG_LR:   return (sizeof (((ex_regs_t*)0)->_lr));   break;
+    case REG_PC:   return (sizeof (((ex_regs_t*)0)->_pc));   break;
+
+#ifndef __ECOS__
+    case REG_F0:   return (sizeof (((ex_regs_t*)0)->_f0));   break;
+    case REG_F1:   return (sizeof (((ex_regs_t*)0)->_f1));   break;
+    case REG_F2:   return (sizeof (((ex_regs_t*)0)->_f2));   break;
+    case REG_F3:   return (sizeof (((ex_regs_t*)0)->_f3));   break;
+    case REG_F4:   return (sizeof (((ex_regs_t*)0)->_f4));   break;
+    case REG_F5:   return (sizeof (((ex_regs_t*)0)->_f5));   break;
+    case REG_F6:   return (sizeof (((ex_regs_t*)0)->_f6));   break;
+    case REG_F7:   return (sizeof (((ex_regs_t*)0)->_f7));   break;
+    case REG_FPS:  return (sizeof (((ex_regs_t*)0)->_fps));  break;
+#endif
+                                                         
+    case REG_CPSR: return (sizeof (((ex_regs_t*)0)->_cpsr)); break;
+    case REG_SPSVC: return (sizeof (((ex_regs_t*)0)->_spsvc)); break;
+    }
+
+    return 0;
+}
+
+
+/*
+ *  Given an exception number and a pointer to saved registers,
+ *  return a GDB signal value.
+ */
+int
+bsp_get_signal(int exc_nr, void *saved_regs)
+{
+  int sig = TARGET_SIGNAL_TRAP;
+  ex_regs_t *regs = (ex_regs_t *)saved_regs;
+
+  switch (exc_nr) {
+  case BSP_CORE_EXC_UNDEFINED_INSTRUCTION:
+  {
+      union arm_insn inst;
+      if (bsp_memory_read((void *)regs->_pc, 0, ARM_INST_SIZE * 8, 1, &(inst.word)) != 0)
+      {
+          /*
+           * We were able to read this address. It must be a valid address.
+           */
+          if (inst.word == BREAKPOINT_INSN)
+              sig = TARGET_SIGNAL_TRAP;
+      }
+      else
+          sig = TARGET_SIGNAL_ILL;
+  }
+  break;
+  case BSP_CORE_EXC_SOFTWARE_INTERRUPT:        sig = TARGET_SIGNAL_TRAP;    break;
+  case BSP_CORE_EXC_PREFETCH_ABORT:            sig = TARGET_SIGNAL_BUS;     break;
+  case BSP_CORE_EXC_DATA_ABORT:                sig = TARGET_SIGNAL_BUS;     break;
+  case BSP_CORE_EXC_ADDRESS_ERROR_26_BIT:      sig = TARGET_SIGNAL_BUS;     break;
+  case BSP_CORE_EXC_IRQ:                       sig = TARGET_SIGNAL_INT;     break;
+  case BSP_CORE_EXC_FIQ:                       sig = TARGET_SIGNAL_INT;     break;
+  default:                                     sig = TARGET_SIGNAL_TRAP;    break;
+  }
+
+  return sig;
+}
+
+
+/*
+ * Set the PC value in the saved registers.
+ */
+void
+bsp_set_pc(unsigned long pc, void *saved_regs)
+{
+  ((ex_regs_t *)saved_regs)->_pc = pc;
+}
+
+
+/*
+ * Get the PC value from the saved registers.
+ */
+unsigned long
+bsp_get_pc(void *saved_regs)
+{
+  return ((ex_regs_t *)saved_regs)->_pc;
+}
diff --git a/packages/cygmon/v2_0/misc/bsp/arm/gdb-cpu.h b/packages/cygmon/v2_0/misc/bsp/arm/gdb-cpu.h
new file mode 100644 (file)
index 0000000..9ee631b
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef __BSP_ARM_GDB_CPU_H__
+#define __BSP_ARM_GDB_CPU_H__
+//==========================================================================
+//
+//      gdb-cpu.h
+//
+//      CPU specific definitions for GDB stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      CPU specific definitions for GDB stub.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+/*
+ * Number of registers that gdb is interested in.
+ */
+#define NUMREGS 26
+
+#endif // __BSP_ARM_GDB_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/arm/gdb.h b/packages/cygmon/v2_0/misc/bsp/arm/gdb.h
new file mode 100644 (file)
index 0000000..37906d8
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __BSP_ARM_GDB_H__
+#define __BSP_ARM_GDB_H__
+//==========================================================================
+//
+//      gdb.h
+//
+//      
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include "../common/gdb.h"
+
+#endif // __BSP_ARM_GDB_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/arm/insn.h b/packages/cygmon/v2_0/misc/bsp/arm/insn.h
new file mode 100644 (file)
index 0000000..44dc3de
--- /dev/null
@@ -0,0 +1,482 @@
+#ifndef __BSP_ARM_INSN_H__
+#define __BSP_ARM_INSN_H__
+//==========================================================================
+//
+//      insn.h
+//
+//      ARM(R) instruction descriptions.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      ARM(R) instruction descriptions.
+// Description:  ARM is a Registered Trademark of Advanced RISC Machines
+//               Limited.
+//               Other Brands and Trademarks are the property of their
+//               respective owners.
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+/* Data Processing Immediate Type */
+struct dpi_type {
+    unsigned immediate   : 8;
+    unsigned rotate      : 4;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned S_bit       : 1;
+    unsigned opcode      : 4;
+    unsigned rsv1        : 3;  /* == 001b */
+    unsigned cond        : 4;
+};
+#define DPI_RSV1_VALUE 0x1
+
+/* Data Processing Immediate Shift Type */
+struct dpis_type {
+    unsigned Rm          : 4;
+    unsigned rsv2        : 1;  /* == 0b */
+    unsigned shift       : 2;
+    unsigned shift_immed : 5;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned S_bit       : 1;
+    unsigned opcode      : 4;
+    unsigned rsv1        : 3;  /* == 000b */
+    unsigned cond        : 4;
+};
+#define DPIS_RSV1_VALUE 0x0
+#define DPIS_RSV2_VALUE 0x0
+
+/* Data Processing Register Shift Type */
+struct dprs_type {
+    unsigned Rm          : 4;
+    unsigned rsv3        : 1;  /* == 1b */
+    unsigned shift       : 2;
+    unsigned rsv2        : 1;  /* == 0b */
+    unsigned Rs          : 4;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned S_bit       : 1;
+    unsigned opcode      : 4;
+    unsigned rsv1        : 3;  /* == 000b */
+    unsigned cond        : 4;
+};
+#define DPRS_RSV1_VALUE 0x0
+#define DPRS_RSV2_VALUE 0x0
+#define DPRS_RSV3_VALUE 0x1
+
+/* Multiply Type */
+struct m_type {
+    unsigned Rm          : 4;
+    unsigned rsv2        : 4;  /* == 1001b */
+    unsigned Rs          : 4;
+    unsigned Rn          : 4;
+    unsigned Rd          : 4;
+    unsigned S_bit       : 1;
+    unsigned A_bit       : 1;
+    unsigned rsv1        : 6;  /* == 000000b */
+    unsigned cond        : 4;
+};
+#define M_RSV1_VALUE 0x0
+#define M_RSV2_VALUE 0x9
+
+/* Multiply Long Type */
+struct ml_type {
+    unsigned Rm          : 4;
+    unsigned rsv2        : 4;  /* == 1001b */
+    unsigned Rs          : 4;
+    unsigned RdLo        : 4;
+    unsigned RdHi        : 4;
+    unsigned S_bit       : 1;
+    unsigned A_bit       : 1;
+    unsigned U_bit       : 1;
+    unsigned rsv1        : 5;  /* == 00001b */
+    unsigned cond        : 4;
+};
+#define ML_RSV1_VALUE 0x1
+#define ML_RSV2_VALUE 0x9
+
+/* Move from status register Type */
+struct mrs_type {
+    unsigned SBZ         : 12;
+    unsigned Rd          : 4;
+    unsigned SBO         : 4;
+    unsigned rsv2        : 2;  /* == 00b */
+    unsigned R_bit       : 1;
+    unsigned rsv1        : 5;  /* == 00010b */
+    unsigned cond        : 4;
+};
+#define MRS_RSV1_VALUE 0x2
+#define MRS_RSV2_VALUE 0x0
+
+/* Move Immediate to status register Type */
+struct misr_type {
+    unsigned immediate   : 8;
+    unsigned rotate      : 4;
+    unsigned SBO         : 4;
+    unsigned mask        : 4;
+    unsigned rsv2        : 2;  /* == 10b */
+    unsigned R_bit       : 1;
+    unsigned rsv1        : 5;  /* == 00110b */
+    unsigned cond        : 4;
+};
+#define MISR_RSV1_VALUE 0x6
+#define MISR_RSV2_VALUE 0x2
+
+/* Move register to status register Type */
+struct mrsr_type {
+    unsigned Rm          : 4;
+    unsigned rsv3        : 1;  /* == 0b */
+    unsigned SBZ         : 7;
+    unsigned SBO         : 4;
+    unsigned mask        : 4;
+    unsigned rsv2        : 2;  /* == 10b */
+    unsigned R_bit       : 1;
+    unsigned rsv1        : 5;  /* == 00010b */
+    unsigned cond        : 4;
+};
+#define MRSR_RSV1_VALUE 0x2
+#define MRSR_RSV2_VALUE 0x2
+#define MRSR_RSV3_VALUE 0x0
+
+/* Branch/Exchange Type */
+struct bx_type {
+    unsigned Rm          : 4;
+    unsigned rsv2        : 4;  /* == 0001b */
+    unsigned SBO3        : 4;
+    unsigned SBO2        : 4;
+    unsigned SBO1        : 4;
+    unsigned rsv1        : 8;  /* == 00010010b */
+    unsigned cond        : 4;
+};
+#define BX_RSV1_VALUE 0x12
+#define BX_RSV2_VALUE 0x1
+
+/* Load/Store Immediate Offset Type */
+struct lsio_type {
+    unsigned immediate   : 12;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned L_bit       : 1;
+    unsigned W_bit       : 1;
+    unsigned B_bit       : 1;
+    unsigned U_bit       : 1;
+    unsigned P_bit       : 1;
+    unsigned rsv1        : 3;  /* == 010b */
+    unsigned cond        : 4;
+};
+#define LSIO_RSV1_VALUE 0x2
+
+/* Load/Store Register Offset Type */
+struct lsro_type {
+    unsigned Rm          : 4;
+    unsigned rsv2        : 1;  /* == 0b */
+    unsigned shift       : 2;
+    unsigned shift_immed : 5;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned L_bit       : 1;
+    unsigned W_bit       : 1;
+    unsigned B_bit       : 1;
+    unsigned U_bit       : 1;
+    unsigned P_bit       : 1;
+    unsigned rsv1        : 3;  /* == 011b */
+    unsigned cond        : 4;
+};
+#define LSRO_RSV1_VALUE 0x3
+#define LSRO_RSV2_VALUE 0x0
+
+/* Load/Store halfword/signed byte Immediate Offset Type */
+struct lshwi_type {
+    unsigned Lo_Offset   : 4;
+    unsigned rsv4        : 1;  /* == 1b */
+    unsigned H_bit       : 1;
+    unsigned S_bit       : 1;
+    unsigned rsv3        : 1;  /* == 1b */
+    unsigned Hi_Offset   : 4;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned L_bit       : 1;
+    unsigned W_bit       : 1;
+    unsigned rsv2        : 1;  /* == 1b */
+    unsigned U_bit       : 1;
+    unsigned P_bit       : 1;
+    unsigned rsv1        : 3;  /* == 000b */
+    unsigned cond        : 4;
+};
+#define LSHWI_RSV1_VALUE 0x0
+#define LSHWI_RSV2_VALUE 0x1
+#define LSHWI_RSV3_VALUE 0x1
+#define LSHWI_RSV4_VALUE 0x1
+
+/* Load/Store halfword/signed byte Register Offset Type */
+struct lshwr_type {
+    unsigned Rm          : 4;
+    unsigned rsv4        : 1;  /* == 1b */
+    unsigned H_bit       : 1;
+    unsigned S_bit       : 1;
+    unsigned rsv3        : 1;  /* == 1b */
+    unsigned SBZ         : 4;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned L_bit       : 1;
+    unsigned W_bit       : 1;
+    unsigned rsv2        : 1;  /* == 0b */
+    unsigned U_bit       : 1;
+    unsigned P_bit       : 1;
+    unsigned rsv1        : 3;  /* == 000b */
+    unsigned cond        : 4;
+};
+#define LSHWR_RSV1_VALUE 0x3
+#define LSHWR_RSV2_VALUE 0x1
+#define LSHWR_RSV3_VALUE 0x1
+#define LSHWR_RSV4_VALUE 0x1
+
+/* Swap/Swap Byte Type */
+struct swap_type {
+    unsigned Rm          : 4;
+    unsigned rsv3        : 4;  /* == 1001b */
+    unsigned SBZ         : 4;
+    unsigned Rd          : 4;
+    unsigned Rn          : 4;
+    unsigned rsv2        : 2;  /* == 00b */
+    unsigned B_bit       : 1;
+    unsigned rsv1        : 5;  /* == 00010b */
+    unsigned cond        : 4;
+};
+#define SWAP_RSV1_VALUE 0x2
+#define SWAP_RSV2_VALUE 0x0
+#define SWAP_RSV3_VALUE 0x9
+
+/* Load/Store Multiple Type */
+struct lsm_type {
+    unsigned Reg_List    : 16 ;
+    unsigned Rn          : 4;
+    unsigned L_bit       : 1;
+    unsigned W_bit       : 1;
+    unsigned S_bit       : 1;
+    unsigned U_bit       : 1;
+    unsigned P_bit       : 1;
+    unsigned rsv1        : 3;  /* == 100b */
+    unsigned cond        : 4;
+};
+#define LSM_RSV1_VALUE 0x4
+
+/* Coprocessor Data Processing Type */
+struct cpdp_type {
+    unsigned CRm         : 4;
+    unsigned rsv2        : 1;  /* == 0b */
+    unsigned op2         : 3;
+    unsigned cp_num      : 4;
+    unsigned CRd         : 4;
+    unsigned CRn         : 4;
+    unsigned op1         : 4;
+    unsigned rsv1        : 4;  /* == 1110b */
+    unsigned cond        : 4;
+};
+#define CPDP_RSV1_VALUE 0xE
+#define CPDP_RSV2_VALUE 0x0
+
+/* Coprocessor Register Transfer Type */
+struct cprt_type {
+    unsigned CRm         : 4;
+    unsigned rsv2        : 1;  /* == 1b */
+    unsigned op2         : 3;
+    unsigned cp_num      : 4;
+    unsigned Rd          : 4;
+    unsigned CRn         : 4;
+    unsigned L_bit       : 1;
+    unsigned op1         : 3;
+    unsigned rsv1        : 4;  /* == 1110b */
+    unsigned cond        : 4;
+};
+#define CPRT_RSV1_VALUE 0xE
+#define CPRT_RSV2_VALUE 0x1
+
+/* Coprocessor Load/Store Type */
+struct cpls_type {
+    unsigned offset      : 8;
+    unsigned cp_num      : 4;
+    unsigned CRd         : 4;
+    unsigned Rn          : 4;
+    unsigned L_bit       : 1;
+    unsigned W_bit       : 1;
+    unsigned N_bit       : 1;
+    unsigned U_bit       : 1;
+    unsigned P_bit       : 1;
+    unsigned rsv1        : 3;  /* == 110b */
+    unsigned cond        : 4;
+};
+#define CPLS_RSV1_VALUE 0x6
+
+/* Branch/Branch w/ Link Type */
+struct bbl_type {
+    unsigned offset      : 24;
+    unsigned L_bit       : 1;
+    unsigned rsv1        : 3;  /* == 101b */
+    unsigned cond        : 4;
+};
+#define BBL_RSV1_VALUE 0x5
+
+/* SWI Type */
+struct swi_type {
+    unsigned swi_number  : 24;
+    unsigned rsv1        : 4;  /* == 1111b */
+    unsigned cond        : 4;
+};
+#define SWI_RSV1_VALUE 0xF
+
+/* Undefined Instruction Type */
+struct undef_type {
+    unsigned pad2        : 4;
+    unsigned rsv2        : 1;  /* == 1b */
+    unsigned pad1        : 20;
+    unsigned rsv1        : 3;  /* == 011b */
+    unsigned cond        : 4;
+};
+#define UNDEF_RSV1_VALUE 0x3
+#define UNDEF_RSV2_VALUE 0x1
+
+union arm_insn {
+    unsigned long          word;
+    struct dpi_type        dpi;
+    struct dpis_type       dpis;
+    struct dprs_type       dprs;
+    struct m_type          m;
+    struct ml_type         ml;
+    struct mrs_type        mrs;
+    struct misr_type       misr;
+    struct mrsr_type       mrsr;
+    struct bx_type         bx;
+    struct lsio_type       lsio;
+    struct lsro_type       lsro;
+    struct lshwi_type      lshwi;
+    struct lshwr_type      lshwr;
+    struct swap_type       swap;
+    struct lsm_type        lsm;
+    struct cpdp_type       cpdp;
+    struct cprt_type       cprt;
+    struct cpls_type       cpls;
+    struct bbl_type        bbl;
+    struct swi_type        swi;
+    struct undef_type      undef;
+};
+
+/*
+ * Conditional field values
+ */
+#define COND_EQ     0x0
+#define COND_NE     0x1
+#define COND_CS_HI  0x2
+#define COND_CC_LO  0x3
+#define COND_MI     0x4
+#define COND_PL     0x5
+#define COND_VS     0x6
+#define COND_VC     0x7
+#define COND_HI     0x8
+#define COND_LS     0x9
+#define COND_GE     0xA
+#define COND_LT     0xB
+#define COND_GT     0xC
+#define COND_LE     0xD
+#define COND_AL     0xE
+#define COND_NV     0xF
+
+/*
+ * Data Processiong Opcode field values
+ */
+#define DP_OPCODE_MOV  0xD
+#define DP_OPCODE_MVN  0xF
+#define DP_OPCODE_ADD  0x4
+#define DP_OPCODE_ADC  0x5
+#define DP_OPCODE_SUB  0x2
+#define DP_OPCODE_SBC  0x6
+#define DP_OPCODE_RSB  0x3
+#define DP_OPCODE_RSC  0x7
+#define DP_OPCODE_AND  0x0
+#define DP_OPCODE_EOR  0x1
+#define DP_OPCODE_ORR  0xC
+#define DP_OPCODE_BIC  0xE
+#define DP_OPCODE_CMP  0xA
+#define DP_OPCODE_CMN  0xB
+#define DP_OPCODE_TST  0x8
+#define DP_OPCODE_TEQ  0x9
+
+/*
+ * Shift field values
+ */
+#define SHIFT_LSL   0x0
+#define SHIFT_LSR   0x1
+#define SHIFT_ASR   0x2
+#define SHIFT_ROR   0x3
+#define SHIFT_RRX   0x3    /* Special case: ROR(0) implies RRX */
+
+/*
+ * Load/Store indexing definitions
+ */
+#define LS_INDEX_POST      0x0
+#define LS_INDEX_PRE       0x1
+
+/*
+ * Load/Store offset operation definitions
+ */
+#define LS_OFFSET_SUB      0x0
+#define LS_OFFSET_ADD      0x1
+
+/*
+ * Load/Store size definitions
+ */
+#define LS_SIZE_WORD       0x0
+#define LS_SIZE_BYTE       0x1
+
+/*
+ * Load/Store Update definitions
+ */
+#define LS_NO_UPDATE       0x0
+#define LS_UPDATE          0x1
+
+/*
+ * Load/Store Opcode definitions
+ */
+#define LS_STORE           0x0
+#define LS_LOAD            0x1
+
+#endif // __BSP_ARM_INSN_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/arm/singlestep.c b/packages/cygmon/v2_0/misc/bsp/arm/singlestep.c
new file mode 100644 (file)
index 0000000..76e994c
--- /dev/null
@@ -0,0 +1,1320 @@
+//==========================================================================
+//
+//      singlestep.c
+//
+//      ARM(R) specific single-step support.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      ARM(R) specific single-step support. 
+// Description:  ARM is a Registered Trademark of Advanced RISC Machines Limited.
+//               Other Brands and Trademarks are the property of their
+//               respective owners.
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <stdlib.h>
+#include <bsp/bsp.h>
+#include <bsp/cpu.h>
+#include "insn.h"
+
+#define DEBUG_SINGLESTEP         0
+#define DEBUG_SINGLESTEP_VERBOSE 0
+
+/*
+ * Structure to hold opcodes hoisted when breakpoints are
+ * set for single-stepping or async interruption.
+ */
+struct _bp_save {
+    unsigned long *addr;
+    unsigned long opcode;
+};
+
+#define NUM_BREAKS_SAVED 2
+static struct _bp_save _breaks[NUM_BREAKS_SAVED];
+
+/*
+ *  Insert a breakpoint at 'pc' using first available
+ *  _bp_save struct.
+ */
+static void
+insert_ss_break(unsigned long *pc)
+{
+    struct _bp_save *p = _breaks;
+    union arm_insn inst;
+
+    if (p->addr && (++p)->addr)
+       return;
+
+    /*
+     * We can't set a breakpoint at 0
+     */
+    if (pc == 0)
+    {
+#if DEBUG_SINGLESTEP
+        bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
+#endif /* DEBUG_SINGLESTEP */
+        return;
+    }
+
+    /*
+     * Make sure we are on a long word boundary.
+     */
+    if (((unsigned long)pc & 0x3) != 0)
+    {
+        /*
+         * All ARM(R) instructions are on a word boundary.
+         * This would be invalid.  Don't set a bkpt here.
+         */
+#if DEBUG_SINGLESTEP
+        bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
+#endif /* DEBUG_SINGLESTEP */
+        return;
+    }
+
+
+    /*
+     * What is the current instruction
+     */
+    if (bsp_memory_read(pc, 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0)
+    {
+        /*
+         * Unable to read this address, probably an invalid address.
+         * Don't set a breakpoint here, as it will likely cause a bus error
+         */
+#if DEBUG_SINGLESTEP
+        bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
+#endif /* DEBUG_SINGLESTEP */
+        return;
+    }
+
+    if (inst.word != BREAKPOINT_INSN)
+    {
+        /*
+         * Only insert a breakpoint if we haven't done so already
+         *
+         * We may try to insert 2 breakpoints if we to a branch to
+         * the immediately following instruction.
+         */
+#if DEBUG_SINGLESTEP
+        bsp_printf("Setting BP at <0x%08lx>: inst <0x%08lx>\n", pc, inst.word);
+#endif /* DEBUG_SINGLESTEP */
+
+        p->addr = pc;
+        p->opcode = inst.word;
+        inst.word = BREAKPOINT_INSN;
+        if (bsp_memory_write(pc, 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0)
+        {
+            /*
+             * Unable to write this address, probably an invalid address.
+             * Don't set a breakpoint here, as it will likely cause a bus error
+             */
+#if DEBUG_SINGLESTEP
+            bsp_printf("Setting BP at <0x%08lx>: Error\n", pc);
+#endif /* DEBUG_SINGLESTEP */
+            return;
+        }
+
+        /* flush icache and dcache, now */
+        bsp_flush_dcache((void *)pc, ARM_INST_SIZE);
+        bsp_flush_icache((void *)pc, ARM_INST_SIZE);
+
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Done setting BP at <0x%08lx>: inst <0x%08lx>\n", pc, *pc);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+    }
+}
+
+/*
+ *  Cleanup after a singlestep.
+ */
+void
+bsp_singlestep_cleanup(void *registers)
+{
+    struct _bp_save *p = _breaks;
+    int i;
+    
+    for (i = 0; i < NUM_BREAKS_SAVED; i++, p++)
+    {
+        if (p->addr)
+        {
+            unsigned long *old_addr = p->addr;
+
+#if DEBUG_SINGLESTEP_VERBOSE
+            bsp_printf("Remove BP at <0x%08lx>: inst <0x%08lx>\n", old_addr, *old_addr);
+#endif /* DEBUG_SINGLESTEP */
+            *(p->addr) = p->opcode;
+            p->addr = NULL;
+
+            /* flush icache and dcache, now */
+            bsp_flush_dcache((void *)old_addr, ARM_INST_SIZE);
+            bsp_flush_icache((void *)old_addr, ARM_INST_SIZE);
+
+#if DEBUG_SINGLESTEP_VERBOSE
+            bsp_printf("Done removing BP at <0x%08lx>: inst <0x%08lx>\n", old_addr, *old_addr);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        }
+    }
+}
+
+/*
+ * Rotate right a value by count
+ */
+static unsigned long ror(unsigned long value, unsigned count)
+{
+    while (count-- > 0)
+    {
+        if (value & 0x1)
+            value = (value >> 1) | 0x80000000;
+        else
+            value = (value >> 1);
+    }
+
+    return(value);
+}
+
+/*
+ * Rotate right a value by 1 with extend
+ */
+static unsigned long rrx(union arm_psr sr, unsigned long value)
+{
+    if (sr.psr.c_bit)
+        value = (value >> 1) | 0x80000000;
+    else
+        value = (value >> 1);
+
+    return(value);
+}
+
+/*
+ * Logical shift left by count
+ */
+static unsigned long lsl(unsigned long value, unsigned count)
+{
+    value <<= count;
+
+    return(value);
+}
+
+/*
+ * Logical shift right by count
+ */
+static unsigned long lsr(unsigned long value, unsigned count)
+{
+    value >>= count;
+
+    return(value); 
+}
+
+/*
+ * Arithmetic shift right by count
+ */
+static unsigned long asr(unsigned long value, unsigned count)
+{
+    unsigned long sign_ext_mask = 0;
+
+    if (value & 0x80000000)
+    {
+        if (count >= sizeof(value)*8)
+            sign_ext_mask = ~0;
+        else
+            sign_ext_mask = (~0 << (sizeof(value)*8 - count));
+    }
+    value = (value >> count) | sign_ext_mask;
+
+    return(value); 
+}
+
+/*
+ * Calculate an immediate shift operand based on input shift operand, 
+ * shift value and register address.
+ */
+static unsigned long immediate_shift_operand(ex_regs_t *regs, unsigned shift_immediate, 
+                                             unsigned shift, unsigned Rm)
+{
+    unsigned char *regs_array = (unsigned char *)regs;
+    unsigned char *reg_ptr = &regs_array[bsp_regbyte(Rm)];
+    unsigned long reg_value = *((unsigned long *)(reg_ptr));
+    unsigned long rc = 0;
+
+    BSP_ASSERT((shift_immediate >= 0) && (shift_immediate <= 0x1f));
+    BSP_ASSERT((shift >= 0) && (shift <= 0x3));
+    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
+    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
+
+    /*
+     * According to the ARM(R) Manual, if Rm is PC then,
+     * the value used is the address of the current instruction
+     * plus 8
+     */
+    if (Rm == REG_PC)
+        reg_value += 8;
+
+    switch (shift)
+    {
+    case SHIFT_LSL:
+        rc = lsl(reg_value, shift_immediate);
+        break;
+
+    case SHIFT_LSR:
+        if (shift_immediate == 0)
+        {
+            /*
+             * Special Case: LSR IMM(0) == 0
+             */
+            rc = 0;
+        } else {
+            rc = lsr(reg_value, shift_immediate);
+        }
+        break;
+
+    case SHIFT_ASR:
+        if (shift_immediate == 0)
+        {
+            /*
+             * Special Case: ASR IMM(0)
+             */
+            if (reg_value & 0x80000000)
+            {
+                rc = 0xFFFFFFFF;
+            } else {
+                rc = 0;
+            }
+        } else {
+            rc = asr(reg_value, shift_immediate);
+        }
+        break;
+
+    case SHIFT_ROR:
+        if (shift_immediate == 0)
+        {
+            /*
+             * SHIFT_RRX
+             * Special case: ROR(0) implies RRX
+             */
+            rc = rrx((union arm_psr)(unsigned long)regs->_cpsr, reg_value);
+        } else {
+            rc = ror(reg_value, shift_immediate);
+        }
+        break;
+
+    default:
+        BSP_ASSERT(0);
+        break;
+    }
+
+    return (rc);
+}
+
+/*
+ * Calculate a register shift operand based on input shift operand, 
+ * and target registers.
+ */
+static unsigned long register_shift_operand(ex_regs_t *regs, unsigned Rs,
+                                            unsigned shift, unsigned Rm)
+{
+    unsigned char *regs_array = (unsigned char *)regs;
+    unsigned char *Rs_ptr = &regs_array[bsp_regbyte(Rs)];
+    unsigned char *Rm_ptr = &regs_array[bsp_regbyte(Rm)];
+    unsigned long Rs_val = *((unsigned long *)(Rs_ptr));
+    unsigned long Rm_val = *((unsigned long *)(Rm_ptr));
+    unsigned long rc = 0;
+
+    /*
+     * Use only the least significant byte of Rs
+     */
+    Rs_val &= 0xFF;
+
+    BSP_ASSERT((Rs >= 0) && (Rs <= 0xf));
+    BSP_ASSERT((shift >= 0) && (shift <= 0x3));
+    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
+    BSP_ASSERT(bsp_regsize(Rs) == sizeof(unsigned long));
+    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
+    BSP_ASSERT((Rs_val >=0) && (Rs_val <= 0xff));
+
+    /*
+     * According to the ARM(R) Manual, if Rm is PC then,
+     * the value used is the address of the current instruction
+     * plus 8
+     */
+    if (Rm == REG_PC)
+        Rm_val += 8;
+
+    switch (shift)
+    {
+    case SHIFT_LSL: rc = lsl(Rm_val, Rs_val); break;
+    case SHIFT_LSR: rc = lsr(Rm_val, Rs_val); break;
+    case SHIFT_ASR: rc = asr(Rm_val, Rs_val); break;
+    case SHIFT_ROR: rc = ror(Rm_val, Rs_val); break;
+    default:        BSP_ASSERT(0);            break;
+    }
+
+    return (rc);
+}
+
+/*
+ * Calculate a branch exchange operand based on input destination register
+ */
+static unsigned long branch_exchange_operand(ex_regs_t *regs, unsigned Rm)
+{
+    unsigned char *regs_array = (unsigned char *)regs;
+    unsigned char *reg_ptr = &regs_array[bsp_regbyte(Rm)];
+    unsigned long reg_value = *((unsigned long *)(reg_ptr));
+
+    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
+    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
+
+    /*
+     * Clear the low-order bit
+     */
+    return (reg_value & ~0x1);
+}
+
+/*
+ * Handle a load to the PC
+ */
+static void handle_pc_load(unsigned size, unsigned long operand)
+{
+    unsigned long mem_value = 0;
+
+    if (size == LS_SIZE_WORD)
+    {
+        if (bsp_memory_read((void*)(operand & ~0x3), 0, 32, 1, &mem_value) == 0)
+        {
+            /*
+             * Unable to read the memory address.
+             * Don't try any further.
+             */
+#if DEBUG_SINGLESTEP
+            bsp_printf("Setting BP at *(0x%08lx): Error\n", operand & ~0x3);
+#endif /* DEBUG_SINGLESTEP */
+            return;
+        } else {
+#if DEBUG_SINGLESTEP
+            bsp_printf("Setting BP at *(0x%08lx): data <0x%08lx>\n", operand & ~0x3, mem_value);
+#endif /* DEBUG_SINGLESTEP */
+        }
+
+        /*
+         * Handle rotations if required
+         */
+        switch (operand & 0x3)
+        {
+        case 0x0: break;
+        case 0x1: mem_value = ror(mem_value,  8); break;
+        case 0x2: mem_value = ror(mem_value, 16); break;
+        case 0x3: mem_value = ror(mem_value, 24); break;
+        }
+    } else {
+        /*
+         * Byte load of the PC
+         */
+        if (bsp_memory_read((void*)operand, 0, 8, 1, &mem_value) == 0)
+        {
+            /*
+             * Unable to read the memory address.
+             * Don't try any further.
+             */
+#if DEBUG_SINGLESTEP
+            bsp_printf("Setting BP at *(0x%08lx): Error\n", operand & ~0x3);
+#endif /* DEBUG_SINGLESTEP */
+            return;
+        } else {
+#if DEBUG_SINGLESTEP
+            bsp_printf("Setting BP at *(0x%08lx): data <0x%08lx>\n", operand & ~0x3, mem_value);
+#endif /* DEBUG_SINGLESTEP */
+        }
+    }
+    
+    insert_ss_break((unsigned long *)mem_value);
+}
+
+/*
+ * Calculate a load/store w/ Immediate offset operand based on input
+ * source register, offset value, and opcode (add/sub)
+ */
+static unsigned long load_store_immediate_operand(ex_regs_t *regs,
+                                                  unsigned p_bit, 
+                                                  unsigned u_bit,
+                                                  unsigned Rn,
+                                                  unsigned offset)
+{
+    unsigned char *regs_array = (unsigned char *)regs;
+    unsigned char *reg_ptr = &regs_array[bsp_regbyte(Rn)];
+    unsigned long rc = *((unsigned long *)(reg_ptr));
+
+    BSP_ASSERT((Rn >= 0) && (Rn <= 0xf));
+    BSP_ASSERT(bsp_regsize(Rn) == sizeof(unsigned long));
+    BSP_ASSERT((offset >= 0) && (offset <= 0xfff));
+    BSP_ASSERT((p_bit >= 0) && (p_bit <= 1));
+    BSP_ASSERT((u_bit >= 0) && (u_bit <= 1));
+
+    /*
+     * According to the ARM(R) Manual, if Rn is PC then,
+     * the value used is the address of the current instruction
+     * plus 8
+     */
+    if (Rn == REG_PC)
+        rc += 8;
+
+    /*
+     * Do the update pre-index update
+     */
+    if (p_bit == LS_INDEX_PRE)
+    {
+        if (u_bit == LS_OFFSET_SUB)
+            rc -= offset;
+        else /* opcode == LS_OFFSET_ADD */
+            rc += offset;
+    }
+
+   return (rc);
+}
+
+/*
+ * Calculate a load/store w/ Register offset operand based on input
+ * source register, offset value, and opcode (add/sub)
+ *
+ * This calculates the appropriate pre-indexed operand
+ */
+static unsigned long load_store_register_operand(ex_regs_t *regs,
+                                                 unsigned p_bit, 
+                                                 unsigned u_bit,
+                                                 unsigned Rn,
+                                                 unsigned Rm,
+                                                 unsigned shift,
+                                                 unsigned shift_immed)
+{
+    unsigned char *regs_array = (unsigned char *)regs;
+    unsigned char *Rn_ptr = &regs_array[bsp_regbyte(Rn)];
+    unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
+    unsigned long rc, index;
+
+    BSP_ASSERT((Rn >= 0) && (Rn <= 0xf));
+    BSP_ASSERT((Rm >= 0) && (Rm <= 0xf));
+    BSP_ASSERT(bsp_regsize(Rn) == sizeof(unsigned long));
+    BSP_ASSERT(bsp_regsize(Rm) == sizeof(unsigned long));
+    BSP_ASSERT((p_bit >= 0) && (p_bit <= 1));
+    BSP_ASSERT((u_bit >= 0) && (u_bit <= 1));
+    BSP_ASSERT((shift >= 0) && (shift <= 0x3));
+    BSP_ASSERT((shift_immed >= 0) && (shift_immed <= 0x1F));
+
+    /*
+     * According to the ARM(R) Manual, if Rn is PC then
+     * the value used is the address of the current
+     * instruction plus 8
+     */
+    if (Rn == REG_PC)
+        Rn_val += 8;
+
+    /*
+     * According to the ARM(R) Manual, if Rm is PC then
+     * the result is unpredictable.  Don't do anything
+     * here.  Just return.
+     */
+    if (Rm == REG_PC)
+        return 0;
+
+    index = immediate_shift_operand(regs, shift_immed, shift, Rm);
+    
+    rc = Rn_val;
+
+    /*
+     * Do the update pre-index update
+     */
+    if (p_bit == LS_INDEX_PRE)
+    {
+        if (u_bit == LS_OFFSET_SUB)
+            rc = Rn_val - index;
+        else /* opcode == LS_OFFSET_ADD */
+            rc = Rn_val + index;
+    }
+
+   return (rc);
+}
+
+/*
+ * Decode all data processing immediate instructions
+ */
+static void decode_dpi_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    if (inst.dpi.Rd == REG_PC)
+    {
+        unsigned long operand = ror(inst.dpi.immediate, (inst.dpi.rotate << 1));
+        unsigned long *dest = 0;
+        unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit;
+        unsigned char *regs_array = (unsigned char *)regs;
+        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.dpi.Rn)];
+        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
+
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Decoded an data processing immediate instruction.\n");
+        bsp_printf("inst.dpi.immediate = 0x%x\n", inst.dpi.immediate);
+        bsp_printf("inst.dpi.rotate    = 0x%x\n", inst.dpi.rotate);
+        bsp_printf("inst.dpi.Rd        = 0x%x\n", inst.dpi.Rd);
+        bsp_printf("inst.dpi.Rn        = 0x%x\n", inst.dpi.Rn);
+        bsp_printf("inst.dpi.S_bit     = 0x%x\n", inst.dpi.S_bit);
+        bsp_printf("inst.dpi.opcode    = 0x%x\n", inst.dpi.opcode);
+        bsp_printf("inst.dpi.cond      = 0x%x\n", inst.dpi.cond);
+        bsp_printf("operand            = 0x%x\n", operand);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+        /*
+         * According to the ARM(R) Manual, if Rn is PC then
+         * the value used is the address of the current
+         * instruction plus 8
+         */
+        if (inst.dpi.Rn == REG_PC)
+            Rn_val += 8;
+
+        switch (inst.dpi.opcode) {
+        case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry);    break;
+        case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand);            break;
+        case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand);            break;
+        case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand);           break;
+        case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand);            break;
+        case DP_OPCODE_MOV: dest = (unsigned long *)operand;                       break;
+        case DP_OPCODE_MVN: dest = (unsigned long *)(~operand);                    break;
+        case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand);            break;
+        case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val);            break;
+        case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry);   break;
+        case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry);   break;
+        case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand);            break;
+        default:            dest = (unsigned long *)0;                             break;
+        }
+        dest = (unsigned long *)((unsigned long)dest & ~0x3);
+        insert_ss_break(dest);
+    }
+}
+
+/*
+ * Decode all data processing immediate w/ shift instructions
+ */
+static void decode_dpis_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    if (inst.dpis.Rd == REG_PC)
+    {
+        unsigned long operand = immediate_shift_operand(regs, inst.dpis.shift_immed, 
+                                                        inst.dpis.shift, inst.dpis.Rm);
+        unsigned long *dest = 0;
+        unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit;
+        unsigned char *regs_array = (unsigned char *)regs;
+        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.dpis.Rn)];
+        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
+
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Decoded an data processing immediate shift instruction.\n");
+        bsp_printf("inst.dpis.Rm          = 0x%x\n", inst.dpis.Rm);
+        bsp_printf("inst.dpis.shift       = 0x%x\n", inst.dpis.shift);
+        bsp_printf("inst.dpis.shift_immed = 0x%x\n", inst.dpis.shift_immed);
+        bsp_printf("inst.dpis.Rd          = 0x%x\n", inst.dpis.Rd);
+        bsp_printf("inst.dpis.Rn          = 0x%x\n", inst.dpis.Rn);
+        bsp_printf("inst.dpis.S_bit       = 0x%x\n", inst.dpis.S_bit);
+        bsp_printf("inst.dpis.opcode      = 0x%x\n", inst.dpis.opcode);
+        bsp_printf("inst.dpis.cond        = 0x%x\n", inst.dpis.cond);
+        bsp_printf("operand               = 0x%x\n", operand);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+        /*
+         * According to the ARM(R) Manual, if Rn is PC then
+         * the value used is the address of the current
+         * instruction plus 8
+         */
+        if (inst.dpis.Rn == REG_PC)
+            Rn_val += 8;
+
+        switch (inst.dpis.opcode) {
+        case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry);    break;
+        case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand);            break;
+        case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand);            break;
+        case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand);           break;
+        case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand);            break;
+        case DP_OPCODE_MOV: dest = (unsigned long *)operand;                       break;
+        case DP_OPCODE_MVN: dest = (unsigned long *)(~operand);                    break;
+        case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand);            break;
+        case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val);            break;
+        case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry);   break;
+        case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry);   break;
+        case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand);            break;
+        default:            dest = (unsigned long *)0;                             break;
+        }
+        dest = (unsigned long *)((unsigned long)dest & ~0x3);
+        insert_ss_break(dest);
+    }
+}
+
+/*
+ * Decode all data processing register w/ shift instructions
+ */
+static void decode_dprs_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    if (inst.dprs.Rd == REG_PC)
+    {
+        unsigned long operand = register_shift_operand(regs, inst.dprs.Rs,
+                                                       inst.dprs.shift, inst.dprs.Rm);
+        unsigned long *dest = 0;
+        unsigned carry = ((union arm_psr)(unsigned long)(regs->_cpsr)).psr.c_bit;
+        unsigned char *regs_array = (unsigned char *)regs;
+        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.dprs.Rn)];
+        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
+
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Decoded an data processing register shift instruction.\n");
+        bsp_printf("inst.dprs.Rm          = 0x%x\n", inst.dprs.Rm);
+        bsp_printf("inst.dprs.rsv3        = 0x%x\n", inst.dprs.rsv3);
+        bsp_printf("inst.dprs.shift       = 0x%x\n", inst.dprs.shift);
+        bsp_printf("inst.dprs.rsv2        = 0x%x\n", inst.dprs.rsv2);
+        bsp_printf("inst.dprs.Rs          = 0x%x\n", inst.dprs.Rs);
+        bsp_printf("inst.dprs.Rd          = 0x%x\n", inst.dprs.Rd);
+        bsp_printf("inst.dprs.Rn          = 0x%x\n", inst.dprs.Rn);
+        bsp_printf("inst.dprs.S_bit       = 0x%x\n", inst.dprs.S_bit);
+        bsp_printf("inst.dprs.opcode      = 0x%x\n", inst.dprs.opcode);
+        bsp_printf("inst.dprs.rsv1        = 0x%x\n", inst.dprs.rsv1);
+        bsp_printf("inst.dprs.cond        = 0x%x\n", inst.dprs.cond);
+        bsp_printf("operand               = 0x%x\n", operand);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+        /*
+         * According to the ARM(R) Manual, if Rn is PC then
+         * the value used is the address of the current
+         * instruction plus 8
+         */
+        if (inst.dprs.Rn == REG_PC)
+            Rn_val += 8;
+
+        switch (inst.dprs.opcode) {
+        case DP_OPCODE_ADC: dest = (unsigned long *)(Rn_val + operand + carry);    break;
+        case DP_OPCODE_ADD: dest = (unsigned long *)(Rn_val + operand);            break;
+        case DP_OPCODE_AND: dest = (unsigned long *)(Rn_val & operand);            break;
+        case DP_OPCODE_BIC: dest = (unsigned long *)(Rn_val & ~operand);           break;
+        case DP_OPCODE_EOR: dest = (unsigned long *)(Rn_val ^ operand);            break;
+        case DP_OPCODE_MOV: dest = (unsigned long *)operand;                       break;
+        case DP_OPCODE_MVN: dest = (unsigned long *)(~operand);                    break;
+        case DP_OPCODE_ORR: dest = (unsigned long *)(Rn_val | operand);            break;
+        case DP_OPCODE_RSB: dest = (unsigned long *)(operand - Rn_val);            break;
+        case DP_OPCODE_RSC: dest = (unsigned long *)(operand - Rn_val - !carry);   break;
+        case DP_OPCODE_SBC: dest = (unsigned long *)(Rn_val - operand - !carry);   break;
+        case DP_OPCODE_SUB: dest = (unsigned long *)(Rn_val - operand);            break;
+        default:            dest = (unsigned long *)0;                             break;
+        }
+
+        dest = (unsigned long *)((unsigned long)dest & ~0x3);
+        insert_ss_break(dest);
+    }
+}
+
+/*
+ * Decode all multiply instructions
+ */
+static void decode_m_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * According to the ARM(R) Manual, if Rd is PC then
+     * the result is unpredictable.  Don't do anything
+     * here.  Just return.
+     */
+}
+
+/*
+ * Decode all multiply long instructions
+ */
+static void decode_ml_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * According to the ARM(R) Manual, if Rd is PC then
+     * the result is unpredictable.  Don't do anything
+     * here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all move from status register instructions
+ */
+static void decode_mrs_inst(ex_regs_t *regs, union arm_insn inst)
+{
+#if 0
+    if (inst.mrs.Rd == REG_PC)
+    {
+        unsigned long *dest = 0;
+
+#if DEBUG_SINGLESTEP_VERBOSE
+    bsp_printf("Decoded an move from status register instruction.\n");
+    bsp_printf("inst.mrs.SBZ        = 0x%x\n", inst.mrs.SBZ);
+    bsp_printf("inst.mrs.Rd         = 0x%x\n", inst.mrs.Rd);
+    bsp_printf("inst.mrs.SBO        = 0x%x\n", inst.mrs.SBO);
+    bsp_printf("inst.mrs.rsv2       = 0x%x\n", inst.mrs.rsv2);
+    bsp_printf("inst.mrs.R_bit      = 0x%x\n", inst.mrs.R_bit);
+    bsp_printf("inst.mrs.rsv1       = 0x%x\n", inst.mrs.rsv1);
+    bsp_printf("inst.mrs.cond       = 0x%x\n", inst.mrs.cond);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+        if (inst.mrs.R_bit == 1)
+            dest = (unsigned long *)regs->_spsr;
+        else
+            dest = (unsigned long *)regs->_cpsr;
+
+        dest = (unsigned long *)((unsigned long)dest & ~0x3);
+        insert_ss_break(dest);
+    }
+#endif
+}
+
+
+/*
+ * Decode all move immediate to status register instructions
+ */
+static void decode_misr_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Can't update the PC w/ this instruction.
+     * Don't set any more breakpoints
+     */
+}
+
+
+/*
+ * Decode all move register to status registers instructions
+ */
+static void decode_mrsr_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Can't update the PC w/ this instruction.
+     * Don't set any more breakpoints
+     */
+}
+
+
+/*
+ * Decode all branch/exchange instructions
+ */
+static void decode_bx_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    unsigned long operand = branch_exchange_operand(regs, inst.bx.Rm);
+
+#if DEBUG_SINGLESTEP_VERBOSE
+    bsp_printf("Decoded an branch/exchange shift instruction.\n");
+    bsp_printf("inst.bx.Rm          = 0x%x\n", inst.bx.Rm);
+    bsp_printf("inst.bx.rsv2        = 0x%x\n", inst.bx.rsv2);
+    bsp_printf("inst.bx.SBO3        = 0x%x\n", inst.bx.SBO3);
+    bsp_printf("inst.bx.SBO2        = 0x%x\n", inst.bx.SBO2);
+    bsp_printf("inst.bx.SBO1        = 0x%x\n", inst.bx.SBO1);
+    bsp_printf("inst.bx.rsv1        = 0x%x\n", inst.bx.rsv1);
+    bsp_printf("inst.bx.cond        = 0x%x\n", inst.bx.cond);
+    bsp_printf("operand             = 0x%x\n", operand);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+    insert_ss_break((unsigned long *)operand);
+}
+
+
+/*
+ * Decode all load/store immediate offset instructions
+ */
+static void decode_lsio_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Only support direct loads of the PC
+     *
+     * According to the ARM(R) manual, automatic updates of the PC
+     * are UNPREDICTABLE (ie implementation defined).
+     */
+    if ((inst.lsio.Rd == REG_PC) && (inst.lsio.L_bit == LS_LOAD))
+    {
+        unsigned long operand = load_store_immediate_operand(regs, inst.lsio.P_bit,
+                                                             inst.lsio.U_bit, inst.lsio.Rn,
+                                                             inst.lsio.immediate);
+
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Decoded an load/store w/ immediate offset instruction.\n");
+        bsp_printf("inst.lsio.immediate = 0x%x\n", inst.lsio.immediate);
+        bsp_printf("inst.lsio.Rd        = 0x%x\n", inst.lsio.Rd);
+        bsp_printf("inst.lsio.Rn        = 0x%x\n", inst.lsio.Rn);
+        bsp_printf("inst.lsio.L_bit     = 0x%x\n", inst.lsio.L_bit);
+        bsp_printf("inst.lsio.W_bit     = 0x%x\n", inst.lsio.W_bit);
+        bsp_printf("inst.lsio.B_bit     = 0x%x\n", inst.lsio.B_bit);
+        bsp_printf("inst.lsio.U_bit     = 0x%x\n", inst.lsio.U_bit);
+        bsp_printf("inst.lsio.P_bit     = 0x%x\n", inst.lsio.P_bit);
+        bsp_printf("inst.lsio.rsv1      = 0x%x\n", inst.lsio.rsv1);
+        bsp_printf("inst.lsio.cond      = 0x%x\n", inst.lsio.cond);
+        bsp_printf("operand             = 0x%x\n", operand);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+        handle_pc_load(inst.lsio.B_bit, operand);
+    }
+}
+
+
+/*
+ * Decode all load/store register offset instructions
+ */
+static void decode_lsro_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Only support direct loads of the PC
+     *
+     * According to the ARM(R) manual, automatic updates of the PC
+     * are UNPREDICTABLE (ie implementation defined).
+     */
+    if ((inst.lsro.Rd == REG_PC) && (inst.lsro.L_bit == LS_LOAD))
+    {
+        unsigned long operand = load_store_register_operand(regs,
+                                                            inst.lsro.P_bit, 
+                                                            inst.lsro.U_bit,
+                                                            inst.lsro.Rn,
+                                                            inst.lsro.Rm,
+                                                            inst.lsro.shift,
+                                                            inst.lsro.shift_immed);
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Decoded an load/store w/ register offset instruction.\n");
+        bsp_printf("inst.lsro.Rm          = 0x%x\n", inst.lsro.Rm);
+        bsp_printf("inst.lsro.rsv2        = 0x%x\n", inst.lsro.rsv2);
+        bsp_printf("inst.lsro.shift       = 0x%x\n", inst.lsro.shift);
+        bsp_printf("inst.lsro.shift_immed = 0x%x\n", inst.lsro.shift_immed);
+        bsp_printf("inst.lsro.Rd          = 0x%x\n", inst.lsro.Rd);
+        bsp_printf("inst.lsro.Rn          = 0x%x\n", inst.lsro.Rn);
+        bsp_printf("inst.lsro.L_bit       = 0x%x\n", inst.lsro.L_bit);
+        bsp_printf("inst.lsro.W_bit       = 0x%x\n", inst.lsro.W_bit);
+        bsp_printf("inst.lsro.B_bit       = 0x%x\n", inst.lsro.B_bit);
+        bsp_printf("inst.lsro.U_bit       = 0x%x\n", inst.lsro.U_bit);
+        bsp_printf("inst.lsro.P_bit       = 0x%x\n", inst.lsro.P_bit);
+        bsp_printf("inst.lsro.rsv1        = 0x%x\n", inst.lsro.rsv1);
+        bsp_printf("inst.lsro.cond        = 0x%x\n", inst.lsro.cond);
+        bsp_printf("operand               = 0x%x\n", operand);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+        handle_pc_load(inst.lsro.B_bit, operand);
+    }
+}
+
+
+/*
+ * Decode all load/store halfword/signed byte immediate offset instructions
+ */
+static void decode_lshwi_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * According to the ARM(R) Manual, if Rd is PC then
+     * the result is unpredictable.  Don't do anything
+     * here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all load/store halfword/signed byte register offset instructions
+ */
+static void decode_lshwr_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * According to the ARM(R) Manual, if Rd is PC then
+     * the result is unpredictable.  Don't do anything
+     * here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all swap/swap byte instructions
+ */
+static void decode_swap_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * According to the ARM(R) Manual, if Rd is PC then
+     * the result is unpredictable.  Don't do anything
+     * here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all load/store multiple instructions
+ */
+static void decode_lsm_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Only support direct load multiples where the PC is in the
+     * register list.
+     *
+     * According to the ARM(R) manual, automatic updates of the PC
+     * are UNPREDICTABLE (ie implementation defined).
+     */
+    if ((inst.lsm.L_bit == LS_LOAD) && (inst.lsm.Reg_List & (0x1 << REG_PC)))
+    {
+        unsigned char *regs_array = (unsigned char *)regs;
+        unsigned char *Rn_ptr = &regs_array[bsp_regbyte(inst.lsm.Rn)];
+        unsigned long Rn_val = *((unsigned long *)(Rn_ptr));
+        unsigned long offset_to_pc = 0;
+        int i;
+        unsigned long **dest = 0;
+
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Decoded an load multiple instruction.\n");
+        bsp_printf("inst.lsm.Reg_List   = 0x%x\n", inst.lsm.Reg_List);
+
+        bsp_printf("inst.lsm.Rn         = 0x%x\n", inst.lsm.Rn);
+        bsp_printf("inst.lsm.L_bit      = 0x%x\n", inst.lsm.L_bit);
+        bsp_printf("inst.lsm.W_bit      = 0x%x\n", inst.lsm.W_bit);
+        bsp_printf("inst.lsm.S_bit      = 0x%x\n", inst.lsm.S_bit);
+        bsp_printf("inst.lsm.U_bit      = 0x%x\n", inst.lsm.U_bit);
+        bsp_printf("inst.lsm.P_bit      = 0x%x\n", inst.lsm.P_bit);
+        bsp_printf("inst.lsm.rsv1       = 0x%x\n", inst.lsm.rsv1);
+        bsp_printf("inst.lsm.cond       = 0x%x\n", inst.lsm.cond);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+
+        if (inst.lsm.U_bit == 0)
+        {
+            /*
+             * We are using a ascending stack.
+             * That means the PC is actually the register
+             * nearest to Rn currently.
+             */
+            if (inst.lsm.P_bit == 1)
+                /*
+                 * Using a pre-decrement.
+                 */
+                offset_to_pc = -bsp_regsize(REG_PC);
+            else
+                offset_to_pc = 0;
+        } else {
+            /*
+             * We are using an descending stack.
+             * That means the PC is actually the register
+             * farthest from Rn currently.
+             *
+             * Find the number of registers stored before the PC
+             */
+            for (i = 0; i < REG_PC; i++)
+            {
+                if ((inst.lsm.Reg_List & (0x1 << i)) != 0)
+                {
+                    /*
+                     * Bit #i is set.  Increment our count.
+                     */
+                    offset_to_pc += bsp_regsize(i);
+                }
+            }
+
+            /*
+             * Adjust the offset if we do a decrement/increment __BEFORE__
+             * the write.
+             */
+            if (inst.lsm.P_bit == 1)
+                offset_to_pc += bsp_regsize(REG_PC);
+        }
+
+        /*
+         * Now let's calculate the real address of the stored PC
+         * making sure to mask out the two LO bits.
+         */
+        dest = (unsigned long **)((Rn_val + offset_to_pc) & ~0x3);
+
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Rn_val = 0x%08lx\n", Rn_val);
+        bsp_printf("offset_to_pc = 0x%08lx\n", offset_to_pc);
+        bsp_printf("dest = 0x%08lx\n", dest);
+        bsp_printf("*dest = 0x%08lx\n", *dest);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        
+        insert_ss_break(*dest);
+    }
+}
+
+
+/*
+ * Decode all coprocessor data processing instructions
+ */
+static void decode_cpdp_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Can't possibly predict what this instruction will do.
+     * Don't do anything here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all coprocessor register transfer instructions
+ */
+static void decode_cprt_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Can't possibly predict what this instruction will do.
+     * Don't do anything here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all coprocessor load/store instructions
+ */
+static void decode_cpls_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Can't possibly predict what this instruction will do.
+     * Don't do anything here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all branch/branch w/ link instructions
+ */
+static void decode_bbl_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    unsigned long disp = inst.bbl.offset;
+
+    /*
+     * Sign extend the 24 bit value
+     */
+    if (disp & 0x00800000)
+        disp |= 0xff000000;
+    
+    /*
+     * Convert to long words
+     */
+    disp <<= 2;
+
+    /*
+     * Note: when the processor actually executes this instruction, the pc
+     *       will point to the address of the current instruction + 8 because
+     *       of the fetch/decode/execute cycle
+     */
+    disp += 8;
+    
+    insert_ss_break((unsigned long *)(regs->_pc + disp));
+}
+
+
+/*
+ * Decode all swi instructions
+ */
+static void decode_swi_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Can't possibly predict where we should set the breakpoint for this.
+     * Don't do anything here.  Just return.
+     */
+}
+
+
+/*
+ * Decode all undefined instructions
+ */
+static void decode_undef_inst(ex_regs_t *regs, union arm_insn inst)
+{
+    /*
+     * Can't possibly predict what this instruction will do.
+     * Don't do anything here.  Just return.
+     */
+}
+
+
+/*
+ * Set breakpoint instructions for single stepping.
+ */
+void
+bsp_singlestep_setup(void *registers)
+{
+    ex_regs_t *regs = (ex_regs_t *)registers;
+    union arm_insn inst;
+
+    if (bsp_memory_read((void*)(regs->_pc), 0, ARM_INST_SIZE * 8, 1, &(inst.word)) == 0)
+    {
+        /*
+         * Unable to read the instruction at the current address.
+         * Let's not do anything with this.  We can't set breakpoints
+         * so let's get out now.
+         */
+        return;
+    }
+
+    /*
+     * Handle the simple case -- linear code
+     */
+    insert_ss_break((unsigned long *)(regs->_pc + ARM_INST_SIZE));
+
+    /*
+     * Now, we need to decode the instructions and figure out what
+     * they would do.
+     */
+    if ((inst.mrs.rsv1 == MRS_RSV1_VALUE) &&
+        (inst.mrs.rsv2 == MRS_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("MRS type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_mrs_inst(regs, inst);
+    } else if ((inst.misr.rsv1 == MISR_RSV1_VALUE) &&
+               (inst.misr.rsv2 == MISR_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("MISR type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_misr_inst(regs, inst);
+    } else if ((inst.mrsr.rsv1 == MRSR_RSV1_VALUE) &&
+               (inst.mrsr.rsv2 == MRSR_RSV2_VALUE) &&
+               (inst.mrsr.rsv3 == MRSR_RSV3_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("MRSR type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_mrsr_inst(regs, inst);
+    } else if (inst.dpi.rsv1 == DPI_RSV1_VALUE) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("DPI type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_dpi_inst(regs, inst);
+    } else if ((inst.bx.rsv1 == BX_RSV1_VALUE) &&
+               (inst.bx.rsv2 == BX_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("BX type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_bx_inst(regs, inst);
+    } else if ((inst.dpis.rsv1 == DPIS_RSV1_VALUE) &&
+               (inst.dpis.rsv2 == DPIS_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("DPIS type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_dpis_inst(regs, inst);
+    } else if ((inst.dprs.rsv1 == DPRS_RSV1_VALUE) &&
+               (inst.dprs.rsv2 == DPRS_RSV2_VALUE) &&
+               (inst.dprs.rsv3 == DPRS_RSV3_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("DPRS type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_dprs_inst(regs, inst);
+    } else if ((inst.m.rsv1 == M_RSV1_VALUE) &&
+               (inst.m.rsv2 == M_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("M type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_m_inst(regs, inst);
+    } else if ((inst.ml.rsv1 == ML_RSV1_VALUE) &&
+               (inst.ml.rsv2 == ML_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("ML type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_ml_inst(regs, inst);
+    } else if (inst.lsio.rsv1 == LSIO_RSV1_VALUE) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("LSIO type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_lsio_inst(regs, inst);
+    } else if ((inst.lsro.rsv1 == LSRO_RSV1_VALUE) &&
+               (inst.lsro.rsv2 == LSRO_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("LSRO type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_lsro_inst(regs, inst);
+    } else if ((inst.lshwi.rsv1 == LSHWI_RSV1_VALUE) &&
+               (inst.lshwi.rsv2 == LSHWI_RSV2_VALUE) &&
+               (inst.lshwi.rsv3 == LSHWI_RSV3_VALUE) &&
+               (inst.lshwi.rsv4 == LSHWI_RSV4_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("LSHWI type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_lshwi_inst(regs, inst);
+    } else if ((inst.lshwr.rsv1 == LSHWR_RSV1_VALUE) &&
+               (inst.lshwr.rsv2 == LSHWR_RSV2_VALUE) &&
+               (inst.lshwr.rsv3 == LSHWR_RSV3_VALUE) &&
+               (inst.lshwr.rsv4 == LSHWR_RSV4_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("LSHWR type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_lshwr_inst(regs, inst);
+    } else if ((inst.swap.rsv1 == SWAP_RSV1_VALUE) &&
+               (inst.swap.rsv2 == SWAP_RSV2_VALUE) &&
+               (inst.swap.rsv3 == SWAP_RSV3_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("SWAP type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_swap_inst(regs, inst);
+    } else if (inst.lsm.rsv1 == LSM_RSV1_VALUE) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("LSM type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_lsm_inst(regs, inst);
+    } else if ((inst.cpdp.rsv1 == CPDP_RSV1_VALUE) &&
+               (inst.cpdp.rsv2 == CPDP_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("CPDP type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_cpdp_inst(regs, inst);
+    } else if ((inst.cprt.rsv1 == CPRT_RSV1_VALUE) &&
+               (inst.cprt.rsv2 == CPRT_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("CPRT type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_cprt_inst(regs, inst);
+    } else if (inst.cpls.rsv1 == CPLS_RSV1_VALUE) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("CPLS type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_cpls_inst(regs, inst);
+    } else if (inst.bbl.rsv1 == BBL_RSV1_VALUE) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("BBL type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_bbl_inst(regs, inst);
+    } else if (inst.swi.rsv1 == SWI_RSV1_VALUE) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("SWI type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_swi_inst(regs, inst);
+    } else if ((inst.undef.rsv1 == UNDEF_RSV1_VALUE) &&
+               (inst.undef.rsv2 == UNDEF_RSV2_VALUE)) {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("UNDEF type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+        decode_undef_inst(regs, inst);
+    } else {
+#if DEBUG_SINGLESTEP_VERBOSE
+        bsp_printf("Unknown instruction type: 0x%08lx\n", inst.word);
+#endif /* DEBUG_SINGLESTEP_VERBOSE */
+    }
+}
+
+void
+bsp_skip_instruction(void *registers)
+{
+    ex_regs_t *regs = (ex_regs_t *)registers;
+    regs->_pc += ARM_INST_SIZE;
+}
diff --git a/packages/cygmon/v2_0/misc/bsp/bsp.h b/packages/cygmon/v2_0/misc/bsp/bsp.h
new file mode 100644 (file)
index 0000000..ce52e74
--- /dev/null
@@ -0,0 +1,445 @@
+#ifndef __BSP_BSP_H__
+#define __BSP_BSP_H__
+//==========================================================================
+//
+//      bsp.h
+//
+//      Public interface to Red Hat BSP.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Public interface to Red Hat BSP.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#ifndef __ASSEMBLER__
+
+/* needed for _bsp_vsprintf() */
+#include <stdarg.h>
+
+/*
+ * Exception and interrupt handler type.
+ */
+#ifndef _BSP_HANDLER_T_DEFINED
+#define _BSP_HANDLER_T_DEFINED
+typedef int (*bsp_handler_t)(int __irq_nr, void *__regs);
+#endif // _BSP_HANDLER_T_DEFINED
+
+/*
+ *  Vector descriptor. This is needed for chaining vectors. The interfaces use
+ *  bsp_vec structure pointers instead of direct pointers to handlers. This
+ *  puts the responsibility for allocating the bsp_vec structures on the
+ *  caller, rather than the BSP code.
+ */
+typedef struct bsp_vec {
+    bsp_handler_t  handler;    /* pointer to actual ISR */
+    struct bsp_vec *next;      /* for chaining */
+} bsp_vec_t;
+
+/*
+ *  Valid op values for vector install routines.
+ */
+#define BSP_VEC_REPLACE     0
+#define BSP_VEC_CHAIN_FIRST 1
+#define BSP_VEC_CHAIN_LAST  2
+
+/*
+ *  Valid kinds of vectors supported by vector install and remove
+ *  routines.
+ */
+#define BSP_VEC_EXCEPTION 0
+#define BSP_VEC_INTERRUPT 1
+
+/*
+ * Routine to cause a breakpoint exception.
+ */
+extern void bsp_breakpoint(void);
+
+/*
+ * Dummy function whose address is the address of
+ * the breakpoint caused by calling bsp_breakpoint().
+ */
+extern void bsp_breakinsn(void);
+
+/*
+ * Enable given irq.
+ */
+extern void bsp_enable_irq(int __irq_nr);
+
+/*
+ * Disable given irq. Returns true if irq was enabled.
+ */
+extern int  bsp_disable_irq(int __irq_nr);
+
+/*
+ * Remove given vector from vector chain.
+ */
+extern void bsp_remove_vec(int __vec_kind,
+                          int __vec_nr,
+                          bsp_vec_t *__vec);
+
+/*
+ * Install a vector chain.
+ *
+ * vec_kind may be BSP_VEC_EXCEPTION or BSP_VEC_INTERRUPT.
+ * vec_nr is the exception or interrupt number.
+ * op may be one of:
+ *     BSP_VEC_REPLACE - replace existing chain.
+ *     BSP_VEC_CHAIN_FIRST - install at head of chain.
+ *     BSP_VEC_CHAIN_LAST  - install at tail of chain.
+ *
+ */
+extern bsp_vec_t *bsp_install_vec(int __vec_kind,
+                                 int __vec_nr,
+                                 int __op,
+                                 bsp_vec_t *__vec);
+
+/*
+ * Install a debug handler.
+ * Returns old handler being replaced.
+ */
+extern bsp_handler_t bsp_install_dbg_handler(bsp_handler_t __new_handler);
+
+/*
+ * Sometimes it is desireable to call the debug handler directly. This routine
+ * accomplishes that. It is the responsibility of the caller to insure that
+ * interrupts are disabled before calling this routine.
+ */
+extern void bsp_invoke_dbg_handler(int __exc_nr, void *__regs);
+
+/*
+ * Install a 'kill' handler. This handler is called when debugger
+ * issues a kill command.
+ * Returns old handler being replaced.
+ */
+extern bsp_handler_t bsp_install_kill_handler(bsp_handler_t __new_handler);
+
+/*
+ * Architecure specific routine to prepare CPU to execute
+ * a single machine instruction.
+ */
+#ifndef USE_ECOS_HAL_SINGLESTEP
+extern void bsp_singlestep_setup(void *__saved_regs);
+#endif /* USE_ECOS_HAL_SINGLESTEP */
+
+/*
+ * Architecure specific routine to cleanup after a single-step
+ * completes.
+ */
+#ifndef USE_ECOS_HAL_SINGLESTEP
+extern void bsp_singlestep_cleanup(void *__saved_regs);
+#endif /* USE_ECOS_HAL_SINGLESTEP */
+
+/*
+ * Architecture specific routine to skip past the current machine instruction.
+ */
+#ifndef USE_ECOS_HAL_SINGLESTEP
+extern void bsp_skip_instruction(void *__saved_regs);
+#endif /* USE_ECOS_HAL_SINGLESTEP */
+
+/*
+ * Return byte offset within the saved register area of the
+ * given register.
+ */
+extern int bsp_regbyte(int __regno);
+
+/*
+ * Return size in bytes of given register.
+ */
+extern int bsp_regsize(int __regno);
+
+/*
+ * Setup the saved registered to establish the given Program Counter.
+ */
+#ifndef bsp_set_pc
+extern void bsp_set_pc(unsigned long __pc, void *__saved_regs);
+#endif
+
+/*
+ * Get the current Program Counter from the saved registers.
+ */
+#ifndef bsp_get_pc
+unsigned long bsp_get_pc(void *__saved_regs);
+#endif
+
+extern int bsp_memory_read(void *__addr,    /* start addr of memory to read */
+                          int  __asid,     /* address space id */
+                          int  __rsize,    /* size of individual read ops */
+                          int  __nreads,   /* number of read operations */
+                          void *__buf);    /* result buffer */
+
+extern int bsp_memory_write(void *__addr,   /* start addr of memory to write */
+                           int  __asid,    /* address space id */
+                           int  __wsize,   /* size of individual write ops */
+                           int  __nwrites, /* number of write operations */
+                           void *__buf);   /* source buffer for write data */
+
+/*
+ * Architecture specific routines to read and write CPU registers.
+ */
+extern void bsp_set_register(int __regno, void *__saved_regs, void *__val);
+extern void bsp_get_register(int __regno, void *__saved_regs, void *__val);
+
+
+/*
+ * Architecture specific conversion of raw exception info into
+ * a signal value.
+ */
+#ifndef bsp_get_signal
+extern int  bsp_get_signal(int __exc_nr, void *__saved_regs);
+#endif
+
+/* light-weight bsp printf to console port */
+extern void bsp_printf(const char *__fmt, ...);
+
+/* light-weight bsp printf to debug port */
+extern void bsp_dprintf(const char *__fmt, ...);
+
+/* bsp vsprintf */
+extern int bsp_vsprintf(char *__str, const char *__fmt, va_list __ap);
+
+/* bsp vprintf to console port */
+extern void bsp_vprintf(const char *__fmt, va_list __ap);
+
+/* bsp vprintf to debug port */
+extern void bsp_dvprintf(const char *__fmt, va_list __ap);
+
+/* bsp sprintf */
+extern void bsp_sprintf(char *str, const char *fmt, ...);
+
+#ifdef NDEBUG
+#define BSP_ASSERT(e)  ((void)0)
+#else /* NDEBUG */
+extern void _bsp_assert(const char *, const int, const char *);
+#define BSP_ASSERT(e)  ((e) ? (void)0 : _bsp_assert(__FILE__, __LINE__, #e))
+#endif /* NDEBUG */
+
+/*
+ * Functions for low-level console and debug i/o.
+ */
+extern void bsp_console_write(const char *__p, int __len);
+extern void bsp_console_putc(char __ch);
+extern int  bsp_console_read(char *__p, int __len);
+extern int  bsp_console_getc(void);
+extern void bsp_console_ungetc(char ch);
+extern void bsp_debug_write(const char *__p, int __len);
+extern int  bsp_debug_read(char *__p, int __len);
+extern void bsp_debug_putc(char __ch);
+extern int  bsp_debug_getc(void);
+extern void bsp_debug_ungetc(char ch);
+
+/*
+ * Disable interrupts for debug comm channel.
+ * Returns true if interrupts were previously enabled,
+ * false if interrupts were already disabled.
+ */
+extern int  bsp_debug_irq_disable(void);
+extern void bsp_debug_irq_enable(void);
+
+/*
+ * Cache control functions. May be noops for architectures not
+ * supporting caches.
+ *
+ * The icache flush simply invalidates _at_least_ the range of
+ * addresses specified.
+ *
+ * The dcache flush writes back (if write-back cache) and invalidates
+ * _at_least_ the range of addresses specified.
+ *
+ */
+extern void bsp_flush_dcache(void *__p, int __nbytes);
+extern void bsp_flush_icache(void *__p, int __nbytes);
+
+/*
+ * Reset function. May be noops for architectures not
+ * supporting software reset.
+ */
+extern void bsp_reset(void);
+
+/*
+ * Generic data (board and CPU specific) handling
+ */
+extern void *bsp_cpu_data(void);
+extern void *bsp_board_data(void);
+
+/*
+ *  List of board characteristics which can be read queried by BSP clients. These
+ *  information IDs are passed to:
+ *
+ *      int bsp_sysinfo(enum bsp_info_id id, ...);
+ *
+ *  Some pieces of information may have more than one instance. For example, the
+ *  BSP will likely have information on multiple memory regions. In those cases,
+ *  a particular instance may be accessed using a small integer index argument.
+ *
+ *  The following comments indicate what additional arguments are needed
+ *  to access the specific information.
+ */
+enum bsp_info_id {
+    /*
+     * CPU and board names.
+     *
+     * err = bsp_sysinfo(BSP_INFO_PLATFORM,
+     *                   struct bsp_platform_info *result)
+     *
+     *     err => zero if successful, -1 if unsupported.
+     */
+    BSP_INFO_PLATFORM,
+
+    /*
+     * Data, instruction, and secondary caches.
+     *
+     * err = bsp_sysinfo(BSP_INFO_[DIS]CACHE,
+     *                   struct bsp_cache_info *result)
+     *
+     *     err => zero if successful, -1 if unsupported.
+     *
+     */
+    BSP_INFO_DCACHE,
+    BSP_INFO_ICACHE,
+    BSP_INFO_SCACHE,
+
+    /*
+     * Memory region info.
+     *
+     * err = bsp_sysinfo(BSP_INFO_MEMORY,
+     *                   int index,
+     *                   struct bsp_mem_info *result)
+     *
+     *     err => zero if successful, -1 if invalid index.
+     *
+     * Caller should start index at zero, then increment index for subsequent
+     * calls until error return indicates no more memory regions.
+     */
+    BSP_INFO_MEMORY,
+
+    /*
+     * Communication channel info.
+     *
+     * err = bsp_sysinfo(BSP_INFO_COMM,
+     *                   int index,
+     *                   struct bsp_comm_info *result)
+     *
+     *     err => zero if successful, -1 if invalid index.
+     *
+     * Caller should start index at zero, then increment index for subsequent
+     * calls until error return indicates no more comm channels.
+     */
+    BSP_INFO_COMM
+};
+
+
+/*
+ * Platform info.
+ */
+struct bsp_platform_info {
+    const char *cpu;   /* CPU name*/
+    const char *board;  /* board name */ 
+    const char *extra;  /* extra info */
+};
+
+
+/*
+ * Cache size info.
+ */
+struct bsp_cachesize_info {
+    int          size;         /* total size in bytes */
+    short linesize;    /* width of cacheline in bytes */
+    short ways;                /* number of ways per line */
+};
+
+
+/*
+ * Memory region info.
+ * The BSP may describe multiple memory regions. For example,
+ * DRAM may be comprised of several non-contiguous regions.
+ * ROM and FLASH regions may also be described.
+ *
+ */
+struct bsp_mem_info {
+    void *phys_start;  /* physical start address */
+    void *virt_start;   /* virtual start address */
+    int  virt_asid;    /* some architectures also use an address space id */
+    long nbytes;       /* length of region in bytes */
+    int  kind;          /* kind of memory */
+#define BSP_MEM_RAM    1
+#define BSP_MEM_FLASH  2
+#define BSP_MEM_ROM    3
+};
+
+
+struct bsp_comm_info {
+    char    *name;
+    short   kind;
+#define BSP_COMM_SERIAL 1
+#define BSP_COMM_ENET   2
+    short   protocol;
+#define BSP_PROTO_NONE  0
+#define BSP_PROTO_UDP   1
+#define BSP_PROTO_TCP   2
+};
+
+
+extern int bsp_sysinfo(enum bsp_info_id __id, ...);
+
+/*
+ * Set or get active debug and console channels.
+ * Returns -1 if unsucessful.
+ * If the passed in __comm_id is -1, then the id of the current channel
+ * is returned.
+ */
+extern int bsp_set_debug_comm(int __comm_id);
+extern int bsp_set_console_comm(int __comm_id);
+
+/*
+ * Set or get the current baud rate of a serial comm channel.
+ * Returns -1 on if unsuccessful.
+ * If the given baud is -1, then the current baudrate is returned.
+ */
+extern int bsp_set_serial_baud(int __comm_id, int baud);
+
+#endif
+
+#endif // __BSP_BSP_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/common/breakpoint.c b/packages/cygmon/v2_0/misc/bsp/common/breakpoint.c
new file mode 100644 (file)
index 0000000..d893ce0
--- /dev/null
@@ -0,0 +1,97 @@
+//==========================================================================
+//
+//      breakpoint.c
+//
+//      Breakpoint generation.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Breakpoint generation.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <bsp/cpu.h>
+#include <bsp/bsp.h>
+
+#ifndef DEBUG_BREAKPOINT
+#define DEBUG_BREAKPOINT 0
+#endif
+
+#ifdef __ECOS__
+#include <cyg/hal/hal_arch.h>
+#endif /* __ECOS__ */
+
+/*
+ *  Trigger a breakpoint exception.
+ */
+void
+bsp_breakpoint(void)
+{
+#if DEBUG_BREAKPOINT
+    bsp_printf("Before BP\n");
+#endif
+
+#ifdef __ECOS__
+#  ifdef __NEED_UNDERSCORE__
+    HAL_BREAKPOINT(_bsp_breakinsn);
+#  else
+    HAL_BREAKPOINT(bsp_breakinsn);
+#  endif
+#else
+#  ifdef __NEED_UNDERSCORE__
+    asm volatile (".globl _bsp_breakinsn\n"
+                 "_bsp_breakinsn:\n");
+#  else
+    asm volatile (".globl bsp_breakinsn\n"
+                 "bsp_breakinsn:\n");
+#  endif
+    BREAKPOINT();
+#endif
+
+#if DEBUG_BREAKPOINT
+    bsp_printf("After BP\n");
+#endif
+}
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/bsp.c b/packages/cygmon/v2_0/misc/bsp/common/bsp.c
new file mode 100644 (file)
index 0000000..6b77289
--- /dev/null
@@ -0,0 +1,341 @@
+//==========================================================================
+//
+//      bsp.c
+//
+//      General BSP support.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      General BSP support. 
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <stdlib.h>
+#include <bsp/cpu.h>
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+#include "gdb.h"
+
+#ifndef DEBUG_BSP_INIT
+#define DEBUG_BSP_INIT 0
+#endif
+
+struct bsp_comm_channel *_bsp_net_channel = NULL;
+
+/*
+ *  This is the array of pointers to interrupt controller descriptors.
+ */
+static struct bsp_irq_controller *_bsp_ictrl_table[BSP_MAX_IRQ_CONTROLLERS];
+
+/*
+ *  This is the array of second-level exception vectors.
+ */
+static bsp_vec_t *_bsp_exc_table[BSP_MAX_EXCEPTIONS];
+
+
+/*
+ * Debug (default exception) handler vector.
+ */
+bsp_handler_t _bsp_dbg_vector;
+
+
+static bsp_shared_t __bsp_shared = {
+    BSP_SHARED_DATA_VERSION,                                  /* version         */
+    (const struct bsp_irq_controller **)&_bsp_ictrl_table[0], /* __ictrl_table   */
+    &_bsp_exc_table[0],                                       /* __exc_table     */
+    &_bsp_dbg_vector,                                         /* __dbg_vector    */
+    (bsp_handler_t)0,                                         /* __kill_vector   */
+    (struct bsp_comm_procs *)NULL,                            /* __console_procs */
+    (struct bsp_comm_procs *)NULL,                            /* __debug_procs   */
+    (void (*)(void *, int      ))NULL,                        /* __flush_dcache  */
+    (void (*)(void *, int      ))NULL,                        /* __flush_icache  */
+    (void (*)(void             ))NULL,                        /* __reset         */
+    (void*)NULL,                                              /* __cpu_data      */
+    (void*)NULL                                               /* __board_data    */
+};
+
+
+static void
+default_cache_proc(void *p, int nbytes)
+{
+    /* do nothing */
+}
+
+
+static void
+default_reset_proc(void)
+{
+    /* do nothing */
+}
+
+
+static int
+find_comm_id(struct bsp_comm_procs *procs)
+{
+    int i;
+
+    for (i = 0; i < _bsp_num_comms; i++)
+       if (&_bsp_comm_list[i].procs == procs)
+           return i;
+
+    if (procs == &_bsp_net_channel->procs)
+       return _bsp_num_comms;
+
+    return -1;
+}
+
+
+/*
+ * Set or get active debug channel.
+ * Returns -1 if unsucessful.
+ * If the passed in comm id is -1, then the id of the current channel
+ * is returned.
+ */
+static int
+set_debug_comm(int id)
+{
+    struct bsp_comm_channel *chan;
+    struct bsp_comm_procs *procs;
+    int  current_chan = find_comm_id(bsp_shared_data->__debug_procs);
+
+    if (id < 0)
+       return current_chan;
+
+    if (id > _bsp_num_comms)
+       return -1;
+
+    if (id == _bsp_num_comms && _bsp_net_channel == NULL)
+       return -1;
+
+    if (id == current_chan)
+       return 0;
+
+    /* Remove existing channel */
+    if ((procs = bsp_shared_data->__debug_procs) != NULL)
+       (*procs->__control)(procs->ch_data, COMMCTL_REMOVE_DBG_ISR);
+    
+    /* Install new channel */
+    if (id == _bsp_num_comms)
+       chan = _bsp_net_channel;
+    else
+       chan = &_bsp_comm_list[id];
+    bsp_shared_data->__debug_procs = &chan->procs;
+    (*chan->procs.__control)(chan->procs.ch_data, COMMCTL_INSTALL_DBG_ISR);
+
+    return 0;
+}
+
+
+/*
+ * Set or get active console channel.
+ * Returns -1 if unsucessful.
+ * If the passed in comm id is -1, then the id of the current channel
+ * is returned.
+ */
+static int
+set_console_comm(int id)
+{
+    int  current_chan = find_comm_id(bsp_shared_data->__console_procs);
+
+    if (id < 0)
+       return current_chan;
+
+    if (id > _bsp_num_comms)
+       return -1;
+
+    if (id == _bsp_num_comms && _bsp_net_channel == NULL)
+       return -1;
+
+    if (id == current_chan)
+       return 0;
+
+    /*
+     * Install new channel. If its the same as the debug channel,
+     * just clear the __console_procs and the bsp_console_*
+     * interface functions will take care of the rest.
+     */
+    if (id == _bsp_num_comms)
+       bsp_shared_data->__console_procs = &_bsp_net_channel->procs;
+    else
+       bsp_shared_data->__console_procs = &_bsp_comm_list[id].procs;
+
+    if (bsp_shared_data->__console_procs == bsp_shared_data->__debug_procs)
+       bsp_shared_data->__console_procs = NULL;
+
+    return 0;
+}
+
+
+/*
+ * Set or get the current baud rate of a serial comm channel.
+ * Returns -1 on if unsuccessful.
+ * If the given baud is -1, then the current baudrate is returned.
+ */
+int
+set_serial_baud(int id, int baud)
+{
+    struct bsp_comm_channel *chan;
+
+    if (id < 0 || id >= _bsp_num_comms)
+       return -1;
+
+    chan = &_bsp_comm_list[id];
+
+    if (chan->info.kind != BSP_COMM_SERIAL)
+       return -1;
+
+    if (baud == -1)
+       return (*chan->procs.__control)(chan->procs.ch_data,
+                                       COMMCTL_GETBAUD);
+
+    return (*chan->procs.__control)(chan->procs.ch_data,
+                                   COMMCTL_SETBAUD, baud);
+}
+
+/*
+ *  Final initialization before calling main.
+ */
+void
+_bsp_init(void)
+{
+    struct bsp_comm_procs *com;
+    extern void __init_irq_controllers(void);
+
+    bsp_shared_data = &__bsp_shared;
+    _bsp_dbg_vector = (bsp_handler_t)_bsp_gdb_handler;
+    bsp_shared_data->__dbg_data = &_bsp_gdb_data;
+
+    bsp_shared_data->__flush_dcache = default_cache_proc;
+    bsp_shared_data->__flush_icache = default_cache_proc;
+
+    bsp_shared_data->__reset = default_reset_proc;
+
+    /*
+     * General BSP information access.
+     */
+    bsp_shared_data->__sysinfo = _bsp_sysinfo;
+
+    /*
+     * Setup comm port handlers.
+     */
+    bsp_shared_data->__set_debug_comm = set_debug_comm;
+    bsp_shared_data->__set_console_comm = set_console_comm;
+    bsp_shared_data->__set_serial_baud = set_serial_baud;
+
+    /*
+     *  Very first thing is to initialize comm channels so
+     *  we can have debug printfs working. None of this
+     *  must rely on interrupts until interrupt controllers
+     *  are initialized below.
+     */
+    _bsp_init_board_comm();
+
+    /*
+     * Assume first comm channel is the default.
+     */
+    bsp_shared_data->__debug_procs = &_bsp_comm_list[0].procs;
+
+    /*
+     * By default, console i/o goes through the debug channel.
+     * We indicate this by making the console i/o procs
+     * pointer NULL.
+     */
+    bsp_shared_data->__console_procs = NULL;
+
+    /*
+     * Install interrupt controllers.
+     */
+#if DEBUG_BSP_INIT
+    bsp_printf("Installing interrupt controllers...\n");
+#endif
+
+    _bsp_install_cpu_irq_controllers();
+    _bsp_install_board_irq_controllers();
+
+#if DEBUG_BSP_INIT
+    bsp_printf("Done installing interrupt controllers.\n");
+    bsp_printf("Initializing interrupt controllers...\n");
+#endif
+    /*
+     *  Actually run the init routines for all installed
+     *  interrupt controllers.
+     */
+    __init_irq_controllers();
+
+#if DEBUG_BSP_INIT
+    bsp_printf("Done initializing interrupt controllers.\n");
+    bsp_printf("CPU-specific initialization...\n");
+#endif
+
+    /*
+     *  Final architecture specific initialization.
+     */
+    _bsp_cpu_init();
+
+#if DEBUG_BSP_INIT
+    bsp_printf("Done w/ CPU-specific initialization.\n");
+    bsp_printf("Board specific initialization...\n");
+#endif
+    /*
+     *  Final board specific initialization.
+     */
+    _bsp_board_init();
+
+#if DEBUG_BSP_INIT
+    bsp_printf("Done w/ board specific initialization.\n");
+#endif
+
+    /*
+     * Now we can install the debug interrupt handler on the debug channel.
+     */
+    com = bsp_shared_data->__debug_procs;
+    (*com->__control)(com->ch_data, COMMCTL_INSTALL_DBG_ISR);
+
+
+    if (_bsp_net_channel != NULL) {
+       set_debug_comm(_bsp_num_comms);
+       set_console_comm(0);
+    }
+}
diff --git a/packages/cygmon/v2_0/misc/bsp/common/bsp_cache.c b/packages/cygmon/v2_0/misc/bsp/common/bsp_cache.c
new file mode 100644 (file)
index 0000000..c9a5907
--- /dev/null
@@ -0,0 +1,70 @@
+//==========================================================================
+//
+//      bsp_cache.c
+//
+//      BSP Cache Interfaces.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      BSP Cache Interfaces.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include "bsp_if.h"
+
+void
+bsp_flush_dcache(void *p, int nbytes)
+{
+    bsp_shared_data->__flush_dcache(p, nbytes);
+}
+
+
+void
+bsp_flush_icache(void *p, int nbytes)
+{
+    bsp_shared_data->__flush_icache(p, nbytes);
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/bsp_if.c b/packages/cygmon/v2_0/misc/bsp/common/bsp_if.c
new file mode 100644 (file)
index 0000000..9b13c82
--- /dev/null
@@ -0,0 +1,160 @@
+//==========================================================================
+//
+//      bsp_if.c
+//
+//      Miscellaneous BSP Interfaces.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Miscellaneous BSP Interfaces.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+
+/*
+ * Install a debug handler.
+ * Returns old handler being replaced.
+ */
+bsp_handler_t
+bsp_install_dbg_handler(bsp_handler_t new_handler)
+{
+    bsp_handler_t old_handler;
+
+    old_handler = *bsp_shared_data->__dbg_vector;
+    *bsp_shared_data->__dbg_vector = new_handler;
+
+    return old_handler;
+}
+
+/*
+ * Sometimes it is desireable to call the debug handler directly. This routine
+ * accomplishes that. It is the responsibility of the caller to insure that
+ * interrupts are disabled before calling this routine.
+ */
+void
+bsp_invoke_dbg_handler(int exc_nr, void *regs)
+{
+    (*bsp_shared_data->__dbg_vector)(exc_nr, regs);
+}
+
+/*
+ * Install a 'kill' handler.
+ * Returns old handler being replaced.
+ */
+bsp_handler_t
+bsp_install_kill_handler(bsp_handler_t new_handler)
+{
+    bsp_handler_t old_handler;
+
+    old_handler = bsp_shared_data->__kill_vector;
+    bsp_shared_data->__kill_vector = new_handler;
+
+    return old_handler;
+}
+
+
+void *
+bsp_cpu_data(void)
+{
+  return bsp_shared_data->__cpu_data;
+}
+
+
+void *
+bsp_board_data(void)
+{
+    return bsp_shared_data->__board_data;
+}
+
+
+int
+bsp_sysinfo(enum bsp_info_id id, ...)
+{
+    int     retval;
+    va_list ap;
+
+    va_start (ap, id);
+    retval = bsp_shared_data->__sysinfo(id, ap);
+    va_end(ap);
+    return retval;
+}
+
+int
+bsp_set_debug_comm(int id)
+{
+    return bsp_shared_data->__set_debug_comm(id);
+}
+
+int
+bsp_set_console_comm(int id)
+{
+    return bsp_shared_data->__set_console_comm(id);
+}
+
+int
+bsp_set_serial_baud(int id, int baud)
+{
+    return bsp_shared_data->__set_serial_baud(id, baud);
+}
+
+
+#if !defined(NDEBUG)
+
+void _bsp_assert(const char *file, const int line, const char *condition)
+{
+    bsp_printf("Assertion \"%s\" failed\n", condition);
+    bsp_printf("File \"%s\"\n", file);
+    bsp_printf("Line %d\n", line);
+#if defined(PORT_TOGGLE_DEBUG)
+    PORT_TOGGLE_DEBUG();
+#else
+    while(1) ;
+#endif /* defined(PORT_TOGGLE_DEBUG) */
+}
+
+#endif /* !defined(NDEBUG) */
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/bsp_if.h b/packages/cygmon/v2_0/misc/bsp/common/bsp_if.h
new file mode 100644 (file)
index 0000000..268b196
--- /dev/null
@@ -0,0 +1,433 @@
+#ifndef __BSP_COMMON_BSP_IF_H__
+#define __BSP_COMMON_BSP_IF_H__
+//==========================================================================
+//
+//      bsp_if.h
+//
+//      BSP interface definitions.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      BSP interface definitions.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <bsp/bsp.h>
+
+/*
+ *  Maximum number of interrupt controllers supported by
+ *  this bsp.
+ */
+#define BSP_MAX_IRQ_CONTROLLERS 8
+
+#ifndef __ASSEMBLER__
+
+
+/*
+ *  Interrupt controller abstraction.
+ *  Each interrupt controller on a given board should be described using
+ *  this data structure.
+ */
+struct bsp_irq_controller {
+    /*
+     * First and last irqs handled by this controller.
+     */
+    short      first;
+    short      last;
+
+    /* 
+     * pointer to array of bsp_vec struct pointers. These are
+     * the heads of the linked list of ISRs for each irq handled
+     * by this controller.
+     */
+    bsp_vec_t  **vec_list;
+
+    /*
+     * Pointer to initialization routine which is run once at boot time.
+     */
+    void       (*init)(const struct bsp_irq_controller *__ic);
+
+    /*
+     * Pointer to routines used to disable and enable interrupts handled
+     * by this controller.
+     */
+    int                (*disable)(const struct bsp_irq_controller *__ic,
+                          int __irq_nr);
+    void       (*enable)(const struct bsp_irq_controller *__ic,
+                         int __irq_nr);
+};
+
+
+/*
+ * Board specific code needs to provide at least one communication channel
+ * for use as the debug and console (stdio) channel. For each channel,
+ * there must be a set of function vectors for the common BSP code to
+ * control the channel.
+ */
+struct bsp_comm_procs {
+    /*
+     * Implementation dependent data pointer passed to the following procs.
+     */
+    void *ch_data;
+
+    /*
+     * Write a buffer of the given length. All of buffer is sent before
+     * the write call returns.
+     */
+    void (*__write)(void *ch_data, const char *buf, int len);
+
+    /*
+     * Fill a buffer with up to the given length. Returns the actual number
+     * of characters read.
+     */
+    int  (*__read)(void *ch_data, char *buf, int len);
+
+    /*
+     * Send a single character.
+     */
+    void (*__putc)(void *ch_data, char ch);
+
+    /*
+     * Read a single character. If no character is immediately available, will
+     * block until one becomes available.
+     */
+    int  (*__getc)(void *ch_data);
+
+    /*
+     * Catchall comm port control.
+     */
+    int  (*__control)(void *ch_data, int func, ...);
+
+    /*
+     * For serial ports, the control function may be used to set and get the
+     * current baud rate. Usage:
+     * 
+     *   err = (*__control)(COMMCTL_SETBAUD, int bits_per_second);
+     *     err => Zero if successful, -1 if error.
+     *
+     *   baud = (*__control)(COMMCTL_GETBAUD);
+     *     baud => -1 if error, current baud otherwise.
+     */
+#define COMMCTL_SETBAUD 0
+#define COMMCTL_GETBAUD 1
+
+    /*
+     * Install and remove debugger interrupt handlers. These are the receiver
+     * interrupt routines which are used to change control from a running
+     * program to the debugger stub.
+     */
+#define COMMCTL_INSTALL_DBG_ISR 2
+#define COMMCTL_REMOVE_DBG_ISR  3
+
+    /*
+     * Disable comm port interrupt. Returns TRUE if interrupt was enabled,
+     * FALSE otherwise.
+     */
+#define COMMCTL_IRQ_DISABLE 4
+    /*
+     * Enable comm port interrupt.
+     */
+#define COMMCTL_IRQ_ENABLE 5
+};
+
+
+/*
+ * The board specific code uses this data structure to provide information
+ * about and procedure vectors for each supported communication channel.
+ * See _bsp_comm_list below.
+ */
+struct bsp_comm_channel {
+    struct bsp_comm_info   info;
+    struct bsp_comm_procs  procs;
+};
+
+
+/*
+ * Number to place in the version field. If structure is changed
+ * in a way which is not backwards compatible, this number should
+ * be incremented.
+ */
+#define BSP_SHARED_DATA_VERSION 2
+
+/*
+ * Clients of this BSP will need to have access to BSP functions and
+ * data structures. Because, the client and the BSP may not be linked
+ * together, a structure of vectors is used to gain this access. A
+ * pointer to this structure can be gotten via a syscall. This syscall
+ * is made automatically from within the crt0.o file.
+ */
+typedef struct {
+    int                version;        /* version number for future expansion */
+
+    /*
+     *  Pointer to the array of pointers to interrupt controller descriptors.
+     */
+    const struct bsp_irq_controller **__ictrl_table;
+
+    /*
+     *  Pointer to the array of exception vectors.
+     */
+    bsp_vec_t **__exc_table;
+
+    /*
+     * Pointer to debug handler vector.
+     */
+    bsp_handler_t *__dbg_vector;
+
+    /*
+     * User hook to catch debugger 'kill' command.
+     */
+    bsp_handler_t __kill_vector;
+
+    /*
+     * Vectored functions for console and debug i/o.
+     */
+    struct bsp_comm_procs *__console_procs;
+    struct bsp_comm_procs *__debug_procs;
+
+    /*
+     * Vectored cache control functions.
+     */
+    void (*__flush_dcache)(void *__p, int __nbytes);
+    void (*__flush_icache)(void *__p, int __nbytes);
+
+    /*
+     * Generic data pointers
+     */
+    void *__cpu_data;
+    void *__board_data;
+
+    /*
+     * General BSP information access.
+     * See bsp.h for details.
+     */
+    int  (*__sysinfo)(enum bsp_info_id __id, va_list __ap);
+
+    /*
+     * Set or get active debug and console channels.
+     * Returns -1 if unsucessful.
+     * If the passed in __comm_id is -1, then the id of the current channel
+     * is returned.
+     */
+    int         (*__set_debug_comm)(int __comm_id);
+    int         (*__set_console_comm)(int __comm_id);
+
+    /*
+     * Set or get the current baud rate of a serial comm channel.
+     * Returns -1 on if unsuccessful.
+     * If the given baud is -1, then the current baudrate is returned.
+     */
+    int  (*__set_serial_baud)(int __comm_id, int baud);
+
+    /*
+     * Debug agent data.
+     */
+    void *__dbg_data;
+
+    /*
+     * Reset function
+     * We want to avoid calling this with a trap since
+     * we may be calling it from SWI mode (in cygmon).
+     * That is problematic, as nested SWI's are not
+     * very good.
+     */
+    void (*__reset)(void);
+
+    /*
+     * TRUE if console interrupt detected during program output.
+     */
+    int  __console_interrupt_flag;
+
+} bsp_shared_t;
+
+
+extern bsp_shared_t *bsp_shared_data;
+
+/*
+ * Platform info which may be overriden/modified by arch/board specific code.
+ */
+extern struct bsp_platform_info _bsp_platform_info;
+
+/*
+ * Cache info which may be overriden/modified by arch/board specific code.
+ */
+extern struct bsp_cachesize_info _bsp_dcache_info;
+extern struct bsp_cachesize_info _bsp_icache_info;
+extern struct bsp_cachesize_info _bsp_scache_info;
+
+/*
+ * Array of comm channel descriptors which must be provided by board specific
+ * code.
+ */
+extern struct bsp_comm_channel _bsp_comm_list[];
+
+/*
+ * Number of comm channel descriptors which must be provided by board specific
+ * code.
+ */
+extern int _bsp_num_comms;
+
+
+/*
+ * Array of memory region descriptors which must be provided by board specific
+ * code.
+ */
+extern struct bsp_mem_info _bsp_memory_list[];
+
+/*
+ * Number of memory region descriptors which must be provided by board specific
+ * code.
+ */
+extern int _bsp_num_mem_regions;
+
+/*
+ * In order to construct the above _bsp_memory_list, some board specific
+ * code may have to size RAM regions. To do this easily and reliably,
+ * the code needs to run from ROM before .bss and .data sections are
+ * initialized. This leads to the problem of where to store the results
+ * of the memory sizing tests. In this case, the _bsp_init_stack routine
+ * which sizes memory and sets up the stack will place the board-specific
+ * information on the stack and return with the stack pointer pointing to
+ * a pointer to the information. That is, addr_of_info = *(void **)sp.
+ * The architecture specific code will then copy that pointer to the
+ * _bsp_ram_info_ptr variable after initializing the .data and .bss sections.
+ */
+extern void *_bsp_ram_info_ptr;
+
+/*
+ * Generic bsp initialization. Called by low level startup code
+ */
+extern void _bsp_init(void);
+
+/*
+ *  Initialize board communication in polling mode. This enables
+ *  debugging printf for later initializations. Interrupts for
+ *  comm channels may be set up later in _bsp_board_init().
+ */
+extern void _bsp_init_board_comm(void);
+
+/*
+ * Make generic BSP aware of CPU/MCU specific interrupt controllers.
+ */
+extern void _bsp_install_cpu_irq_controllers(void);
+
+/*
+ * Make generic BSP aware of board specific interrupt controllers.
+ */
+extern void _bsp_install_board_irq_controllers(void);
+
+/*
+ * Callback used by above two routines to install a single
+ * interrupt controller.
+ */
+extern void _bsp_install_irq_controller(const struct bsp_irq_controller *__ic);
+
+/*
+ *  Generic exception dispatch routine. Usually called from asm-level
+ *  exception handler to call vectors in vector chain for the given
+ *  exception number. Stops traversing vector chain when a called
+ *  vector returns a non-zero value. If no vector returns non-zero,
+ *  a default error message and register dump is printed.
+ */
+extern int _bsp_exc_dispatch(int __exc_number, void *__regs);
+
+
+/*
+ * Architecture specific routine to dump register values.
+ */
+extern void _bsp_dump_regs(void *__regs);
+
+
+/*
+ * Generic syscall handler called by architecture specific handler.
+ * Returns non-zero if given 'func' number was handled by the generic
+ * code, zero otherwise. If handled, the syscall error is returned
+ * via the err_ptr.
+ */
+extern int  _bsp_do_syscall(int __func,
+                           long __arg1, long __arg2, long __arg3, long __arg4,
+                           int *__err_ptr);
+
+
+extern void _bsp_cpu_init(void);
+extern void _bsp_board_init(void);
+
+
+/*
+ * General interface for getting certain BSP parameters.
+ * See bsp.h for details.
+ */
+extern int  _bsp_sysinfo(enum bsp_info_id __id, va_list __ap);
+
+/*
+ * Called from comm channel when a connection to host is closed.
+ */
+extern void _bsp_dbg_connect_abort(void);
+  
+
+/*
+ * Pointer to a network channel. NULL if no network channel
+ * exists.
+ */
+extern struct bsp_comm_channel *_bsp_net_channel;
+
+
+/*
+ * Formatted output primitive.
+ */
+extern void __vprintf(void (*putc_func)(char c), const char *fmt0, va_list ap);
+
+
+
+#endif /* !__ASSEMBLER__ */
+
+/*
+ * SYSCALL number to use to get pointer to above bsp_shared_t structure.
+ */
+#define BSP_GET_SHARED  0xbaad
+
+#endif // __BSP_COMMON_BSP_IF_H__
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/console-io.c b/packages/cygmon/v2_0/misc/bsp/common/console-io.c
new file mode 100644 (file)
index 0000000..ad0450a
--- /dev/null
@@ -0,0 +1,140 @@
+//==========================================================================
+//
+//      console-io.c
+//
+//      BSP Console Channel Interfaces.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      BSP Console Channel Interfaces.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <stdlib.h>
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+
+static unsigned char __console_ungetc;
+
+void
+bsp_console_write(const char *p, int len)
+{
+    struct bsp_comm_procs *com;
+
+    if ((com = bsp_shared_data->__console_procs) != NULL)
+       com->__write(com->ch_data, p, len);
+    else
+       bsp_debug_write(p, len);
+}
+
+
+int
+bsp_console_read(char *p, int len)
+{
+    struct bsp_comm_procs *com;
+
+    if (len <= 0)
+       return 0;
+
+    if ((com = bsp_shared_data->__console_procs) != NULL) {
+       if (__console_ungetc) {
+           *p = __console_ungetc;
+           __console_ungetc = 0;
+           return 1;
+       }
+       return com->__read(com->ch_data, p, len);
+    } else
+       return bsp_debug_read(p, len);
+}
+
+/*#define PRINTABLE_ONLY*/
+#ifdef PRINTABLE_ONLY
+#include <ctype.h>
+#endif /* PRINTABLE_ONLY */
+
+void
+bsp_console_putc(char ch)
+{
+    struct bsp_comm_procs *com;
+
+#ifdef PRINTABLE_ONLY
+    if ((!isprint(ch)) && (!isspace(ch)))
+        ch = '.';
+#endif /* PRINTABLE_ONLY */
+
+    if ((com = bsp_shared_data->__console_procs) != NULL)
+       com->__putc(com->ch_data, ch);
+    else
+       bsp_debug_putc(ch);
+}
+
+int
+bsp_console_getc(void)
+{
+    struct bsp_comm_procs *com;
+    int    ch;
+
+    if ((com = bsp_shared_data->__console_procs) != NULL) {
+       if (__console_ungetc) {
+           ch = __console_ungetc;
+           __console_ungetc = 0;
+           return ch;
+       }
+       return com->__getc(com->ch_data);
+    } else
+       return bsp_debug_getc();
+}
+
+
+void
+bsp_console_ungetc(char ch)
+{
+    if (bsp_shared_data->__console_procs != NULL)
+       __console_ungetc = (unsigned char)ch;
+    else
+       bsp_debug_ungetc(ch);
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/debug-io.c b/packages/cygmon/v2_0/misc/bsp/common/debug-io.c
new file mode 100644 (file)
index 0000000..6d66771
--- /dev/null
@@ -0,0 +1,142 @@
+//==========================================================================
+//
+//      debug-io.c
+//
+//      BSP Debug Channel Interfaces.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      BSP Debug Channel Interfaces.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <stdlib.h>
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+
+static unsigned char __debug_ungetc;
+
+extern int stub_is_active;
+extern int __output_gdb_string (const char *str, int string_len);
+void
+bsp_debug_write(const char *p, int len)
+{
+    struct bsp_comm_procs *com = bsp_shared_data->__debug_procs;
+    if (stub_is_active) {
+        // We are running in 'GDB' mode
+        __output_gdb_string(p, len);
+    } else {
+        com->__write(com->ch_data, p, len);
+    }
+}
+
+
+int
+bsp_debug_read(char *p, int len)
+{
+    struct bsp_comm_procs *com = bsp_shared_data->__debug_procs;
+
+    if (len <= 0)
+       return 0;
+
+    if (__debug_ungetc) {
+       *p = __debug_ungetc;
+       __debug_ungetc = 0;
+       return 1;
+    }
+
+    return com->__read(com->ch_data, p, len);
+}
+
+
+void
+bsp_debug_putc(char ch)
+{
+    struct bsp_comm_procs *com = bsp_shared_data->__debug_procs;
+
+    com->__putc(com->ch_data, ch);
+}
+
+int
+bsp_debug_getc(void)
+{
+    struct bsp_comm_procs *com = bsp_shared_data->__debug_procs;
+    int  ch;
+
+    if (__debug_ungetc) {
+       ch = __debug_ungetc;
+       __debug_ungetc = 0;
+    } else
+       ch = com->__getc(com->ch_data);
+
+    return ch;
+}
+
+
+void
+bsp_debug_ungetc(char ch)
+{
+    __debug_ungetc = (unsigned char)ch;
+}
+
+
+int
+bsp_debug_irq_disable(void)
+{
+    struct bsp_comm_procs *com = bsp_shared_data->__debug_procs;
+
+    return com->__control(com->ch_data, COMMCTL_IRQ_DISABLE);
+}
+
+
+void
+bsp_debug_irq_enable(void)
+{
+    struct bsp_comm_procs *com = bsp_shared_data->__debug_procs;
+
+    com->__control(com->ch_data, COMMCTL_IRQ_ENABLE);
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/gdb-cpu.c b/packages/cygmon/v2_0/misc/bsp/common/gdb-cpu.c
new file mode 100644 (file)
index 0000000..610b6b5
--- /dev/null
@@ -0,0 +1,61 @@
+//==========================================================================
+//
+//      gdb-cpu.c
+//
+//      Architecture specific support for GDB
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+#include <pkgconf/system.h>
+
+#ifdef CYGPKG_HAL_ARM
+#include "bsp/arm/gdb-cpu.c"
+#endif
+
+#ifdef CYGPKG_HAL_MIPS
+#include "bsp/mips/gdb-cpu.c"
+#endif
diff --git a/packages/cygmon/v2_0/misc/bsp/common/gdb-cpu.h b/packages/cygmon/v2_0/misc/bsp/common/gdb-cpu.h
new file mode 100644 (file)
index 0000000..75821cb
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef __BSP_COMMON_GDB_CPU_H__
+#define __BSP_COMMON_GDB_CPU_H__
+//==========================================================================
+//
+//      gdb-cpu.h
+//
+//      CPU specifics for GDB
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+#include <pkgconf/system.h>
+
+#ifdef CYGPKG_HAL_ARM
+#include "../arm/gdb-cpu.h"
+#endif
+
+#ifdef CYGPKG_HAL_MIPS
+#include "../mips/gdb-cpu.h"
+#endif
+
+#endif // __BSP_COMMON_GDB_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/common/gdb.h b/packages/cygmon/v2_0/misc/bsp/common/gdb.h
new file mode 100644 (file)
index 0000000..1ade0ff
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef __BSP_COMMON_GDB_H__
+#define __BSP_COMMON_GDB_H__
+//==========================================================================
+//
+//      gdb.h
+//
+//      Definitions for GDB stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Definitions for GDB stub.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include "gdb-cpu.h"
+#include <bsp/gdb-data.h>
+
+#ifndef DEBUG_STUB
+#define DEBUG_STUB 0
+#endif
+
+/*
+ *  These need to match the same in devo/gdb/target.h
+ */
+#define  TARGET_SIGNAL_INT  2
+#define  TARGET_SIGNAL_ILL  4
+#define  TARGET_SIGNAL_TRAP 5
+#define  TARGET_SIGNAL_ABRT 6
+#define  TARGET_SIGNAL_FPE  8
+#define  TARGET_SIGNAL_BUS  10
+#define  TARGET_SIGNAL_SEGV 11
+
+
+/*
+ *  Socket to use for tcp/ip debug channel.
+ */
+#define GDB_TCP_SOCKET  1000
+
+
+#ifndef __ASSEMBLER__
+
+/* generic gdb protocol handler */
+extern void _bsp_gdb_handler(int exc_nr, void *saved_regs);
+extern gdb_data_t _bsp_gdb_data;
+
+
+/* start forming an outgoing gdb packet */
+/* if ack is true, prepend an ack character */
+extern void _gdb_pkt_start(int ack);
+
+/* Append data to packet using formatted string. */
+extern void _gdb_pkt_append(char *fmt, ...);
+
+/* Calculate checksum and append to end of packet. */
+extern void _gdb_pkt_end(void);
+
+/* Send the packet. Blocks waiting for ACK */
+extern void _gdb_pkt_send(void);
+#endif
+
+#endif //__BSP_COMMON_GDB_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/common/generic-mem.c b/packages/cygmon/v2_0/misc/bsp/common/generic-mem.c
new file mode 100644 (file)
index 0000000..53c1985
--- /dev/null
@@ -0,0 +1,194 @@
+//==========================================================================
+//
+//      generic-mem.c
+//
+//      Generic support for safe memory read/write.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Generic support for safe memory read/write.
+// Description:  Some targets may need to provide their own version.
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <stdlib.h>
+#include <setjmp.h>
+#include <bsp/bsp.h>
+
+typedef void (*moveproc_t)(void *s, void *d);
+
+static jmp_buf __errjmp;
+
+/*
+ * These are globals because we want them preserved
+ * across function calls.
+ */
+static bsp_handler_t __oldtrap;
+static int __done;
+
+
+static void
+move_8(void *src, void *dest)
+{
+    *(char *)dest = *(char *)src;
+}
+
+
+static void
+move_16(void *src, void *dest)
+{
+    *(short *)dest = *(short *)src;
+}
+
+
+static void
+move_32(void *src, void *dest)
+{
+    *(int *)dest = *(int *)src;
+}
+
+
+static int
+err_trap(int exc_nr, void *regs)
+{
+    longjmp(__errjmp, 1);
+}
+
+
+int
+bsp_memory_read(void *addr,    /* start addr of memory to read */
+               int  asid,     /* address space id */
+               int  rsize,    /* size of individual read operation */
+               int  nreads,   /* number of read operations */
+               void *buf)     /* result buffer */
+{
+    if (nreads <= 0)
+       return 0;
+
+    __oldtrap = bsp_install_dbg_handler(err_trap);
+    
+    if (setjmp(__errjmp) == 0) {
+       moveproc_t move_mem;
+       int        incr;
+       char       *src, *dest;
+
+       switch (rsize) {
+         case 8:
+           move_mem = move_8;
+           incr = 1;
+           break;
+         case 16:
+           move_mem = move_16;
+           incr = 2;
+           break;
+         case 32:
+           move_mem = move_32;
+           incr = 4;
+           break;
+         default:
+           (void)bsp_install_dbg_handler(__oldtrap);
+           return 0;
+       }
+
+       src = addr;
+       dest = buf;
+
+       for (__done = 0; __done < nreads; __done++) {
+           move_mem(src, dest);
+           src  += incr;
+           dest += incr;
+       }
+    }
+
+    (void)bsp_install_dbg_handler(__oldtrap);
+    return __done;
+}
+
+
+int bsp_memory_write(void *addr,   /* start addr of memory to write */
+                     int  asid,    /* address space id */
+                     int  wsize,   /* size of individual write operation */
+                     int  nwrites, /* number of write operations */
+                     void *buf)    /* source buffer for write data */
+{
+    if (nwrites <= 0)
+       return 0;
+
+    __oldtrap = bsp_install_dbg_handler(err_trap);
+    
+    if (setjmp(__errjmp) == 0) {
+       moveproc_t move_mem;
+       int        incr;
+       char       *src, *dest;
+
+       switch (wsize) {
+         case 8:
+           move_mem = move_8;
+           incr = 1;
+           break;
+         case 16:
+           move_mem = move_16;
+           incr = 2;
+           break;
+         case 32:
+           move_mem = move_32;
+           incr = 4;
+           break;
+         default:
+           (void)bsp_install_dbg_handler(__oldtrap);
+           return 0;
+       }
+
+       src = buf;
+       dest = addr;
+
+       for (__done = 0; __done < nwrites; __done++) {
+           move_mem(src, dest);
+           src  += incr;
+           dest += incr;
+       }
+    }
+
+    (void)bsp_install_dbg_handler(__oldtrap);
+    return __done;
+}
diff --git a/packages/cygmon/v2_0/misc/bsp/common/hex-utils.c b/packages/cygmon/v2_0/misc/bsp/common/hex-utils.c
new file mode 100644 (file)
index 0000000..5cb2c4c
--- /dev/null
@@ -0,0 +1,126 @@
+//==========================================================================
+//
+//      hex-utils.c
+//
+//      Utilities for dealing with hexadecimal strings.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <bsp/hex-utils.h>
+
+int
+__hex(char ch)
+{
+    if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
+    if ((ch >= '0') && (ch <= '9')) return (ch-'0');
+    if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
+    return (-1);
+}
+
+
+/*
+ * Convert the hex data in 'buf' into 'count' bytes to be placed in 'mem'.
+ * Returns a pointer to the character in mem AFTER the last byte written.
+ */
+char *
+__unpack_bytes_to_mem(char *buf, char *mem, int count)
+{
+    int  i;
+    char ch;
+
+    for (i = 0; i < count; i++) {
+       ch = __hex(*buf++) << 4;
+       ch = ch + __hex(*buf++);
+       *mem++ = ch;
+    }
+    return(mem);
+}
+
+/*
+ * While finding valid hex chars, build an unsigned long int.
+ * Return number of hex chars processed.
+ */
+int
+__unpack_ulong(char **ptr, unsigned long *val)
+{
+    int numChars = 0;
+    int hexValue;
+    
+    *val = 0;
+
+    while (**ptr) {
+       hexValue = __hex(**ptr);
+       if (hexValue >= 0) {
+           *val = (*val << 4) | hexValue;
+           numChars ++;
+       } else
+           break;
+       (*ptr)++;
+    }
+    return (numChars);
+}
+
+
+/*
+ * Unpack 'count' hex characters, forming them into a binary value.
+ * Return that value as an int. Adjust the source pointer accordingly.
+ */
+int
+__unpack_nibbles(char **ptr, int count)
+{
+    int value = 0;
+
+    while (--count >= 0) {
+       value = (value << 4) | __hex(**ptr);
+       (*ptr)++;
+    }
+    return value;
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/printf.c b/packages/cygmon/v2_0/misc/bsp/common/printf.c
new file mode 100644 (file)
index 0000000..d8fdea1
--- /dev/null
@@ -0,0 +1,95 @@
+//==========================================================================
+//
+//      printf.c
+//
+//      Light-weight BSP printf.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Light-weight BSP printf.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+
+
+void
+bsp_vprintf(const char *fmt, va_list ap)
+{
+    __vprintf(bsp_console_putc, fmt, ap);
+}
+
+
+void
+bsp_dvprintf(const char *fmt, va_list ap)
+{
+    __vprintf(bsp_debug_putc, fmt, ap);
+}
+
+
+void
+bsp_printf(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start (ap, fmt);
+    __vprintf(bsp_console_putc, fmt, ap);
+    va_end (ap);
+}
+
+
+void
+bsp_dprintf(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start (ap, fmt);
+    __vprintf(bsp_debug_putc, fmt, ap);
+    va_end (ap);
+}
+
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/shared-data.c b/packages/cygmon/v2_0/misc/bsp/common/shared-data.c
new file mode 100644 (file)
index 0000000..281a103
--- /dev/null
@@ -0,0 +1,59 @@
+//==========================================================================
+//
+//      shared-data.c
+//
+//      Declaration of bsp shared data pointer.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Declaration of bsp shared data pointer.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include "bsp_if.h"
+
+bsp_shared_t *bsp_shared_data;
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/singlestep.c b/packages/cygmon/v2_0/misc/bsp/common/singlestep.c
new file mode 100644 (file)
index 0000000..04cbc0b
--- /dev/null
@@ -0,0 +1,61 @@
+//==========================================================================
+//
+//      singlestep.c
+//
+//      Architecture specific single-step support
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:
+// Description: 
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+#include <pkgconf/system.h>
+
+#ifdef CYGPKG_HAL_ARM
+#include "bsp/arm/singlestep.c"
+#endif
+
+#ifdef CYGPKG_HAL_MIPS
+#include "bsp/mips/singlestep.c"
+#endif
diff --git a/packages/cygmon/v2_0/misc/bsp/common/sprintf.c b/packages/cygmon/v2_0/misc/bsp/common/sprintf.c
new file mode 100644 (file)
index 0000000..b05645b
--- /dev/null
@@ -0,0 +1,86 @@
+//==========================================================================
+//
+//      sprintf.c
+//
+//      Light-weight BSP sprintf.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Light-weight BSP sprintf.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+
+static char *str_ptr;
+
+static void
+str_putc(char ch)
+{
+    *str_ptr++ = ch;
+}
+
+int
+bsp_vsprintf(char *str, const char *fmt, va_list ap)
+{
+    str_ptr = str;
+    __vprintf(str_putc, fmt, ap);
+    *str_ptr = '\0';
+    return str_ptr - str;
+}
+
+
+void
+bsp_sprintf(char *str, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start (ap, fmt);
+    bsp_vsprintf(str, fmt, ap);
+    va_end (ap);
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/syscall.c b/packages/cygmon/v2_0/misc/bsp/common/syscall.c
new file mode 100644 (file)
index 0000000..120f722
--- /dev/null
@@ -0,0 +1,218 @@
+//==========================================================================
+//
+//      syscall.c
+//
+//      Minimal generic syscall support.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Minimal generic syscall support.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <errno.h>
+#include <bsp/cpu.h>
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+#include "syscall.h"
+
+/*
+ * read  -- read bytes from the serial port. Ignore fd, since
+ *          we only have stdin.
+ */
+static int
+sys_read(int fd, char *buf, int nbytes)
+{
+    int i = 0;
+
+    for (i = 0; i < nbytes; i++) {
+       *(buf + i) = bsp_console_getc();
+       if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
+           (*(buf + i + 1)) = 0;
+           break;
+       }
+    }
+    return (i);
+}
+
+
+/*
+ * write -- write bytes to the serial port. Ignore fd, since
+ *          stdout and stderr are the same. Since we have no filesystem,
+ *          open will only return an error.
+ */
+static int
+sys_write(int fd, char *buf, int nbytes)
+{
+#define WBUFSIZE  256
+    char ch, lbuf[WBUFSIZE];
+    int  i, tosend;
+
+    tosend = nbytes;
+
+    while (tosend > 0) {
+       for (i = 0; tosend > 0 && i < (WBUFSIZE-2); tosend--) {
+           ch = *buf++;
+           if (ch == '\n')
+               lbuf[i++] = '\r';
+           lbuf[i++] = ch;
+       }
+       bsp_console_write(lbuf, i);
+    }
+
+    return (nbytes);
+}
+
+
+/*
+ * open -- open a file descriptor. We don't have a filesystem, so
+ *         we return an error.
+ */
+static int
+sys_open (const char *buf, int flags, int mode)
+{
+    return (-EIO);
+}
+
+
+/*
+ * close -- We don't need to do anything, but pretend we did.
+ */
+static int
+sys_close(int fd)
+{
+    return (0);
+}
+
+
+/*
+ * lseek --  Since a serial port is non-seekable, we return an error.
+ */
+static int
+sys_lseek(int fd,  int offset, int whence)
+{
+#ifdef ESPIPE
+    return (-ESPIPE);
+#else
+    return (-EIO);
+#endif
+}
+
+
+/*
+ *  Generic syscall handler.
+ *
+ *  Returns 0 if syscall number is not handled by this
+ *  module, 1 otherwise. This allows applications to
+ *  extend the syscall handler by using exception chaining.
+ */
+int
+_bsp_do_syscall(int func,              /* syscall function number */
+               long arg1, long arg2,   /* up to four args.        */
+               long arg3, long arg4,
+               int *retval)            /* syscall return value    */
+{
+    int err = 0;
+
+    switch (func) {
+
+      case SYS_read:
+       err = sys_read((int)arg1, (char *)arg2, (int)arg3);
+       break;
+
+      case SYS_write:
+       err = sys_write((int)arg1, (char *)arg2, (int)arg3);
+       break;
+
+      case SYS_open:
+       err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
+       break;
+
+      case SYS_close:
+       err = sys_close((int)arg1);
+       break;
+
+      case SYS_lseek:
+       err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
+       break;
+
+      case BSP_GET_SHARED:
+       *(bsp_shared_t **)arg1 = bsp_shared_data;
+       break;
+
+      case SYS_meminfo:
+        {
+          // Return the top and size of memory.
+          struct bsp_mem_info      mem;
+          int                      i;
+          unsigned long            u, totmem, topmem, numbanks;
+
+          i = totmem = topmem = numbanks = 0;
+          while (bsp_sysinfo(BSP_INFO_MEMORY, i++, &mem) == 0)
+            {
+              if (mem.kind == BSP_MEM_RAM)
+                {
+                  numbanks++;
+                  totmem += mem.nbytes;
+                  u = (unsigned long)mem.virt_start + mem.nbytes;
+                  if (u > topmem)
+                    topmem = u;
+                }
+            }
+          *(unsigned long *)arg1 = totmem;
+          *(unsigned long *)arg2 = topmem;
+          *retval = numbanks;
+        }
+        return 1;
+        break;
+
+      default:
+       return 0;
+    }    
+
+    *retval = err;
+    return 1;
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/syscall.h b/packages/cygmon/v2_0/misc/bsp/common/syscall.h
new file mode 100644 (file)
index 0000000..00d555f
--- /dev/null
@@ -0,0 +1,50 @@
+/* General use syscall.h file.
+   The more ports that use this file, the simpler sim/common/nltvals.def
+   remains.  */
+
+#ifndef LIBGLOSS_SYSCALL_H
+#define LIBGLOSS_SYSCALL_H
+
+/* Note: This file may be included by assembler source.  */
+
+/* These should be as small as possible to allow a port to use a trap type
+   instruction, which the system call # as the trap (the d10v for instance
+   supports traps 0..31).  An alternative would be to define one trap for doing
+   system calls, and put the system call number in a register that is not used
+   for the normal calling sequence (so that you don't have to shift down the
+   arguments to add the system call number).  Obviously, if these system call
+   numbers are ever changed, all of the simulators and potentially user code
+   will need to be updated.  */
+
+/* There is no current need for the following: SYS_execv, SYS_creat, SYS_wait,
+   etc. etc.  Don't add them.  */
+
+/* These are required by the ANSI C part of newlib (excluding system() of
+   course).  */
+#define        SYS_exit        1
+#define        SYS_open        2
+#define        SYS_close       3
+#define        SYS_read        4
+#define        SYS_write       5
+#define        SYS_lseek       6
+#define        SYS_unlink      7
+#define        SYS_getpid      8
+#define        SYS_kill        9
+#define SYS_fstat       10
+/*#define SYS_sbrk     11 - not currently a system call, but reserved.  */
+
+/* ARGV support.  */
+#define SYS_argvlen    12
+#define SYS_argv       13
+
+/* These are extras added for one reason or another.  */
+#define SYS_chdir      14
+#define SYS_stat       15
+#define SYS_chmod      16
+#define SYS_utime      17
+#define SYS_time       18
+
+#define SYS_interrupt   1000
+
+#define SYS_meminfo     1001
+#endif
diff --git a/packages/cygmon/v2_0/misc/bsp/common/sysinfo.c b/packages/cygmon/v2_0/misc/bsp/common/sysinfo.c
new file mode 100644 (file)
index 0000000..cc15801
--- /dev/null
@@ -0,0 +1,170 @@
+//==========================================================================
+//
+//      sysinfo.c
+//
+//      Interface for getting system information.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Interface for getting system information.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <stdlib.h>
+#include <bsp/bsp.h>
+#include "bsp_if.h"
+
+
+/*
+ * In order to construct the _bsp_memory_list, some board specific code
+ * may have to size RAM regions. To do this easily and reliably, the code
+ * needs to run from ROM before .bss and .data sections are initialized.
+ * This leads to the problem of where to store the results of the memory
+ * sizing tests. In this case, the _bsp_init_stack routine which sizes
+ * memory and sets up the stack will place the board-specific information
+ * on the stack and return with the stack pointer pointing to a pointer to
+ * the information. That is, addr_of_info = *(void **)sp. The architecture
+ * specific code will then copy that pointer to the _bsp_ram_info_ptr variable
+ * after initializing the .data and .bss sections.
+ */
+void *_bsp_ram_info_ptr;
+
+/*
+ *  Name of CPU and board. Should be overridden by arch/board specific
+ *  code.
+ */
+struct bsp_platform_info _bsp_platform_info = {
+    "Unknown",  /* cpu name */
+    "Unknown",  /* board name */
+    ""          /* extra info */
+};
+
+
+/*
+ *  Information about possible data cache. Should be overridden by
+ *  by arch/board specific code.
+ */
+struct bsp_cachesize_info _bsp_dcache_info = {
+    0, 0, 0
+};
+
+
+/*
+ *  Information about possible instruction cache. Should be overridden by
+ *  by arch/board specific code.
+ */
+struct bsp_cachesize_info _bsp_icache_info = {
+    0, 0, 0
+};
+
+
+/*
+ *  Information about possible secondary cache. Should be overridden by
+ *  by arch/board specific code.
+ */
+struct bsp_cachesize_info _bsp_scache_info = {
+    0, 0, 0
+};
+
+
+
+int
+_bsp_sysinfo(enum bsp_info_id id, va_list ap)
+{
+    int  index, rval = 0;
+    void *p;
+
+    switch (id) {
+      case BSP_INFO_PLATFORM:
+       p = va_arg(ap, void *);
+       *(struct bsp_platform_info *)p = _bsp_platform_info;
+       break;
+
+      case BSP_INFO_DCACHE:
+       p = va_arg(ap, void *);
+       *(struct bsp_cachesize_info *)p = _bsp_dcache_info;
+       break;
+
+      case BSP_INFO_ICACHE:
+       p = va_arg(ap, void *);
+       *(struct bsp_cachesize_info *)p = _bsp_icache_info;
+       break;
+
+      case BSP_INFO_SCACHE:
+       p = va_arg(ap, void *);
+       *(struct bsp_cachesize_info *)p = _bsp_scache_info;
+       break;
+
+      case BSP_INFO_MEMORY:
+       index = va_arg(ap, int);
+       p = va_arg(ap, void *);
+
+       if (index >= 0 && index < _bsp_num_mem_regions)
+           *(struct bsp_mem_info *)p = _bsp_memory_list[index];
+       else
+           rval = -1;
+       break;
+
+      case BSP_INFO_COMM:
+       index = va_arg(ap, int);
+       p = va_arg(ap, void *);
+
+       if (index >= 0 && index < _bsp_num_comms)
+           *(struct bsp_comm_info *)p = _bsp_comm_list[index].info;
+       else if (index == _bsp_num_comms && _bsp_net_channel != NULL)
+           *(struct bsp_comm_info *)p = _bsp_net_channel->info;
+       else
+           rval = -1;
+       break;
+
+      default:
+       rval =  -1;
+    }
+
+    return rval;
+}
+
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/common/vprintf.c b/packages/cygmon/v2_0/misc/bsp/common/vprintf.c
new file mode 100644 (file)
index 0000000..5d1a7e7
--- /dev/null
@@ -0,0 +1,445 @@
+//==========================================================================
+//
+//      vprintf.c
+//
+//      Stripped down (no floating point) for debugging printf in ROMable BSP.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+/*
+ * Copyright (c) 1990, 1999 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Stripped down (no floating point) for debugging printf in ROMable BSP.
+ */
+#include <string.h>
+#include <stdarg.h>
+
+#define        BUF             40
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define        to_digit(c)     ((c) - '0')
+#define is_digit(c)    ((unsigned)to_digit(c) <= 9)
+#define        to_char(n)      ((n) + '0')
+
+/*
+ * Flags used during conversion.
+ */
+#define        ALT             0x001           /* alternate form */
+#define        HEXPREFIX       0x002           /* add 0x or 0X prefix */
+#define        LADJUST         0x004           /* left adjustment */
+#define        LONGDBL         0x008           /* long double; unimplemented */
+#define        LONGINT         0x010           /* long integer */
+#define        QUADINT         0x020           /* quad integer */
+#define        SHORTINT        0x040           /* short integer */
+#define        ZEROPAD         0x080           /* zero (as opposed to blank) pad */
+#define FPT            0x100           /* Floating point number */
+
+
+void
+__vprintf(void (*putc_func)(char c), const char *fmt0, va_list ap)
+{
+    char *fmt;         /* format string */
+    int ch;            /* character from fmt */
+    int n, m;          /* handy integers (short term usage) */
+    char *cp;          /* handy char pointer (short term usage) */
+    int flags;         /* flags as above */
+    int width;                 /* width from format (%8d), or 0 */
+    int prec;                  /* precision from format (%.3d), or -1 */
+    char sign;                 /* sign prefix (' ', '+', '-', or \0) */
+    unsigned long _uquad;
+    enum {OCT, DEC, HEX} base;  /* base for [diouxX] conversion */
+    int dprec;                 /* a copy of prec if [diouxX], 0 otherwise */
+    int realsz;                        /* field size expanded by dprec */
+    int size;                  /* size of converted field or string */
+    char *xdigs = NULL;                /* digits for [xX] conversion */
+    char buf[BUF];             /* space for %c, %[diouxX], %[eEfgG] */
+    char ox[2];                        /* space for 0x hex-prefix */
+
+#define        PRINT(ptr, len) {         \
+        for(n=0;n<(len);n++) {    \
+         if((ptr)[n] == '\n')    \
+            (*putc_func)('\r');   \
+         (*putc_func)((ptr)[n]); \
+       } \
+}
+
+#define        PAD(howmany, with) {        \
+       if ((n = (howmany)) > 0) {  \
+           while (n--)             \
+               (*putc_func)(with); \
+       } \
+}
+
+    /*
+     * To extend shorts properly, we need both signed and unsigned
+     * argument extraction methods.
+     */
+#define        SARG() \
+        (flags&LONGINT ? va_arg(ap, long) : \
+           flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
+           (long)va_arg(ap, int))
+
+#define        UARG() \
+       (flags&LONGINT ? va_arg(ap, unsigned long) : \
+           flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \
+           (unsigned long)va_arg(ap, unsigned int))
+
+    fmt = (char *)fmt0;
+
+    /*
+     * Scan the format for conversions (`%' character).
+     */
+    for (;;) {
+       cp = fmt;
+       while (*fmt && *fmt != '%')
+           fmt++;
+       if ((m = fmt - cp) != 0) {
+           PRINT(cp, m);
+       }
+
+       if (*fmt)
+           fmt++;              /* skip over '%' */
+       else
+           goto done;
+
+       flags = 0;
+       dprec = 0;
+       width = 0;
+       prec = -1;
+       sign = '\0';
+
+    rflag:
+       ch = *fmt++;
+    reswitch:
+       switch (ch) {
+         case ' ':
+           /*
+            * ``If the space and + flags both appear, the space
+            * flag will be ignored.''
+            *  -- ANSI X3J11
+            */
+           if (!sign)
+               sign = ' ';
+           goto rflag;
+         case '#':
+           flags |= ALT;
+           goto rflag;
+         case '*':
+           /*
+            * ``A negative field width argument is taken as a
+            * - flag followed by a positive field width.''
+            *  -- ANSI X3J11
+            * They don't exclude field widths read from args.
+            */
+           if ((width = va_arg(ap, int)) >= 0)
+               goto rflag;
+           width = -width;
+           /* FALLTHROUGH */
+         case '-':
+           flags |= LADJUST;
+           goto rflag;
+         case '+':
+           sign = '+';
+           goto rflag;
+         case '.':
+           if ((ch = *fmt++) == '*') {
+               n = va_arg(ap, int);
+               prec = n < 0 ? -1 : n;
+               goto rflag;
+           }
+           n = 0;
+           while (is_digit(ch)) {
+               n = 10 * n + to_digit(ch);
+               ch = *fmt++;
+           }
+           prec = n < 0 ? -1 : n;
+           goto reswitch;
+         case '0':
+           /*
+            * ``Note that 0 is taken as a flag, not as the
+            * beginning of a field width.''
+            *  -- ANSI X3J11
+            */
+           flags |= ZEROPAD;
+           goto rflag;
+         case '1': case '2': case '3': case '4':
+         case '5': case '6': case '7': case '8': case '9':
+           n = 0;
+           do {
+               n = 10 * n + to_digit(ch);
+               ch = *fmt++;
+           } while (is_digit(ch));
+           width = n;
+           goto reswitch;
+         case 'h':
+           flags |= SHORTINT;
+           goto rflag;
+         case 'l':
+           if (*fmt == 'l') {
+               fmt++;
+               flags |= QUADINT;
+           } else {
+               flags |= LONGINT;
+           }
+           goto rflag;
+         case 'c':
+           *(cp = buf) = va_arg(ap, int);
+           size = 1;
+           sign = '\0';
+           break;
+         case 'd':
+         case 'i':
+           _uquad = SARG();
+           if ((long) _uquad < 0)
+               {
+
+                   _uquad = -_uquad;
+                   sign = '-';
+               }
+           base = DEC;
+           goto number;
+         case 'o':
+           _uquad = UARG();
+           base = OCT;
+           goto nosign;
+         case 's':
+           if ((cp = va_arg(ap, char *)) == NULL)
+               cp = "(null)";
+           if (prec >= 0) {
+               /*
+                * can't use strlen; can only look for the
+                * NUL in the first `prec' characters, and
+                * strlen() will go further.
+                */
+               char *p = memchr(cp, 0, prec);
+
+               if (p != NULL) {
+                   size = p - cp;
+                   if (size > prec)
+                       size = prec;
+               } else
+                   size = prec;
+           } else
+               size = strlen(cp);
+           sign = '\0';
+           break;
+         case 'u':
+           _uquad = UARG();
+           base = DEC;
+           goto nosign;
+         case 'X':
+           xdigs = "0123456789ABCDEF";
+           goto hex;
+         case 'x':
+           xdigs = "0123456789abcdef";
+       hex:                    _uquad = UARG();
+           base = HEX;
+           /* leading 0x/X only if non-zero */
+           if (flags & ALT && _uquad != 0)
+               flags |= HEXPREFIX;
+
+           /* unsigned conversions */
+       nosign:                 sign = '\0';
+           /*
+            * ``... diouXx conversions ... if a precision is
+            * specified, the 0 flag will be ignored.''
+            *  -- ANSI X3J11
+            */
+       number:                 if ((dprec = prec) >= 0)
+           flags &= ~ZEROPAD;
+
+           /*
+            * ``The result of converting a zero value with an
+            * explicit precision of zero is no characters.''
+            *  -- ANSI X3J11
+            */
+           cp = buf + BUF;
+           if (_uquad != 0 || prec != 0) {
+               /*
+                * Unsigned mod is hard, and unsigned mod
+                * by a constant is easier than that by
+                * a variable; hence this switch.
+                 */
+               switch (base) {
+                 case OCT:
+                   do {
+                       *--cp = to_char(_uquad & 7);
+                       _uquad >>= 3;
+                   } while (_uquad);
+                   /* handle octal leading 0 */
+                   if (flags & ALT && *cp != '0')
+                       *--cp = '0';
+                   break;
+
+                 case DEC:
+                   /* many numbers are 1 digit */
+                   while (_uquad >= 10) {
+                       *--cp = to_char(_uquad % 10);
+                       _uquad /= 10;
+                   }
+                   *--cp = to_char(_uquad);
+                   break;
+
+                 case HEX:
+                   do {
+                       *--cp = xdigs[_uquad & 15];
+                       _uquad >>= 4;
+                   } while (_uquad);
+                   break;
+
+                 default:
+                   cp = "bug in vfprintf: bad base";
+                   size = strlen(cp);
+                   goto skipsize;
+               }
+           }
+           size = buf + BUF - cp;
+       skipsize:
+           break;
+         default:      /* "%?" prints ?, unless ? is NUL */
+           if (ch == '\0')
+               goto done;
+           /* pretend it was %c with argument ch */
+           cp = buf;
+           *cp = ch;
+           size = 1;
+           sign = '\0';
+           break;
+       }
+
+       /*
+        * All reasonable formats wind up here.  At this point, `cp'
+        * points to a string which (if not flags&LADJUST) should be
+        * padded out to `width' places.  If flags&ZEROPAD, it should
+        * first be prefixed by any sign or other prefix; otherwise,
+        * it should be blank padded before the prefix is emitted.
+        * After any left-hand padding and prefixing, emit zeroes
+        * required by a decimal [diouxX] precision, then print the
+        * string proper, then emit zeroes required by any leftover
+        * floating precision; finally, if LADJUST, pad with blanks.
+        *
+        * Compute actual size, so we know how much to pad.
+        * size excludes decimal prec; realsz includes it.
+        */
+       realsz = dprec > size ? dprec : size;
+       if (sign)
+           realsz++;
+       else if (flags & HEXPREFIX)
+           realsz+= 2;
+
+       /* right-adjusting blank padding */
+       if ((flags & (LADJUST|ZEROPAD)) == 0)
+           PAD(width - realsz, ' ');
+
+       /* prefix */
+       if (sign) {
+           PRINT(&sign, 1);
+       } else if (flags & HEXPREFIX) {
+           ox[0] = '0';
+           ox[1] = ch;
+           PRINT(ox, 2);
+       }
+
+       /* right-adjusting zero padding */
+       if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
+           PAD(width - realsz, '0');
+
+       /* leading zeroes from decimal precision */
+       PAD(dprec - size, '0');
+
+       /* the string or number proper */
+       PRINT(cp, size);
+
+       /* left-adjusting padding (always blank) */
+       if (flags & LADJUST)
+           PAD(width - realsz, ' ');
+    }
+ done:
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/bsp/cpu.h b/packages/cygmon/v2_0/misc/bsp/cpu.h
new file mode 100644 (file)
index 0000000..66ea53a
--- /dev/null
@@ -0,0 +1,71 @@
+#ifndef __BSP_CPU_H__
+#define __BSP_CPU_H__
+//==========================================================================
+//
+//      cpu.h
+//
+//      Architecture/processor specifics
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+// Pick up architecture info
+
+#include <pkgconf/system.h>
+
+#ifdef CYGPKG_HAL_ARM
+#include "arm/cpu.h"
+#endif
+
+#ifdef CYGPKG_HAL_MIPS
+#include "mips/cpu.h"
+#endif
+
+#ifdef CYGPKG_HAL_MN10300
+#include "mn10300/cpu.h"
+#endif
+
+#endif // __BSP_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/dbg-threads-api.h b/packages/cygmon/v2_0/misc/bsp/dbg-threads-api.h
new file mode 100644 (file)
index 0000000..8eb1bd7
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef __BSP_DBG_THREADS_API_H__
+#define __BSP_DBG_THREADS_API_H__
+//==========================================================================
+//
+//      dbg-threads-api.h
+//
+//      <DESCRIPTION>
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  These are the calls used to extract operating system
+//               specific information used in supporting thread aware
+//               debugging.
+//               The Operating Environment being debugged needs to supply
+//               these functions.
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#define has_thread_void       0 
+#define has_thread_current    1
+#define has_thread_registers  2
+#define has_thread_reg_change 4
+#define has_thread_list       8
+#define has_thread_info       16
+
+typedef unsigned char threadref[8] ;
+
+struct dbg_capabilities
+{
+    unsigned long mask1;
+};
+
+/* fill in the list of thread aware capabilities */
+extern int dbg_thread_capabilities(struct dbg_capabilities *cbp);
+
+
+/* Fill in the identifier of the current thread */
+/* return 1 if defined, 0 if not defined */
+extern int dbg_currthread(threadref *varparm);
+
+/* get the first or next member of the list of known threads */
+extern int dbg_threadlist(int startflag,
+                         threadref *lastthreadid,
+                         threadref *next_thread);
+
+/* return 1 if next_threadid has been filled in with a value */
+/* return 0 if there are none or no more */
+
+/* The O.S can fill in the following information about a thread when queried.
+   The structure of thise strings is determined by the O.S.
+   It is display oriented, so figure out what the users need to see.
+   Nulls are OK but GDB will fill some not so meaningful data.
+   These pointers may be in the calles private structures, the info will
+   get copied immediatly after the call to retreive it.
+   */
+struct cygmon_thread_debug_info
+{
+  threadref thread_id ;
+  int context_exists ; /* To the point where examining its state,
+                        registers and stack makes sense to GDB */
+  char * thread_display ; /* As shown in thread status window, name, state */
+  char * unique_thread_name ; /* human readable identifier, window label */
+  char * more_display ;   /* more detailed info about thread.
+                         priority, queuedepth, state, stack usage, statistics */
+} ;
+
+
+
+
+extern int dbg_threadinfo(threadref *threadid,
+                         struct cygmon_thread_debug_info *info);
+
+/* Return 1 if threadid is defined and info copied, 0 otherwise */
+
+/* The O.S should fillin the array of registers using values from the
+saves context. The array MUST be in GDB register save order even if
+the saved context is different or smaller. Do not alter the values of
+registers which are NOT in the O.S. thread context. Their default values
+have already been assigned.
+*/
+
+extern int dbg_getthreadreg(threadref *osthreadid, 
+                           int regcount, /* count of registers in the array */
+                           void * regval); /* fillin this array */
+
+
+/* The O.S. should scan through this list of registers which are in
+GDB order and the O.S. should replace the values of all registers
+which are defined in the saved context of thread or process identified
+by osthreadid. Return 0 if the threadis does not map to a known
+process or other error. Return 1 if the setting is successful.  */
+
+extern int dbg_setthreadreg(threadref *osthreadid, 
+                           int regcount, /* number of registers */
+                           void *regval) ;
+
+
+extern int dbg_scheduler(threadref *thread_id, int lock, int mode);
+
+/* --- EXCEPTION -
+   The O.S. does not provide this function , it calls this to specify the
+   location of the dbg_syscall vector
+   */
+extern void patch_dbg_syscalls(void * vector);
+
+#endif /* DBG_THREADS_API_INCLUDED */
+#endif // __BSP_DBG_THREADS_API_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/defs.h b/packages/cygmon/v2_0/misc/bsp/defs.h
new file mode 100644 (file)
index 0000000..cd39ac2
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef __BSP_DEFS_H__
+#define __BSP_DEFS_H__
+//==========================================================================
+//
+//      defs.h
+//
+//      Definitions of interest to Red Hat BSP.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Definitions of interest to Red Hat BSP.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#define BIT0            0x00000001
+#define BIT1            0x00000002
+#define BIT2            0x00000004
+#define BIT3            0x00000008
+#define BIT4            0x00000010
+#define BIT5            0x00000020
+#define BIT6            0x00000040
+#define BIT7            0x00000080
+#define BIT8            0x00000100
+#define BIT9            0x00000200
+#define BIT10           0x00000400
+#define BIT11           0x00000800
+#define BIT12           0x00001000
+#define BIT13           0x00002000
+#define BIT14           0x00004000
+#define BIT15           0x00008000
+#define BIT16           0x00010000
+#define BIT17           0x00020000
+#define BIT18           0x00040000
+#define BIT19           0x00080000
+#define BIT20           0x00100000
+#define BIT21           0x00200000
+#define BIT22           0x00400000
+#define BIT23           0x00800000
+#define BIT24           0x01000000
+#define BIT25           0x02000000
+#define BIT26           0x04000000
+#define BIT27           0x08000000
+#define BIT28           0x10000000
+#define BIT29           0x20000000
+#define BIT30           0x40000000
+#define BIT31           0x80000000
+
+#define SZ_1K           0x00000400
+#define SZ_2K           0x00000800
+#define SZ_4K           0x00001000
+#define SZ_8K           0x00002000
+#define SZ_16K          0x00004000
+#define SZ_32K          0x00008000
+#define SZ_64K          0x00010000
+#define SZ_128K         0x00020000
+#define SZ_256K         0x00040000
+#define SZ_512K         0x00080000
+#define SZ_1M           0x00100000
+#define SZ_2M           0x00200000
+#define SZ_4M           0x00400000
+#define SZ_8M           0x00800000
+#define SZ_16M          0x01000000
+#define SZ_32M          0x02000000
+#define SZ_64M          0x04000000
+#define SZ_128M         0x08000000
+#define SZ_256M         0x10000000
+#define SZ_512M         0x20000000
+#define SZ_1G           0x40000000
+
+#endif // __BSP_DEFS_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/gdb-data.h b/packages/cygmon/v2_0/misc/bsp/gdb-data.h
new file mode 100644 (file)
index 0000000..b4dce69
--- /dev/null
@@ -0,0 +1,126 @@
+#ifndef __BSP_GDB_DATA_H__
+#define __BSP_GDB_DATA_H__
+//==========================================================================
+//
+//      gdb-data.h
+//
+//      Shared data specific to gdb stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Shared data specific to gdb stub.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#ifndef __ASSEMBLER__
+typedef int (*gdb_memproc_t)(void *__addr,    /* start addr of memory to read/write */
+                            int  __asid,     /* address space id */
+                            int  __size,     /* size of individual read/write ops */
+                            int  __n,        /* number of read/write operations */
+                            void *__buf);    /* result(read)/src(write) buffer */
+
+
+typedef void (*gdb_regproc_t)(int  __regno,   /* Register number */
+                             void *__regs,   /* pointer to saved regs */
+                             void *__val);   /* pointer to register value */
+
+
+typedef struct {
+    /*
+     * An application may override the standard BSP memory
+     * read and/or write routines with these hooks.
+     */
+    gdb_memproc_t      __mem_read_hook;
+    gdb_memproc_t      __mem_write_hook;
+
+    /*
+     * An application may override the standard BSP register
+     * access routines with these hooks.
+     */
+    gdb_regproc_t      __reg_get_hook;
+    gdb_regproc_t      __reg_set_hook;
+
+    /*
+     * An application may extend the gdb remote protocol by
+     * installing hooks to handle unknown general query and
+     * set packets ("q" pkts and 'Q' pkts) with these two hooks.
+     */
+    void                (*__pkt_query_hook)(unsigned char *__pkt);
+    void                (*__pkt_set_hook)(unsigned char *__pkt);
+
+    /*
+     * An application may also extend the gdb remote protocol
+     * by installing a hook to handle all unknown packets.
+     */
+    void                (*__pkt_hook)(unsigned char *__pkt);
+
+    /*
+     * The above hooks for receiving packets will probably need
+     * a mechanism to respond. This vector is provided to allow
+     * an application to append data to the outgoing packet which
+     * will be sent after the above hooks are called.
+     *
+     * This vector uses a printf-like format string followed by
+     * some number of arguments.
+     */
+    void                (*__pkt_append)(char *fmt, ...);
+
+    /*
+     * An application can read/write from/to gdb console
+     * through these vectors.
+     *
+     * NB: console read is not supported and will block forever.
+     */
+    int                 (*__console_read)(char *__buf, int len);
+    int                 (*__console_write)(char *__buf, int len);
+
+} gdb_data_t;
+
+
+extern gdb_data_t *__get_gdb_data(void);
+
+#endif /* __ASSEMBLER__ */
+
+#endif // __BSP_GDB_DATA_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/hex-utils.h b/packages/cygmon/v2_0/misc/bsp/hex-utils.h
new file mode 100644 (file)
index 0000000..12bf43a
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef __BSP_HEX_UTILS_H__
+#define __BSP_HEX_UTILS_H__
+//==========================================================================
+//
+//      hex-utils.h
+//
+//      Utilities for decoding hexadecimal encoded integers.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Utilities for decoding hexadecimal encoded integers.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#ifndef __ASSEMBLER__
+
+/*
+ * Convert a single hex character to its binary value.
+ * Returns -1 if given character is not a value hex character.
+ */
+extern int __hex(char ch);
+
+/*
+ * Convert the hex data in 'buf' into 'count' bytes to be placed in 'mem'.
+ * Returns a pointer to the character in mem AFTER the last byte written.
+ */
+extern char *__unpack_bytes_to_mem(char *buf, char *mem, int count);
+
+/*
+ * While finding valid hex chars, build an unsigned long int.
+ * Return number of hex chars processed.
+ */
+extern int __unpack_ulong(char **ptr, unsigned long *val);
+
+/*
+ * Unpack 'count' hex characters, forming them into a binary value.
+ * Return that value as an int. Adjust the source pointer accordingly.
+ */
+extern int __unpack_nibbles(char **ptr, int count);
+
+#endif
+
+#endif // __BSP_HEX_UTILS_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/mips/gdb-cpu.c b/packages/cygmon/v2_0/misc/bsp/mips/gdb-cpu.c
new file mode 100644 (file)
index 0000000..b539c7e
--- /dev/null
@@ -0,0 +1,53 @@
+//==========================================================================
+//
+//      gdb-cpu.c
+//
+//      CPU specific support for GDB stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-06-07
+// Purpose:      CPU specific support for GDB stub.
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
diff --git a/packages/cygmon/v2_0/misc/bsp/mips/gdb-cpu.h b/packages/cygmon/v2_0/misc/bsp/mips/gdb-cpu.h
new file mode 100644 (file)
index 0000000..fc68a42
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __BSP_MIPS_GDB_CPU_H__
+#define __BSP_MIPS_GDB_CPU_H__
+//==========================================================================
+//
+//      gdb-cpu.h
+//
+//      CPU specific definitions for GDB stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: dmoseley
+// Date:         2000-07-10
+// Purpose:      CPU specific definitions for GDB stub.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+
+#endif // __BSP_MIPS_GDB_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/mips/gdb.h b/packages/cygmon/v2_0/misc/bsp/mips/gdb.h
new file mode 100644 (file)
index 0000000..1218012
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __BSP_MIPS_GDB_H__
+#define __BSP_MIPS_GDB_H__
+//==========================================================================
+//
+//      gdb.h
+//
+//      
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+
+#endif // __BSP_ARM_GDB_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/mips/insn.h b/packages/cygmon/v2_0/misc/bsp/mips/insn.h
new file mode 100644 (file)
index 0000000..e6cedea
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __BSP_MIPS_INSN_H__
+#define __BSP_MIPS_INSN_H__
+//==========================================================================
+//
+//      insn.h
+//
+//      MIPS instruction descriptions.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-07-10
+// Purpose:      MIPS instruction descriptions.
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+// We are using the eCos hal for single-stepping.
+// FIXME: this file can be removed
+
+#endif // __BSP_ARM_INSN_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/mips/singlestep.c b/packages/cygmon/v2_0/misc/bsp/mips/singlestep.c
new file mode 100644 (file)
index 0000000..b57e73c
--- /dev/null
@@ -0,0 +1,55 @@
+//==========================================================================
+//
+//      singlestep.c
+//
+//      MIPS specific single-step support.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-07-10
+// Purpose:      MIPS specific single-step support. 
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+// We are using the eCos hal for single-stepping.
+// FIXME: this file can be removed
diff --git a/packages/cygmon/v2_0/misc/bsp/mn10300/gdb-cpu.c b/packages/cygmon/v2_0/misc/bsp/mn10300/gdb-cpu.c
new file mode 100644 (file)
index 0000000..ce92d11
--- /dev/null
@@ -0,0 +1,53 @@
+//==========================================================================
+//
+//      gdb-cpu.c
+//
+//      CPU specific support for GDB stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      CPU specific support for GDB stub.
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
diff --git a/packages/cygmon/v2_0/misc/bsp/mn10300/gdb-cpu.h b/packages/cygmon/v2_0/misc/bsp/mn10300/gdb-cpu.h
new file mode 100644 (file)
index 0000000..87d6179
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __BSP_MN10300_GDB_CPU_H__
+#define __BSP_MN10300_GDB_CPU_H__
+//==========================================================================
+//
+//      gdb-cpu.h
+//
+//      CPU specific definitions for GDB stub.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      CPU specific definitions for GDB stub.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+
+#endif // __BSP_MN10300_GDB_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/mn10300/gdb.h b/packages/cygmon/v2_0/misc/bsp/mn10300/gdb.h
new file mode 100644 (file)
index 0000000..6b580e9
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __BSP_MN10300_GDB_H__
+#define __BSP_MN10300_GDB_H__
+//==========================================================================
+//
+//      gdb.h
+//
+//      
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+
+#endif // __BSP_ARM_GDB_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/mn10300/insn.h b/packages/cygmon/v2_0/misc/bsp/mn10300/insn.h
new file mode 100644 (file)
index 0000000..3a29fc7
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __BSP_MN10300_INSN_H__
+#define __BSP_MN10300_INSN_H__
+//==========================================================================
+//
+//      insn.h
+//
+//      MN10300 instruction descriptions.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      MN10300 instruction descriptions.
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+// We are using the eCos hal for single-stepping.
+// FIXME: this file can be removed
+
+#endif // __BSP_ARM_INSN_H__
diff --git a/packages/cygmon/v2_0/misc/bsp/mn10300/singlestep.c b/packages/cygmon/v2_0/misc/bsp/mn10300/singlestep.c
new file mode 100644 (file)
index 0000000..1273f5a
--- /dev/null
@@ -0,0 +1,55 @@
+//==========================================================================
+//
+//      singlestep.c
+//
+//      MN10300 specific single-step support.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      MN10300 specific single-step support. 
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Nothing now.
+// We are using the eCos hal for single-stepping.
+// FIXME: this file can be removed
diff --git a/packages/cygmon/v2_0/misc/cpu-mon.c b/packages/cygmon/v2_0/misc/cpu-mon.c
new file mode 100644 (file)
index 0000000..43cbb4f
--- /dev/null
@@ -0,0 +1,61 @@
+//==========================================================================
+//
+//        cpu-mon.c
+//
+//        eCos BSP (for building Cygmon)
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     gthomas
+// Contributors:  gthomas, dmoseley
+// Date:          1999-10-11
+// Description:   Architecture support for Cygmon
+//####DESCRIPTIONEND####
+
+#include <pkgconf/system.h>   // Configuration header
+
+#ifdef CYGPKG_HAL_ARM
+#include "arm/arm-mon.c"
+#endif
+
+#ifdef CYGPKG_HAL_MIPS
+#include "mips/mips-mon.c"
+#endif
+
+#ifdef CYGPKG_HAL_MN10300
+#include "mn10300/mn10300-mon.c"
+#endif
diff --git a/packages/cygmon/v2_0/misc/cpu_info.h b/packages/cygmon/v2_0/misc/cpu_info.h
new file mode 100644 (file)
index 0000000..1a1700a
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef __CYGMON_CPU_INFO_H__
+#define __CYGMON_CPU_INFO_H__
+//==========================================================================
+//
+//      cpu_info.h
+//
+//      Architecture specific information
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+#include <pkgconf/system.h>
+#include <pkgconf/hal.h>
+
+#ifdef CYGPKG_HAL_ARM
+#include "arm/cpu_info.h"
+#endif
+
+#ifdef CYGPKG_HAL_MIPS
+#include "mips/cpu_info.h"
+#endif
+
+#ifdef CYGPKG_HAL_MN10300
+#include "mn10300/cpu_info.h"
+#endif
+#endif // __CYGMON_CPU_INFO_H__
diff --git a/packages/cygmon/v2_0/misc/ecos_bsp.c b/packages/cygmon/v2_0/misc/ecos_bsp.c
new file mode 100644 (file)
index 0000000..f6ee0fc
--- /dev/null
@@ -0,0 +1,470 @@
+//==========================================================================
+//
+//        ecos_bsp.c
+//
+//        eCos BSP (for building Cygmon)
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     gthomas
+// Contributors:  gthomas, dmoseley
+// Date:          1999-10-11
+// Description:   Wrapper functions which provide BSP environment for Cygmon
+//####DESCRIPTIONEND####
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>   // Configuration headers
+#endif
+#include <pkgconf/hal.h>
+#include <pkgconf/cygmon.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_cache.h>
+#ifdef CYGPKG_KERNEL
+#include <cyg/kernel/kapi.h>
+#else
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_intr.h>
+#endif
+#include <cyg/infra/diag.h>
+#include "bsp/common/bsp_if.h"
+#include <cyg/hal/hal_if.h>
+#include <signal.h>
+#include CYGHWR_MEMORY_LAYOUT_H
+#include <pkgconf/system.h>
+#ifdef CYGPKG_IO
+#include <cyg/io/io.h>
+#include <cyg/io/serialio.h>
+#endif
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
+static char stack[STACK_SIZE];
+#ifdef CYGPKG_KERNEL
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+#endif
+
+char *build_date = __DATE__;
+
+extern void monitor_main(int, char *);
+extern int  stub_is_active;
+
+void ecos_bsp_set_memsize(unsigned long size);
+
+void
+cygmon_main(void)
+{
+    _bsp_init();
+    monitor_main(0, 0);  // Null argument list
+}
+
+extern unsigned long cygmon_memsize;
+
+externC void
+cyg_start( void )
+{
+    // Fill in the BSP memory info
+    if (cygmon_memsize != 0)
+        ecos_bsp_set_memsize(cygmon_memsize);
+
+#ifdef CYGPKG_KERNEL
+    // Create a main thread, so we can run the scheduler and have time 'pass'
+    cyg_thread_create(10,                // Priority - just a number
+                      (cyg_thread_entry_t*)cygmon_main,       // entry
+                      0,                 // entry parameter
+                      "Cygmon",          // Name
+                      &stack[0],         // Stack
+                      STACK_SIZE,        // Size
+                      &thread_handle,    // Handle
+                      &thread_data       // Thread data structure
+            );
+    cyg_thread_resume(thread_handle);  // Start it
+    cyg_scheduler_start();
+#else
+#ifdef HAL_ARCH_FUNCALL_NEW_STACK
+    HAL_ARCH_FUNCALL_NEW_STACK(cygmon_main, &stack[0], STACK_SIZE);
+#else
+    #error Need to define HAL_ARCH_FUNCALL_NEW_STACK
+#endif
+#endif
+} // cyg_package_start()
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+extern void *_hal_registers;  // Used by eCos GDB stubs
+extern void (*__init_vec)(void);
+extern void (*__cleanup_vec)(void);
+extern void __install_traps(void);
+#endif
+
+extern int machine_syscall(HAL_SavedRegisters *regs);
+void
+_bsp_handle_exception(cyg_addrword_t data, cyg_code_t num, cyg_addrword_t info)
+{
+    if (num == CYGNUM_HAL_EXCEPTION_INTERRUPT) {
+        if (machine_syscall((HAL_SavedRegisters*)info)) {
+            return;
+        }
+        // Fall through to "normal" exception handling if system call failed
+    }
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+    _hal_registers = (void *)info;  // Used by eCos GDB stubs
+    __cleanup_vec();
+#endif
+    bsp_invoke_dbg_handler(num, (void *)info);
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+    __init_vec();
+#endif
+}
+
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+extern void __handle_exception(void);
+#else
+
+int
+unhandled_exception(int num, void *args)
+{
+    diag_printf("Unhandled exception: %d/%x\n", num, args);
+    while (1) ;
+}
+#endif
+
+void
+_bsp_cpu_init(void)
+{
+#ifdef CYGPKG_KERNEL
+    int d0;
+    cyg_exception_set_handler(CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION,
+                              _bsp_handle_exception,
+                              (cyg_addrword_t)&d0,
+                              0,
+                              0);
+#endif
+#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
+    bsp_install_dbg_handler((bsp_handler_t)__handle_exception);
+    __install_traps();
+#else
+    bsp_install_dbg_handler(unhandled_exception);
+#endif
+}
+
+#define FAIL() diag_printf("fail: %s\n", __FUNCTION__);  while (1) ;
+
+#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+struct BSP_IO {
+    char            *name;
+    cyg_io_handle_t  chan;
+};
+
+static void 
+uart_putchar(void *base, char c)
+{
+    char buf;
+    int len;
+    struct BSP_IO *io = (struct BSP_IO *)base;
+    if (io->chan) {
+        len = 1;
+        buf = c;
+        cyg_io_write(io->chan, &buf, &len);
+    }
+}
+
+extern int __output_gdb_string (const char *str, int string_len);
+
+// This function is mostly used by the 'write()' system call
+static void
+uart_write(void *base, const char *buf, int len)
+{
+    struct BSP_IO *io = (struct BSP_IO *)base;
+    if (io->chan) {
+        if (stub_is_active) {
+            // We are running in 'GDB' mode
+            __output_gdb_string(buf, len);
+        } else {
+            cyg_io_write(io->chan, buf, &len);
+        }
+    }
+}
+
+static int
+uart_read(void *base, char *buf, int len)
+{
+    struct BSP_IO *io = (struct BSP_IO *)base;
+    if (io->chan) {
+        cyg_io_read(io->chan, buf, &len);
+        return len;
+    }
+    return 0;
+}
+
+static int
+uart_getchar(void *base)
+{
+    char buf = '\0';
+    int len;
+    struct BSP_IO *io = (struct BSP_IO *)base;
+    if (io->chan) {
+        len = 1;
+        cyg_io_read(io->chan, &buf, &len);
+    }
+    return buf;
+}
+
+static int
+uart_control(void *base, int func, ...)
+{
+    int rc = 0;
+    va_list ap;
+    int arg;
+    struct BSP_IO *io = (struct BSP_IO *)base;
+
+    va_start(ap, func);
+
+    if (func == COMMCTL_SETBAUD)
+    {
+        cyg_serial_info_t buffer = {
+            CYG_SERIAL_BAUD_DEFAULT, 
+            CYG_SERIAL_STOP_DEFAULT, 
+            CYG_SERIAL_PARITY_DEFAULT,
+            CYG_SERIAL_WORD_LENGTH_DEFAULT,
+            CYG_SERIAL_FLAGS_DEFAULT
+        };
+        int len = sizeof(buffer);
+        arg = va_arg(ap, int);
+
+        switch (arg)
+        {
+        case 50:         buffer.baud = CYG_SERIAL_BAUD_RATE(50);       break;
+        case 75:         buffer.baud = CYG_SERIAL_BAUD_RATE(75);       break;
+        case 110:        buffer.baud = CYG_SERIAL_BAUD_RATE(110);      break;
+        case 134:        buffer.baud = CYG_SERIAL_BAUD_RATE(134_5);    break;
+        case 135:        buffer.baud = CYG_SERIAL_BAUD_RATE(134_5);    break;
+        case 150:        buffer.baud = CYG_SERIAL_BAUD_RATE(150);      break;
+        case 200:        buffer.baud = CYG_SERIAL_BAUD_RATE(200);      break;
+        case 300:        buffer.baud = CYG_SERIAL_BAUD_RATE(300);      break;
+        case 600:        buffer.baud = CYG_SERIAL_BAUD_RATE(600);      break;
+        case 1200:       buffer.baud = CYG_SERIAL_BAUD_RATE(1200);     break;
+        case 1800:       buffer.baud = CYG_SERIAL_BAUD_RATE(1800);     break;
+        case 2400:       buffer.baud = CYG_SERIAL_BAUD_RATE(2400);     break;
+        case 3600:       buffer.baud = CYG_SERIAL_BAUD_RATE(3600);     break;
+        case 4800:       buffer.baud = CYG_SERIAL_BAUD_RATE(4800);     break;
+        case 7200:       buffer.baud = CYG_SERIAL_BAUD_RATE(7200);     break;
+        case 9600:       buffer.baud = CYG_SERIAL_BAUD_RATE(9600);     break;
+        case 14400:      buffer.baud = CYG_SERIAL_BAUD_RATE(14400);    break;
+        case 19200:      buffer.baud = CYG_SERIAL_BAUD_RATE(19200);    break;
+        case 38400:      buffer.baud = CYG_SERIAL_BAUD_RATE(38400);    break;
+        case 57600:      buffer.baud = CYG_SERIAL_BAUD_RATE(57600);    break;
+        case 115200:     buffer.baud = CYG_SERIAL_BAUD_RATE(115200);   break;
+        case 230400:     buffer.baud = CYG_SERIAL_BAUD_RATE(230400);   break;
+        default:         buffer.baud = -1; rc = -1;                    break;
+        }
+
+        if ((io->chan) && (buffer.baud != -1)) {
+            rc = cyg_io_set_config(io->chan, CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer, &len);
+        }
+    }
+
+    va_end(ap);
+    return rc;
+}
+
+/*
+ * Setup the bsp_comm_channel data structure
+ */
+struct BSP_IO bsp_comm_io[] = { 
+    {CYGDAT_CYGMON_CONSOLE_DEV, 0},  // Console device
+};
+
+struct bsp_comm_channel _bsp_comm_list[] = 
+{
+    {
+       { "UART 0", 
+          BSP_COMM_SERIAL, 
+          BSP_PROTO_NONE },
+       { (void*)&bsp_comm_io[0], 
+          uart_write, 
+          uart_read,
+         uart_putchar, 
+          uart_getchar, 
+          uart_control }
+    },
+};
+int _bsp_num_comms = sizeof(_bsp_comm_list)/sizeof(_bsp_comm_list[0]);
+
+void
+_bsp_init_board_comm(void)
+{
+    int i;
+    for (i = 0;  i < _bsp_num_comms;  i++) {
+        Cyg_ErrNo err;
+        struct BSP_IO *io;
+        io = (struct BSP_IO *)_bsp_comm_list[i].procs.ch_data;
+        if ((err = cyg_io_lookup(io->name, &io->chan)) != ENOERR) {
+            diag_printf("Can't open '%s'\n", io->name);
+        }
+    }
+}
+
+#else // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+struct bsp_comm_channel _bsp_comm_list[1];
+int _bsp_num_comms = 1;
+
+// Yuck! Two things need doing:
+
+// FIXME: Make bsp code use pointers in the bsp_comm_channel instead
+//        of sub-structures.
+
+// FIXME: Make HAL provide the bsp_comm_info structure - I missed that
+//        initially because it cannot be accessed via the virtual table API.
+void
+_bsp_init_board_comm(void)
+{
+    struct bsp_comm_channel* channel;
+    hal_virtual_comm_table_t* comm;
+
+    channel = &_bsp_comm_list[0];
+    channel->info.name = "fixme";
+    channel->info.kind = BSP_COMM_SERIAL;
+    channel->info.protocol = BSP_PROTO_NONE;
+
+    comm = CYGACC_CALL_IF_DEBUG_PROCS();
+    channel->procs = *(struct bsp_comm_procs*)comm;
+}
+#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+
+/*
+ * Array of memory region descriptors. We just list RAM.
+ */
+#ifdef CYGMEM_REGION_ram
+#define RAM_VIRTUAL_BASE CYGMEM_REGION_ram
+#define RAM_TOTAL_SIZE   CYGMEM_REGION_ram_SIZE
+#else
+#define RAM_VIRTUAL_BASE 0x00008000
+#define RAM_TOTAL_SIZE   0x00FF8000
+#endif
+
+struct bsp_mem_info _bsp_memory_list[] = 
+{
+    { (void *)RAM_VIRTUAL_BASE,   
+      (void *)RAM_VIRTUAL_BASE,   
+      0, 
+      RAM_TOTAL_SIZE,   
+      BSP_MEM_RAM 
+    },
+};
+
+/*
+ * Number of memory region descriptors.
+ */
+int _bsp_num_mem_regions = sizeof(_bsp_memory_list)/sizeof(_bsp_memory_list[0]);
+
+void
+_bsp_install_cpu_irq_controllers(void)
+{
+}
+
+void
+_bsp_install_board_irq_controllers(void)
+{
+}
+
+void
+__init_irq_controllers(void)
+{
+}
+
+void
+_bsp_board_init(void)
+{
+    /*
+     * Define platform info.
+     */
+#ifdef HAL_PLATFORM_CPU
+    _bsp_platform_info.cpu = HAL_PLATFORM_CPU;
+#else
+    _bsp_platform_info.cpu = "Unknown CPU";
+#endif
+#ifdef HAL_PLATFORM_BOARD
+    _bsp_platform_info.board = HAL_PLATFORM_BOARD;
+#else
+    _bsp_platform_info.board = "Unknown board";
+#endif
+#ifdef HAL_PLATFORM_EXTRA
+    _bsp_platform_info.extra = HAL_PLATFORM_EXTRA;
+#else
+    _bsp_platform_info.extra = "";
+#endif
+}
+
+extern char *strchr(char *, char);
+char *
+index(char *string, char key)
+{
+    return strchr(string, key);
+}
+
+void
+flush_i_cache(void)
+{
+    HAL_ICACHE_SYNC();
+}
+
+void
+ecos_bsp_console_putc(char c)
+{
+    if (bsp_shared_data) {
+        bsp_console_putc(c);
+    }
+}
+
+char
+ecos_bsp_console_getc(void)
+{
+    if (bsp_shared_data) {
+        return bsp_console_getc();
+    } else {
+        return '?';
+    }
+}
+
+void
+ecos_bsp_set_memsize(unsigned long size)
+{
+    _bsp_memory_list[0].nbytes = size;
+}
diff --git a/packages/cygmon/v2_0/misc/ecos_dummy.c b/packages/cygmon/v2_0/misc/ecos_dummy.c
new file mode 100644 (file)
index 0000000..876d527
--- /dev/null
@@ -0,0 +1,70 @@
+//==========================================================================
+//
+//        ecos_dummy.c
+//
+//        eCos BSP (for building Cygmon)
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):     gthomas
+// Contributors:  gthomas, dmoseley
+// Date:          1999-10-11
+// Description:   Wrapper functions which provide BSP environment for Cygmon
+//####DESCRIPTIONEND####
+
+#ifdef CYGPKG_KERNEL
+#include <pkgconf/kernel.h>   // Configuration header
+#include <cyg/kernel/kapi.h>
+#endif
+#include <cyg/infra/diag.h>
+#include <cyg/hal/plf_stub.h>
+
+// TEMP
+
+#define FAIL(n)                                 \
+void n(void)                                    \
+{                                               \
+    diag_printf("Fail: %s\n", #n);              \
+    while (1) ;                                 \
+}
+
+#ifndef CYGHWR_HAL_RESET_DEFINED
+    FAIL(bsp_reset)
+#endif
+
+    FAIL(_bsp_gdb_handler)
+    FAIL(_bsp_gdb_data)
diff --git a/packages/cygmon/v2_0/misc/fmt_util.h b/packages/cygmon/v2_0/misc/fmt_util.h
new file mode 100644 (file)
index 0000000..03a3fca
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef __FMT_UTIL_H__
+#define __FMT_UTIL_H__
+//==========================================================================
+//
+//      fmt_util.g
+//
+//      Interface to generic string parsing and formatting utilities.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+/* Interface to generic string parsing and formatting utilities.
+
+   It is posible that these services need to be defined in
+   a platform dependent way. These will work for the majority of
+   processors. */
+
+extern int str2addr (char *string, mem_addr_t *res);
+extern void addr2str (mem_addr_t *addr, char *dest);
+
+#endif // __FMT_UTIL_H__
diff --git a/packages/cygmon/v2_0/misc/generic-stub.h b/packages/cygmon/v2_0/misc/generic-stub.h
new file mode 100644 (file)
index 0000000..d6b44ec
--- /dev/null
@@ -0,0 +1,54 @@
+//==========================================================================
+//
+//      generic-stub.h
+//
+//      
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Placeholder
diff --git a/packages/cygmon/v2_0/misc/generic_fmt32.c b/packages/cygmon/v2_0/misc/generic_fmt32.c
new file mode 100644 (file)
index 0000000..26d2112
--- /dev/null
@@ -0,0 +1,98 @@
+//==========================================================================
+//
+//      generic_fmt32.c
+//
+//      Generic address conversion routines
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Generic address conversion routines
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <string.h>
+#ifdef HAVE_BSP
+#include <bsp/bsp.h>
+#include <bsp/cpu.h>
+#endif
+#include "monitor.h"
+#include "fmt_util.h"
+
+
+int
+str2addr (char *string, mem_addr_t *res)
+{
+#ifdef HAVE_ASI
+  if (string[0] == '[')
+    {
+      char *ptr = ++string;
+      while (*ptr && *ptr != ']')
+       ptr++;
+
+      if (*ptr == 0)
+       return -1;
+
+      *(ptr++) = 0;
+      res->asi = str2int (string, 16);
+      string = ptr;
+    }
+  else
+    res->asi = ASI_DEFAULT;
+#endif
+  res->addr = str2int (string, 16);
+  return 0;
+}
+
+void
+addr2str (mem_addr_t *addr, char *dest)
+{
+#ifdef HAVE_ASI
+  if (addr->asi != ASI_DEFAULT)
+    xsprintf(dest, "[%x]", addr->asi);
+  else
+#endif
+    dest[0] = 0;
+  strcat (dest, int2str (addr->addr, 16, sizeof (void *) * 2));
+}
diff --git a/packages/cygmon/v2_0/misc/generic_mem.c b/packages/cygmon/v2_0/misc/generic_mem.c
new file mode 100644 (file)
index 0000000..76c6c86
--- /dev/null
@@ -0,0 +1,99 @@
+//==========================================================================
+//
+//      generic_mem.c
+//
+//      Routines for reading and writing memory.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      
+// Description:  It may be appropriate to relay directly into the stubs
+//               implementation of read memory, without board specific
+//               considerations such as checking the allowed ranges of
+//               addresses. Perhaps there needs to be some consideration
+//               of address spaces or, masking addresses.
+//
+//               This file implements a default version of reading and writing
+//               memory when none of this is an issue
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#ifdef HAVE_BSP
+#include <bsp/bsp.h>
+#include "cpu_info.h"
+#endif
+#include "board.h"
+#include "monitor.h"
+#include "tservice.h"
+
+#ifndef HAVE_BSP
+#include "generic-stub.h"
+#endif
+
+
+int
+read_memory (mem_addr_t *src, int size, int amt, char *dst)
+{
+#if defined(HAVE_BSP) && !defined(USE_ECOS_HAL_SAFE_MEMORY)
+    return (bsp_memory_read((unsigned char *)src->addr, MEM_ADDR_ASI(src),
+                           size << 3, amt, dst) != amt);
+#else
+  int totamt = size * amt;
+  return (totamt != __read_mem_safe (dst, (void*)src->addr, totamt));
+#endif
+}
+
+int
+write_memory (mem_addr_t *dst, int size, int amt, char *src)
+{
+#if defined(HAVE_BSP) && !defined(USE_ECOS_HAL_SAFE_MEMORY)
+    return (bsp_memory_write((unsigned char *)dst->addr, MEM_ADDR_ASI(dst),
+                            size << 3, amt, src) != amt);
+#else
+  int totamt = size * amt;
+  return (totamt != __write_mem_safe (src, (void*)dst->addr, totamt));
+#endif
+}
+
+
+   
diff --git a/packages/cygmon/v2_0/misc/ledit.c b/packages/cygmon/v2_0/misc/ledit.c
new file mode 100644 (file)
index 0000000..c2609d3
--- /dev/null
@@ -0,0 +1,604 @@
+//==========================================================================
+//
+//      ledit.c
+//
+//      Utterly simple line editor
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Udderly simple line editor
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+
+#include <monitor.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_BSP
+#include <bsp/bsp.h>
+#endif
+#include "ledit.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+static char *cutBuf = NULL;
+
+#ifdef NO_MALLOC
+static char linebufArray [MAX_HIST_ENTS + 2][MAXLINELEN + 1];
+#endif
+
+static struct termcap 
+{
+  char *relleft, *relright;
+  char *oneleft;
+  char *insertch;
+  char *deletech;
+  char *deleteonech;
+  char *clreol;
+  char *gobol;
+  int width;
+} terminal;
+
+static struct linepos 
+{
+  char *prompt;
+  char *buffer;
+  char *ebuf;
+  int cursor;
+} linebuf;
+
+static struct history 
+{
+  char *cmd;
+  struct history *next, *prev;
+} *list = NULL, *topl = NULL, *curl = NULL;
+
+static int histlen = 0;
+static int histLimit = MAX_HIST_ENTS;
+
+static struct history histEnts[MAX_HIST_ENTS + 1], *histPtr = histEnts;
+static struct history currLine = { NULL, NULL, NULL };
+
+void
+beep (void)
+{
+  xputchar ('\007');
+}
+
+void
+printHistoryList () 
+{
+  struct history *hist = list;
+  int hist_num = 1;
+
+  if (hist != NULL)
+  {
+    while (hist->prev != NULL)
+    {
+      hist = hist->prev;
+    }
+
+    while (hist != NULL)
+    {
+      if (hist->cmd != NULL)
+        xprintf(" %d %s\n", hist_num++, hist->cmd);
+      hist = hist->next;
+    }
+  }
+}
+
+static void
+outputParamStr (char *str, int val)
+{
+  char *i = strchr (str, '%');
+  char *ptr;
+  int dist = val;
+
+  if (i == NULL)
+    {
+      while (dist-- > 0)
+       xprintf (str);
+    }
+  else
+    {
+      for (ptr = str; *ptr && ptr < i; ptr++)
+       xputchar (*ptr);
+      if (dist > 99)
+       {
+         xputchar ('0' + dist / 100);
+         dist = dist % 100;
+       }
+      if (dist > 9)
+       {
+         xputchar ('0' + dist / 10);
+         dist = dist % 10;
+       }
+      xputchar ('0' + dist);
+      if (*ptr)
+       xprintf (ptr + 1);
+    }
+}
+
+static void
+absMoveCursor (int pos)
+{
+  int dist, oldpos = linebuf.cursor;
+  int absdist;
+  char *bigmove;
+
+  if (pos > (linebuf.ebuf - linebuf.buffer))
+    {
+      beep ();
+      pos = linebuf.ebuf - linebuf.buffer;
+    }
+  else if (pos < 0)
+    pos = 0;
+  dist = pos - linebuf.cursor;
+  absdist = (dist < 0 ? -dist : dist);
+  linebuf.cursor = pos;
+  if (dist == 0)
+    return;
+  if (dist < 0)
+    bigmove = terminal.relleft;
+  else
+    bigmove = terminal.relright;
+
+  if ((absdist < 4) || (bigmove == NULL))
+    {
+      int x;
+      int promptLen = strlen (linebuf.prompt);
+
+      if (pos < (absdist - promptLen))
+       {
+         xprintf (terminal.gobol);
+         xprintf (linebuf.prompt);
+         for (x = 0; x < pos; x++)
+           xputchar (linebuf.buffer[x]);
+         return;
+       }
+
+      if (dist < 0)
+       {
+         for (x = 0; x < -dist ;x++)
+           xprintf (terminal.oneleft);
+       }
+      else
+       {
+         for (x = 0; x < dist; x++)
+           xputchar (linebuf.buffer [oldpos + x]);
+       }
+    }
+  else
+    {
+      outputParamStr (bigmove, absdist);
+    }
+}
+
+static void
+clrScrToEol (void)
+{
+  int len = linebuf.ebuf - linebuf.buffer;
+
+  if (len < linebuf.cursor)
+    return;
+
+  if(terminal.clreol)
+    {
+      xprintf (terminal.clreol);
+    }
+  else if (terminal.deletech)
+    {
+      outputParamStr (terminal.deletech, len - linebuf.cursor);
+    }
+  else
+    {
+      int oldcur = linebuf.cursor;
+      while (linebuf.cursor < len)
+       {
+         xputchar (' ');
+         linebuf.cursor++;
+       }
+      
+      absMoveCursor (oldcur);
+    }
+}
+
+static void
+redrawCmd (void)
+{
+  xprintf (terminal.gobol);
+  xprintf (linebuf.prompt);
+  linebuf.buffer[linebuf.cursor] = 0;
+  xprintf (linebuf.buffer);
+  clrScrToEol ();
+}
+
+static void
+instCmd (char *ncmd)
+{
+  linebuf.cursor = strlen (ncmd);
+  strcpy (linebuf.buffer, ncmd);
+  redrawCmd ();
+  linebuf.ebuf = linebuf.buffer + linebuf.cursor;
+}
+
+static void
+prevCmd (void) 
+{
+  if (curl == &currLine)
+    {
+      if (list != NULL)
+       {
+         *linebuf.ebuf = 0;
+#ifdef NO_MALLOC
+         currLine.cmd = linebufArray[MAX_HIST_ENTS];
+         strcpy (currLine.cmd, linebuf.buffer);
+#else
+         if (currLine.cmd != NULL)
+           free (currLine.cmd);
+         currLine.cmd = strdup (linebuf.buffer);
+#endif
+         curl = list;
+       }
+    }
+  else
+    {
+      if (curl->prev != NULL)
+       curl = curl->prev;
+    }
+  if (curl != NULL && curl->cmd != NULL)
+    instCmd (curl->cmd);
+  else
+    beep ();
+}
+
+static void
+nextCmd (void)
+{
+  if (curl->next == NULL)
+    {
+      beep ();
+    }
+  else
+    {
+      curl = curl->next;
+      instCmd (curl->cmd);
+    }
+
+}
+
+static int initted = 0;
+
+void
+initVt100 (void) 
+{
+  terminal.gobol = "\r";
+  terminal.oneleft = "\010";
+  terminal.relleft = "\033[%D";
+  terminal.relright = "\033[%C";
+  terminal.insertch = "\033[%@";
+  terminal.deletech = "\033[%P";
+  terminal.deleteonech = "\033[P";
+  terminal.clreol = "\033[K";
+  terminal.width = 80;
+  initted = 1;
+}
+
+void
+initDumb (void)
+{
+  terminal.gobol = "\r";
+  terminal.oneleft = "\010";
+  terminal.relleft = NULL;
+  terminal.relright = NULL;
+  terminal.insertch = NULL;
+  terminal.deletech = NULL;
+  terminal.deleteonech = NULL;
+  terminal.clreol = NULL;
+  terminal.width = 80;
+  initted = 1;
+}
+
+static void
+insertChar (char *chars, int num)
+{
+  int len = linebuf.ebuf - linebuf.buffer + strlen (linebuf.prompt);
+  int n = 0;
+
+  if ((len + num) >= terminal.width)
+    {
+      beep ();
+      return;
+    }
+  if ((linebuf.ebuf - linebuf.buffer) > linebuf.cursor)
+    {
+      char *ptr, *eptr = linebuf.buffer + linebuf.cursor;
+
+      for (ptr = linebuf.ebuf; ptr >= eptr; ptr--)
+       *(ptr+num) = *ptr;
+
+      if (terminal.insertch != NULL)
+       outputParamStr (terminal.insertch, num);
+    }
+  for (n = 0; n < num; n++)
+    {
+      xputchar (*chars);
+      linebuf.buffer[linebuf.cursor++] = *(chars++);
+    }
+
+  linebuf.ebuf += num;
+
+  if (terminal.insertch == NULL)
+    {
+      char *ptr = linebuf.buffer + linebuf.cursor;
+      int oldcur = linebuf.cursor;
+      for (; ptr < linebuf.ebuf; ptr++)
+       xputchar (*ptr);
+      linebuf.cursor = linebuf.ebuf - linebuf.buffer;
+      absMoveCursor (oldcur);
+    }
+}
+
+static void
+deleteEol (int putInCutBuffer)
+{
+  int len = linebuf.ebuf - linebuf.buffer;
+  if (linebuf.cursor < len)
+    {
+      clrScrToEol ();
+
+      if (putInCutBuffer)
+       {
+         *linebuf.ebuf = 0;
+#ifdef NO_MALLOC
+         cutBuf = linebufArray[MAX_HIST_ENTS + 1];
+         strcpy (cutBuf, linebuf.buffer + linebuf.cursor);
+#else
+         if (cutBuf != NULL)
+           free (cutBuf);
+         cutBuf = strdup (linebuf.buffer + linebuf.cursor);
+#endif
+       }
+      linebuf.ebuf = linebuf.buffer + linebuf.cursor;
+    }
+}
+
+static void
+deleteCurrChar (void)
+{
+  int len = linebuf.ebuf - linebuf.buffer;
+  char *ptr;
+  if (len == linebuf.cursor || len == 0)
+    return;
+  for (ptr = linebuf.buffer + linebuf.cursor; ptr < (linebuf.ebuf - 1); ptr++)
+    {
+      *ptr = *(ptr + 1);
+      if (terminal.deleteonech == NULL)
+       xputchar (*ptr);
+    }
+  linebuf.ebuf--;
+  if (terminal.deleteonech && (len - 1) != linebuf.cursor)
+    xprintf (terminal.deleteonech);
+  else
+    {
+      int oldcur = linebuf.cursor;
+      xputchar (' ');
+      linebuf.cursor = linebuf.ebuf - linebuf.buffer + 1;
+      absMoveCursor (oldcur);
+    }
+}
+
+static void
+deleteChar (void)
+{
+  if (linebuf.cursor == 0)
+    {
+      beep ();
+      return;
+    }
+  absMoveCursor (linebuf.cursor - 1);
+  deleteCurrChar ();
+}
+
+int
+lineedit (char *prompt, char *buffer, int maxLen)
+{
+  int c;
+
+  curl = &currLine;
+
+  if (!initted)
+    {
+      initted = 1;
+      /*initVt100 ();*/
+      initDumb();
+    }
+  linebuf.prompt = prompt;
+  linebuf.buffer = buffer;
+  linebuf.ebuf = buffer;
+  buffer[0] = 0;
+  linebuf.cursor = 0;
+  redrawCmd ();
+  while ((c=input_char ()) > 0) 
+    {
+      switch (c)
+       {
+       case PREVCMD:
+         prevCmd ();
+         break;
+       case NEXTCMD:
+         nextCmd ();
+         break;
+       case LF:
+       case CR:
+         *linebuf.ebuf = 0;
+#ifdef NO_MALLOC
+         cutBuf = NULL;
+         currLine.cmd = NULL;
+#else
+         if (cutBuf != NULL)
+           {
+             free (cutBuf);
+             cutBuf = NULL;
+           }
+         if (currLine.cmd != NULL)
+           {
+             free (currLine.cmd);
+             currLine.cmd = NULL;
+           }
+#endif
+         return linebuf.ebuf - linebuf.buffer;
+         break;
+       case BOLCMD:
+         absMoveCursor (0);
+         break;
+       case EOLCMD:
+         absMoveCursor (linebuf.ebuf-linebuf.buffer);
+         break;
+       case FORWCMD:
+         absMoveCursor (linebuf.cursor + 1);
+         break;
+       case BACKCMD:
+         absMoveCursor (linebuf.cursor - 1);
+         break;
+       case DELBACK:
+       case '\177':
+         deleteChar ();
+         break;
+       case ERASELINE:
+         absMoveCursor (0);
+         deleteEol (0);
+         break;
+       case DELEOL:
+         deleteEol (1);
+         break;
+       case DELCURRCH:
+         deleteCurrChar ();
+         break;
+       case YANKCH:
+         if (cutBuf != NULL)
+           insertChar (cutBuf,strlen (cutBuf));
+         break;
+       default:
+         if (c >= 32 && c < 127)
+           {
+             char ch = c;
+             insertChar (&ch, 1);
+           }
+         break;
+       }
+    }
+  return -1;
+}
+
+void
+addHistoryCmd (char *cmd)
+{
+  struct history *newent = NULL;
+
+  if (histlen >= histLimit)
+    {
+      newent = topl;
+      topl = topl->next;
+      topl->prev = NULL;
+#ifdef NO_MALLOC
+      newent->prev = NULL;
+      newent->next = NULL;
+#else
+      free (newent->cmd);
+      newent->cmd = NULL;
+#endif
+      histlen = histLimit - 1;
+    }
+
+  histlen++;
+
+  if (newent == NULL)
+    {
+      newent = histPtr++;
+#ifdef NO_MALLOC
+      newent->cmd = linebufArray[histlen - 1];
+#endif
+    }
+
+  if (list == NULL)
+    {
+      list = newent;
+      list->prev = NULL;
+      topl = list;
+    }
+  else
+    {
+      list->next = newent;
+      list->next->prev = list;
+      list = list->next;
+    }
+  currLine.prev = list;
+  list->next = &currLine;
+#ifdef NO_MALLOC
+  strcpy (list->cmd, cmd);
+#else
+  list->cmd = strdup (cmd);
+#endif
+  curl = &currLine;
+}
+
+void
+set_term_name (char *name)
+{
+  if (! strcmp (name, "vt100"))
+    {
+      initVt100 ();
+    }
+  else if (! strcmp (name, "dumb"))
+    {
+      initDumb ();
+    }
+  else
+    {
+      xprintf ("Unknown terminal name %s\n", name);
+    }  
+}
diff --git a/packages/cygmon/v2_0/misc/ledit.h b/packages/cygmon/v2_0/misc/ledit.h
new file mode 100644 (file)
index 0000000..083eeff
--- /dev/null
@@ -0,0 +1,88 @@
+//==========================================================================
+//
+//      ledit.h
+//
+//      Header for the utterly simple line editor
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Header for the udderly simple line editor
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#ifndef LEDIT_H
+#define LEDIT_H
+
+#define LF '\n'
+#define CR '\r'
+#define BOLCMD '\001'
+#define EOLCMD '\005'
+#define FORWCMD '\006'
+#define BACKCMD '\002'
+#define DELBACK '\010'
+#define DELEOL '\013'
+#define YANKCH '\031'
+#define DELCURRCH '\004'
+#define PREVCMD '\020'
+#define ERASELINE '\025'
+#define NEXTCMD '\016'
+
+/* Prompt for one line of input using PROMPT. The input from the user
+   (up to MAXINPLEN characters) will be stored in BUFFER. The number
+   of characters read will be returned. */
+extern int lineedit(char *prompt, char *buffer, int maxInpLen);
+
+/* Add CMD to the user's command history. */
+extern void addHistoryCmd (char *cmd);
+
+/* Configure the editor to use the specified terminal. */
+extern void set_term_name (char *name);
+
+/* Beep the terminal. */
+extern void beep (void);
+
+/* Print a history list. */
+extern void printHistoryList(void);
+
+#endif
diff --git a/packages/cygmon/v2_0/misc/mips/board.h b/packages/cygmon/v2_0/misc/mips/board.h
new file mode 100644 (file)
index 0000000..fff5918
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef __CYGMON_MIPS_BOARD_H__
+#define __CYGMON_MIPS_BOARD_H__
+//==========================================================================
+//
+//      board.h
+//
+//      Cygmon board/platform configuration file
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-07-11
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+// Hardware/platform/configuration specifics
+
+// These defines are only necessary for using target_reg union in monitor.h
+// It should be possible to remove that once the HAL integration is complete.
+#define HAVE_FLOAT_REGS         0
+#define HAVE_DOUBLE_REGS        0
+
+#define HAVE_CACHE              0
+#define HAVE_USAGE              0
+#define USE_CYGMON_PROTOTYPES   1
+#define NOMAIN                  1
+#define CYGMON_SYSTEM_SERVICES  0 // Not used, fall back to BSP/HAL support
+
+#ifdef CYGDAT_CYGMON_USE_HELP
+#define USE_HELP                1
+#endif
+
+#define USE_ECOS_HAL_EXCEPTIONS
+#define USE_ECOS_HAL_BREAKPOINTS
+#define USE_ECOS_HAL_SINGLESTEP
+
+#include "cpu_info.h"
+extern void bp_print (target_register_t bp_val);
+extern int __set_breakpoint (target_register_t addr);
+extern int __remove_breakpoint (target_register_t addr);
+extern void __install_breakpoint_list (void);
+extern void __clear_breakpoint_list (void);
+extern int __display_breakpoint_list (void (*print_func)(target_register_t));
+
+#define bsp_skip_instruction(regs)      __skipinst()
+#define install_breakpoints()           __install_breakpoints()
+#define add_mon_breakpoint(bpt)         __set_breakpoint((bpt).addr)
+#define clear_mon_breakpoint(bpt)       __remove_breakpoint((bpt).addr)
+#define show_breakpoints()              __display_breakpoint_list(bp_print)
+#define clear_breakpoints()             __clear_breakpoint_list()
+
+#define bsp_get_signal(exc_nr, regs)    __computeSignal(exc_nr)
+#define bsp_get_pc(regs)                get_register(PC)
+
+#define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
+#include <cyg/hal/mips-regs.h>
+#include "monitor.h"
+
+#ifdef __mips64
+#define bsp_set_pc(pc, regs)                \
+    put_register(PC, pc);                   \
+    if (regs->_sr & SR_ERL)                 \
+        put_register(EPC, pc);              \
+    else                                    \
+        put_register(EEPC, pc);
+#else
+#define bsp_set_pc(pc, regs)                \
+    put_register(PC, pc);
+#endif
+
+#endif //  __CYGMON_MIPS_BOARD_H__
diff --git a/packages/cygmon/v2_0/misc/mips/cpu.h b/packages/cygmon/v2_0/misc/mips/cpu.h
new file mode 100644 (file)
index 0000000..e746a2a
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __MIPS_CPU_H__
+#define __MIPS_CPU_H__
+//==========================================================================
+//
+//      cpu.h
+//
+//      MIPS specific processor defines
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-06-07
+// Purpose:      MIPS specific processor defines 
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+#define BSP_MAX_EXCEPTIONS CYGNUM_HAL_VSR_COUNT
+
+#endif // __MIPS_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/mips/cpu_info.h b/packages/cygmon/v2_0/misc/mips/cpu_info.h
new file mode 100644 (file)
index 0000000..adf6d70
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef __MIPS_CPU_INFO_H__
+#define __MIPS_CPU_INFO_H__
+//==========================================================================
+//
+//      cpu_info.h
+//
+//      Architecture information for MIPS processors
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-06-07
+// Purpose:      
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#define IS_MIPS 1
+
+/* Temporary as long a multiple protypes are copied in multiple files */
+/* This variation does NOT clone the prototypes */
+#define NO_MALLOC 1
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+
+/* big enuf to store a trap in the BP structure */
+
+#define BP_INST_T_DEFINED 1
+typedef unsigned int bp_inst_t ;
+
+#else /* USE_ECOS_HAL_BREAKPOINTS */
+
+#define MEM_ADDR_DEFINED 1 
+typedef struct mem_addr {
+  unsigned long addr;
+} mem_addr_t ;
+
+#endif /* USE_ECOS_HAL_BREAKPOINTS */
+
+typedef unsigned long target_register_t;
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/basetype.h>
+#if CYG_BYTEORDER == CYG_MSBFIRST
+#define PRINT_INSN print_insn_big_mips
+#else
+#define PRINT_INSN print_insn_little_mips
+#endif
+
+#undef BFD_MACH
+#define BFD_MACH 0
+
+#endif // __MIPS_CPU_INFO_H__
diff --git a/packages/cygmon/v2_0/misc/mips/mips-mon.c b/packages/cygmon/v2_0/misc/mips/mips-mon.c
new file mode 100644 (file)
index 0000000..ab6067c
--- /dev/null
@@ -0,0 +1,183 @@
+//==========================================================================
+//
+//      mips-mon.c
+//
+//      Support code to extend the generic monitor code to support
+//      MIPS processors.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-06-07
+// Purpose:      Support code to extend the generic monitor code to support
+//               MIPS(R) processors.
+// Description:  Further board specific support is in other files.
+//               This file contains:
+//                 register names lookup table
+//
+//               Empty Stubs:
+//                 Interval timer - This should really belong to the application
+//                 operating system.
+//
+//               Should not contain:
+//                 low level uart getchar and putchar functions
+//                 delay function to support uart
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include "monitor.h"
+
+struct regstruct regtab[] =
+{
+    { "zero",      REG_ZERO },
+    { "at",        REG_AT },
+    { "v0",        REG_V0 },
+    { "v1",        REG_V1 },
+    { "a0",        REG_A0 },
+    { "a1",        REG_A1 },
+    { "a2",        REG_A2 },
+    { "a3",        REG_A3 },
+    { "t0",        REG_T0 },
+    { "t1",        REG_T1 },
+    { "t2",        REG_T2 },
+    { "t3",        REG_T3 },
+    { "t4",        REG_T4 },
+    { "t5",        REG_T5 },
+    { "t6",        REG_T6 },
+    { "t7",        REG_T7 },
+    { "s0",        REG_S0 },
+    { "s1",        REG_S1 },
+    { "s2",        REG_S2 },
+    { "s3",        REG_S3 },
+    { "s4",        REG_S4 },
+    { "s5",        REG_S5 },
+    { "s6",        REG_S6 },
+    { "s7",        REG_S7 },
+    { "t8",        REG_T8 },
+    { "t9",        REG_T9 },
+    { "k0",        REG_K0 },
+    { "k1",        REG_K1 },
+    { "gp",        REG_GP },
+    { "sp",        REG_SP },
+    { "s8",        REG_S8 },
+    { "ra",        REG_RA },
+
+    { "sr",        REG_SR },
+    { "lo",        REG_LO },
+    { "hi",        REG_HI },
+    { "badvr",     REG_BAD },
+    { "cause",     REG_CAUSE },
+    { "pc",        REG_PC },
+#ifdef CYGHWR_HAL_MIPS_FPU
+    { "f0",        REG_F0 },
+    { "f1",        REG_F1 },
+    { "f2",        REG_F2 },
+    { "f3",        REG_F3 },
+    { "f4",        REG_F4 },
+    { "f5",        REG_F5 },
+    { "f6",        REG_F6 },
+    { "f7",        REG_F7 },
+    { "f8",        REG_F8 },
+    { "f9",        REG_F9 },
+    { "f10",       REG_F10 },
+    { "f11",       REG_F11 },
+    { "f12",       REG_F12 },
+    { "f13",       REG_F13 },
+    { "f14",       REG_F14 },
+    { "f15",       REG_F15 },
+    { "f16",       REG_F16 },
+    { "f17",       REG_F17 },
+    { "f18",       REG_F18 },
+    { "f19",       REG_F19 },
+    { "f20",       REG_F20 },
+    { "f21",       REG_F21 },
+    { "f22",       REG_F22 },
+    { "f23",       REG_F23 },
+    { "f24",       REG_F24 },
+    { "f25",       REG_F25 },
+    { "f26",       REG_F26 },
+    { "f27",       REG_F27 },
+    { "f28",       REG_F28 },
+    { "f29",       REG_F29 },
+    { "f30",       REG_F30 },
+    { "f31",       REG_F31 },
+    { "fcr31",     REG_FCR31 },
+#endif /* CYGHWR_HAL_MIPS_FPU */
+    { 0, 0 }, /* Terminating element must be last */
+} ;
+
+void
+initialize_mon(void)
+{
+} /* initialize_mon */
+
+
+#include <cyg/hal/hal_arch.h>
+#include <bsp/common/bsp_if.h>
+int
+machine_syscall(HAL_SavedRegisters *regs)
+{
+    int res, err;
+    target_register_t a0, a1, a2, a3;
+
+    a0 = get_register(REG_A0);
+    a1 = get_register(REG_A1);
+    a2 = get_register(REG_A2);
+    a3 = get_register(REG_A3);
+
+    err = _bsp_do_syscall(a0, // Function
+                          a1, a2, a3, 0, // arguments,
+                          &res);
+    if (err)
+    {
+        // This was a syscall.  It has now been handled, so update the registers appropriately
+        put_register(REG_V0, res);
+        bsp_skip_instruction(regs);
+    }
+
+    return err;
+}
+
+
+// Utility function for printing breakpoints
+void bp_print(target_register_t bp_val)
+{
+    bsp_printf("0x%08lx\n", (unsigned long)bp_val);
+}
diff --git a/packages/cygmon/v2_0/misc/mn10300/board.h b/packages/cygmon/v2_0/misc/mn10300/board.h
new file mode 100644 (file)
index 0000000..19b6ba1
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef __CYGMON_MN10300_BOARD_H__
+#define __CYGMON_MN10300_BOARD_H__
+//==========================================================================
+//
+//      board.h
+//
+//      Cygmon board/platform configuration file
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+// Hardware/platform/configuration specifics
+
+// These defines are only necessary for using target_reg union in monitor.h
+// It should be possible to remove that once the HAL integration is complete.
+#if CYGHWR_HAL_MN10300_AM33_REVISION == 2
+#define HAVE_FLOAT_REGS         1
+#else
+#define HAVE_FLOAT_REGS         0
+#endif
+#define HAVE_DOUBLE_REGS        0
+
+#define HAVE_CACHE              0
+#define HAVE_USAGE              0
+#define USE_CYGMON_PROTOTYPES   1
+#define NOMAIN                  1
+#define CYGMON_SYSTEM_SERVICES  0 // Not used, fall back to BSP/HAL support
+
+#ifdef CYGDAT_CYGMON_USE_HELP
+#define USE_HELP                1
+#endif
+
+#define USE_ECOS_HAL_EXCEPTIONS
+#define USE_ECOS_HAL_BREAKPOINTS
+#define USE_ECOS_HAL_SINGLESTEP
+#define USE_ECOS_HAL_SAFE_MEMORY
+extern int __read_mem_safe (void *dst, void *src, int count);
+extern int __write_mem_safe (void *src, void *dst, int count);
+
+
+#include "cpu_info.h"
+extern void bp_print (target_register_t bp_val);
+extern int __set_breakpoint (target_register_t addr);
+extern int __remove_breakpoint (target_register_t addr);
+extern void __install_breakpoint_list (void);
+extern void __clear_breakpoint_list (void);
+extern int __display_breakpoint_list (void (*print_func)(target_register_t));
+
+#define bsp_skip_instruction(regs)      __skipinst()
+#define install_breakpoints()           __install_breakpoints()
+#define add_mon_breakpoint(bpt)         __set_breakpoint((bpt).addr)
+#define clear_mon_breakpoint(bpt)       __remove_breakpoint((bpt).addr)
+#define show_breakpoints()              __display_breakpoint_list(bp_print)
+#define clear_breakpoints()             __clear_breakpoint_list()
+
+#define bsp_get_signal(exc_nr, regs)    __computeSignal(exc_nr)
+#define bsp_get_pc(regs)                get_register(PC)
+#define bsp_set_pc(pc, regs)            put_register(PC, pc);
+
+#endif //  __CYGMON_MN10300_BOARD_H__
diff --git a/packages/cygmon/v2_0/misc/mn10300/cpu.h b/packages/cygmon/v2_0/misc/mn10300/cpu.h
new file mode 100644 (file)
index 0000000..ae8a50d
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef __MN10300_CPU_H__
+#define __MN10300_CPU_H__
+//==========================================================================
+//
+//      cpu.h
+//
+//      MN10300 specific processor defines
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      MN10300 specific processor defines 
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <cyg/hal/hal_intr.h>
+
+#define BSP_MAX_EXCEPTIONS CYGNUM_HAL_VSR_COUNT
+
+#define REG_PC PC
+
+#endif // __MN10300_CPU_H__
diff --git a/packages/cygmon/v2_0/misc/mn10300/cpu_info.h b/packages/cygmon/v2_0/misc/mn10300/cpu_info.h
new file mode 100644 (file)
index 0000000..000c8af
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef __MN10300_CPU_INFO_H__
+#define __MN10300_CPU_INFO_H__
+//==========================================================================
+//
+//      cpu_info.h
+//
+//      Architecture information for MN10300 processors
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#define IS_MN10300 1
+
+/* Temporary as long a multiple protypes are copied in multiple files */
+/* This variation does NOT clone the prototypes */
+#define NO_MALLOC 1
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+
+/* big enuf to store a trap in the BP structure */
+
+#define BP_INST_T_DEFINED 1
+typedef unsigned char bp_inst_t ;
+
+#else /* USE_ECOS_HAL_BREAKPOINTS */
+
+#define MEM_ADDR_DEFINED 1 
+typedef struct mem_addr {
+  unsigned long addr;
+} mem_addr_t ;
+
+#endif /* USE_ECOS_HAL_BREAKPOINTS */
+
+typedef unsigned long target_register_t;
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/basetype.h>
+#define PRINT_INSN print_insn_mn10300
+
+#undef BFD_MACH
+#define BFD_MACH 0
+
+// Ensure that the reg_valid field in regstruct is used.
+#define REG_VALID_FIELD_IN_REGSTRUCT
+#define INITIALIZE_MON_EACH_TIME() initialize_mon_each_time()
+extern void initialize_mon_each_time(void);
+
+#endif // __MN10300_CPU_INFO_H__
diff --git a/packages/cygmon/v2_0/misc/mn10300/mn10300-mon.c b/packages/cygmon/v2_0/misc/mn10300/mn10300-mon.c
new file mode 100644 (file)
index 0000000..205c7f6
--- /dev/null
@@ -0,0 +1,206 @@
+//==========================================================================
+//
+//      mn10300-mon.c
+//
+//      Support code to extend the generic monitor code to support
+//      MN10300 processors.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    dmoseley
+// Contributors: dmoseley
+// Date:         2000-08-11
+// Purpose:      Support code to extend the generic monitor code to support
+//               MN10300 processors.
+// Description:  Further board specific support is in other files.
+//               This file contains:
+//                 register names lookup table
+//
+//               Empty Stubs:
+//                 Interval timer - This should really belong to the application
+//                 operating system.
+//
+//               Should not contain:
+//                 low level uart getchar and putchar functions
+//                 delay function to support uart
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include "monitor.h"
+
+struct regstruct regtab[] =
+{
+    {"d0",       D0,          1},
+    {"d1",       D1,          1},
+    {"d2",       D2,          1},
+    {"d3",       D3,          1},
+    {"a0",       A0,          1},
+    {"a1",       A1,          1},
+    {"a2",       A2,          1},
+    {"a3",       A3,          1},
+    {"sp",       SP,          1},
+    {"pc",       PC,          1},
+    {"mdr",      MDR,         1},
+    {"psw",      PSW,         1},
+    {"lir",      LIR,         1},
+    {"lar",      LAR,         1},
+#ifdef CYGPKG_HAL_MN10300_AM33
+    {"r0",       R0,          1},
+    {"r1",       R1,          1},
+    {"r2",       R2,          1},
+    {"r3",       R3,          1},
+    {"r4",       R4,          1},
+    {"r5",       R5,          1},
+    {"r6",       R6,          1},
+    {"r7",       R7,          1},
+    {"ssp",      SSP,         1},
+    {"msp",      MSP,         1},
+    {"usp",      USP,         1},
+    {"mcrh",     MCRH,        1},
+    {"mcrl",     MCRL,        1},
+    {"mcvf",     MCVF,        1},
+    {"mdrq",     MDRQ,        1},
+#if CYGHWR_HAL_MN10300_AM33_REVISION == 2
+    {"fpcr",     FPCR,        1},
+    {"fs0",      FS0,         1},
+    {"fs1",      FS1,         1},
+    {"fs2",      FS2,         1},
+    {"fs3",      FS3,         1},
+    {"fs4",      FS4,         1},
+    {"fs5",      FS5,         1},
+    {"fs6",      FS6,         1},
+    {"fs7",      FS7,         1},
+    {"fs8",      FS8,         1},
+    {"fs9",      FS9,         1},
+    {"fs10",     FS10,        1},
+    {"fs11",     FS11,        1},
+    {"fs12",     FS12,        1},
+    {"fs13",     FS13,        1},
+    {"fs14",     FS14,        1},
+    {"fs15",     FS15,        1},
+    {"fs16",     FS16,        1},
+    {"fs17",     FS17,        1},
+    {"fs18",     FS18,        1},
+    {"fs19",     FS19,        1},
+    {"fs20",     FS20,        1},
+    {"fs21",     FS21,        1},
+    {"fs22",     FS22,        1},
+    {"fs23",     FS23,        1},
+    {"fs24",     FS24,        1},
+    {"fs25",     FS25,        1},
+    {"fs26",     FS26,        1},
+    {"fs27",     FS27,        1},
+    {"fs28",     FS28,        1},
+    {"fs29",     FS29,        1},
+    {"fs30",     FS30,        1},
+    {"fs31",     FS31,        1},
+#endif
+#endif  
+    { 0,         0,           1}, /* Terminating element must be last */
+} ;
+
+void
+initialize_mon(void)
+{
+} /* initialize_mon */
+
+#if CYGHWR_HAL_MN10300_AM33_REVISION == 2
+extern int fpu_regs_read;
+#endif
+
+#ifdef CYGPKG_HAL_MN10300_AM33
+extern int msp_read;
+#endif
+
+void
+initialize_mon_each_time(void)
+{
+  int i;
+#if CYGHWR_HAL_MN10300_AM33_REVISION == 2
+  // Make sure the regtab[] indicates the valid status of the FPU registers
+  for (i = 0; regtab[i].registername != NULL; i++)
+    {
+      if ((regtab[i].registernumber >= FP_START) && (regtab[i].registernumber <= FP_END))
+        regtab[i].registervalid = fpu_regs_read;
+    }
+#endif
+
+#ifdef CYGPKG_HAL_MN10300_AM33
+  // Make sure the regtab[] indicates the valid status of the MSP
+  for (i = 0; regtab[i].registername != NULL; i++)
+    {
+      if (regtab[i].registernumber == MSP)
+          regtab[i].registervalid = msp_read;
+    }
+#endif
+} /* initialize_mon_each_time */
+
+
+#include <cyg/hal/hal_arch.h>
+#include <bsp/common/bsp_if.h>
+int
+machine_syscall(HAL_SavedRegisters *regs)
+{
+    int res, err;
+    target_register_t d0, d1, d2, d3;
+
+    d0 = get_register(D0);
+    d1 = get_register(D1);
+    d2 = get_register(D2);
+    d3 = get_register(D3);
+
+    err = _bsp_do_syscall(d0, // Function
+                          d1, d2, d3, 0, // arguments,
+                          &res);
+    if (err)
+    {
+        // This was a syscall.  It has now been handled, so update the registers appropriately
+        put_register(D0, res);
+        bsp_skip_instruction(regs);
+    }
+
+    return err;
+}
+
+
+// Utility function for printing breakpoints
+void bp_print(target_register_t bp_val)
+{
+    bsp_printf("0x%08lx\n", (unsigned long)bp_val);
+}
diff --git a/packages/cygmon/v2_0/misc/monitor.c b/packages/cygmon/v2_0/misc/monitor.c
new file mode 100644 (file)
index 0000000..06c04ae
--- /dev/null
@@ -0,0 +1,494 @@
+//==========================================================================
+//
+//      monitor.c
+//
+//      Monitor shell and main routines for CygMON the Wonder Monitor
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      Monitor shell and main routines for CygMON the Wonder Monitor
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+/* Platform-independent code for cygmon */
+
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef HAVE_BSP
+#include <bsp/bsp.h>
+#include <bsp/cpu.h>
+#include <bsp/hex-utils.h>
+#endif
+#include <monitor.h>
+#ifdef HAVE_BSP
+#include "cpu_info.h"
+#endif
+#include <ledit.h>
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+
+#if USE_CYGMON_PROTOTYPES
+/* Use common prototypes */
+/* Some of the composed board.h files compose these
+   prototypes redundently, but if they dont,
+   these are the common definitions */
+#include "fmt_util.h"   /* Interface to string formatting utilities */
+#include "tservice.h"   /* Interface to target specific services */
+#include "generic-stub.h" /* from libstub */
+#endif /* USE_CYGMON_PROTOTYPES */
+
+static int  cygmon_handle_exception (int sigval);
+static void monitor_take_control (void);
+
+#if CYGMON_SYSTEM_SERVICES
+extern int process_syscall (int syscall_num);
+#elif defined (USE_ECOS_HAL_EXCEPTIONS)
+static int cygmon_process_syscall (int sigval);
+#endif
+
+int stub_is_active = 0;
+mem_addr_t last_pc;
+
+#ifdef HAVE_BSP
+
+#if !defined(USE_ECOS_HAL_EXCEPTIONS)
+static int mon_dbg_handler(int exc_nr, void *regs);
+static int mon_kill_handler(int exc_nr, void *regs);
+#endif // USE_ECOS_HAL_EXCEPTIONS
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+#define __is_breakpoint_function() (get_pc() == (target_register_t)bsp_breakinsn)
+#endif
+
+#ifdef __ECOS__
+/*
+ * This global flag is used by generic-stub.c to communicate to us that we
+ * are processing the breakpoint function within Cygmon itself.
+ */
+extern int processing_breakpoint_function;
+#endif
+
+/* Global pointer to current set of saved registers. */
+void *mon_saved_regs;
+
+/* Original BSP debug vector replaced by monitor. */
+#if !defined(USE_ECOS_HAL_EXCEPTIONS)
+static bsp_handler_t old_dbg_vec;
+#endif // !defined(USE_ECOS_HAL_EXCEPTIONS)
+
+#else
+static int handle_signal (int signal_val);
+
+__PFI user_signal_handler = NULL;
+#endif
+
+#if defined(__ECOS__)
+#include <cyg/hal/hal_stub.h>
+#endif
+
+#if defined(__ECOS__) && !defined(PROCESS_EXCEPTION_VEC_PROTOTYPE_EXISTS)
+#define PROCESS_EXCEPTION_VEC_PROTOTYPE_EXISTS
+extern volatile __PFI (*__process_exception_vec)(int);
+#endif
+
+
+#ifdef MONITOR_CONTROL_INTERRUPTS
+/* This is set if the user wants interrupts enabled in the monitor. */
+static int monitor_interrupts_enabled;
+#endif
+
+
+#if NOMAIN
+int monitor_main (int argc, char **argv) /* Suppress default main() junk */
+#else
+int main (int argc, char **argv)     
+#endif
+{
+#ifdef HAVE_BSP
+  int  cur_port;
+  struct bsp_comm_info comm_info;
+#else
+  /* Set up exception handling traps */
+  initialize_stub ();
+#endif
+
+  initialize_mon ();
+
+#ifdef HAVE_BSP
+  /* get info on debug channel */
+  cur_port = bsp_set_debug_comm(-1);
+  bsp_sysinfo(BSP_INFO_COMM, cur_port, &comm_info);
+
+  /*
+   * If we're using a network interface, don't install
+   * the cygmon vectors. Currently, we only support stub
+   * mode over a network connection.
+   */
+  if (comm_info.kind != BSP_COMM_ENET)
+    {
+      xprintf("\n");
+      version ();
+
+      /* replace original BSP debug and kill handler with ours */
+#if !defined(USE_ECOS_HAL_EXCEPTIONS)
+      old_dbg_vec = bsp_install_dbg_handler(mon_dbg_handler);
+      (void)bsp_install_kill_handler(mon_kill_handler);
+#else
+      /* replace original BSP debug and kill handler with ours using eCos stuff */
+      __process_exception_vec = (__PFI)cygmon_handle_exception;
+      __process_syscall_vec = cygmon_process_syscall;
+      __process_exit_vec = monitor_take_control;
+#endif // __ECOS__
+    }
+  else
+    {
+      /* This forces the console to use the gdb channel. */
+      bsp_set_console_comm(cur_port);
+    }
+#else
+  xprintf("\n");
+  version ();
+
+  __process_exception_vec = cygmon_handle_exception;
+  __process_exit_vec = monitor_take_control;
+#if CYGMON_SYSTEM_SERVICES
+  __process_syscall_vec = process_syscall;
+#endif  
+  __process_signal_vec = handle_signal;
+  __init_vec = install_breakpoints;
+  __cleanup_vec = clear_breakpoints;
+#endif
+
+#if 0
+#ifdef __ECOS__
+  __process_exception_vec = cygmon_handle_exception;
+#endif
+#endif
+
+  while (1)
+    {
+      breakpoint ();
+      if (switch_to_stub_flag)
+        {
+         xprintf("Switching to stub\n");
+         switch_to_stub_flag = 0;
+       }
+    }
+
+  /* never reached */
+  exit (0);
+}
+
+
+/* Transfer control to gdb stub */
+int 
+transfer_to_stub ()
+{
+  /* Return back to the exception handler, but the exception handler
+     should invoke the stub's exception handler instead of ours. */
+#if defined(HAVE_BSP) && !defined(USE_ECOS_HAL_EXCEPTIONS)
+  (void)bsp_install_dbg_handler(old_dbg_vec);
+#else
+  __switch_to_stub ();
+#endif
+
+  /* The stub is now active. */
+  stub_is_active = 1;
+  return -1;
+}
+
+void
+clear_user_state (void)
+{
+#ifdef HAS_TIMER
+  if (__timer_enabled ())
+    __settimer (0, 0);
+#endif
+
+  clear_breakpoints ();
+
+#ifndef HAVE_BSP
+  user_signal_handler = NULL;
+#endif
+
+  __clear_single_step ();
+}
+
+static void
+monitor_take_control (void)
+{
+  stub_is_active = 0;
+  switch_to_stub_flag = 0;
+
+  // Flush the unget state.  This is because the ecos stub and Cygmon track this
+  // stuff separately.
+  bsp_debug_ungetc('\0');
+
+#ifdef INITIALIZE_MON_EACH_TIME
+  // Call the per-stop initialization routine if it is defined.
+  INITIALIZE_MON_EACH_TIME();
+#endif
+
+#if defined(HAVE_BSP) && !defined(USE_ECOS_HAL_EXCEPTIONS)
+  /* replace original BSP debug trap handler with ours */
+  (void)bsp_install_dbg_handler(mon_dbg_handler);
+#else
+  clear_user_state ();
+  __process_exception_vec = cygmon_handle_exception;
+#endif
+}
+
+
+#ifdef MONITOR_CONTROL_INTERRUPTS
+void
+monitor_enable_interrupts (void)
+{
+  monitor_interrupts_enabled = 1;
+  enable_interrupts ();
+}
+
+void
+monitor_disable_interrupts (void)
+{
+  monitor_interrupts_enabled = 0;
+  disable_interrupts ();
+}
+
+int
+monitor_interrupt_state (void)
+{
+  return monitor_interrupts_enabled;
+}
+#endif
+
+#if defined(USE_ECOS_HAL_EXCEPTIONS)
+externC HAL_SavedRegisters *_hal_registers;
+extern int machine_syscall(HAL_SavedRegisters *regs);
+static int
+cygmon_process_syscall (int sigval)
+{
+    return machine_syscall(_hal_registers);
+}
+#endif
+
+static int
+cygmon_handle_exception (int sigval)
+{
+  target_register_t pc;
+
+#ifdef MONITOR_CONTROL_INTERRUPTS
+  if (monitor_interrupts_enabled)
+    {
+      if (! __in_interrupt)
+       enable_interrupts ();
+    }
+#endif
+
+#ifdef TARGET_EXCEPTION_CODE
+  TARGET_EXCEPTION_CODE
+#endif
+
+#ifndef HAVE_BSP
+  if (sigval != SIGKILL)
+    if (handle_signal (sigval) == 0)
+      return 0;
+#endif
+
+  clear_user_state ();
+
+  /* We may want to tweak the PC to point at the faulting instruction,
+     for example. (breakpoints on x86). */
+#ifdef TARGET_ADJUST_PC
+  TARGET_ADJUST_PC
+#endif
+
+  pc = get_pc();
+  MAKE_STD_ADDR (pc, &last_pc);
+
+#ifdef __ECOS__
+  if ((sigval == SIGTRAP) && (__is_breakpoint_function() || processing_breakpoint_function))
+#else
+  if ((sigval == SIGTRAP) && __is_breakpoint_function())
+#endif
+    {
+      /*
+       * This is the initial breakpoint inserted by the BSP
+       * Don't print anything for this as it is confusing
+       */
+    }
+  else
+    {
+      if (sigval == SIGTRAP)
+          xprintf ("Hit breakpoint");
+      else
+          xprintf ("Got signal %d", sigval);
+
+      xprintf (" at 0x%s\n", int2str (pc, 16, sizeof (target_register_t) * 2));
+
+#ifdef DISASSEMBLER
+      if (!__is_breakpoint_function ())
+       {
+         do_dis (&last_pc);
+         flush_dis ();
+       }
+#endif
+    }
+
+  monitor_take_control ();
+
+  return monitor_loop ();
+}
+
+#ifndef HAVE_BSP
+/* Returns 0 if the program should restart at the point at which the
+   signal was received, -1 otherwise. */
+static int
+handle_signal (int signal)
+{
+  if (signal == SIGKILL)
+    return -1;
+
+  if (user_signal_handler != NULL)
+    {
+      int result = user_signal_handler (signal);
+      switch (result)
+       {
+         /* Don't ignore potential hardware signals. */
+       case 3:
+         if (signal == SIGSEGV || signal == SIGBUS || signal == SIGFPE
+             || signal == SIGTRAP || signal == SIGILL)
+           return -1;
+
+       case 0:
+         return 0;
+
+       default:
+       case 1:
+       case 2:
+         return -1;
+       }
+    }
+    return -1;
+}
+#endif
+
+
+void
+version (void)
+{
+#ifdef HAVE_BSP
+  struct bsp_platform_info platform;
+  struct bsp_mem_info      mem;
+  int                      i;
+  unsigned long            u, totmem, topmem;
+#endif
+  extern char *build_date;
+
+  xprintf ("Cygmon, the Cygnus ROM monitor.\n");
+  xprintf ("Copyright(c) 1997, 1998, 1999, 2000 Red Hat\n\n");
+  xprintf ("Version: %s\nThis image was built on %s\n\n",
+          VERSION, build_date);
+
+#ifdef HAVE_BSP
+  bsp_sysinfo(BSP_INFO_PLATFORM, &platform);
+
+  totmem = topmem = 0;
+  i = 0;
+  while (bsp_sysinfo(BSP_INFO_MEMORY, i++, &mem) == 0)
+    {
+      if (mem.kind == BSP_MEM_RAM)
+        {
+          totmem += mem.nbytes;
+          u = (unsigned long)mem.virt_start + mem.nbytes;
+         if (u > topmem)
+           topmem = u;
+        }
+    }
+
+  xprintf("CPU: %s\n", platform.cpu);
+  xprintf("Board: %s\n", platform.board);
+  if (*(platform.extra))
+      xprintf("%s\n", platform.extra);
+  xprintf("Total RAM: %d bytes\n", totmem);
+  xprintf("Top of RAM: 0x%x\n", topmem);
+#endif
+}
+
+
+#ifdef HAVE_BSP
+#if !defined(USE_ECOS_HAL_EXCEPTIONS)
+static int
+mon_kill_handler(int exc_nr, void *regs)
+{
+    monitor_take_control();
+    return 1;
+}
+#endif // !defined(USE_ECOS_HAL_EXCEPTIONS)
+
+#if !defined(USE_ECOS_HAL_EXCEPTIONS)
+static int
+mon_dbg_handler(int exc_nr, void *regs)
+{
+    int sig;
+    unsigned long cur_pc;
+
+    mon_saved_regs = regs;
+    sig = bsp_get_signal(exc_nr, regs);
+
+    cygmon_handle_exception(sig);
+
+    cur_pc = bsp_get_pc(regs);
+    if (cur_pc == (unsigned long)bsp_breakinsn)
+       bsp_skip_instruction(regs);
+
+    if (!stub_is_active)
+       install_breakpoints();
+
+    return 1;
+}
+#endif // !defined(USE_ECOS_HAL_EXCEPTIONS)
+
+#endif
diff --git a/packages/cygmon/v2_0/misc/monitor.h b/packages/cygmon/v2_0/misc/monitor.h
new file mode 100644 (file)
index 0000000..fe1a619
--- /dev/null
@@ -0,0 +1,303 @@
+//==========================================================================
+//
+//      monitor.h
+//
+//      Main definitions for the CygMON ROM monitor
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      Main definitions for the CygMON ROM monitor
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#ifndef MONITOR_H
+#define MONITOR_H
+
+#if !defined(__ASSEMBLER__)
+#include <stdarg.h>
+#endif
+
+#include <board.h>
+#ifdef HAVE_BSP
+#include "cpu_info.h"
+#endif
+#include <monitor_cmd.h>
+
+#ifdef __ECOS__
+#include <cyg/hal/plf_stub.h>
+#endif
+
+#ifndef ASM
+
+#ifdef HAVE_BSP
+#define xprintf    bsp_dprintf
+#define xsprintf   bsp_sprintf
+#define xvprintf   bsp_dvprintf
+#define xputchar   bsp_debug_putc
+#define xgetchar   bsp_debug_getc
+#define xungetchar bsp_debug_ungetc
+#define __getTty() bsp_set_debug_comm(-1)
+#define set_pc(x)  bsp_set_pc((x), mon_saved_regs)
+
+#ifndef USE_ECOS_HAL_SINGLESTEP
+#define __single_step()            bsp_singlestep_setup(mon_saved_regs)
+#define __clear_single_step()      bsp_singlestep_cleanup(mon_saved_regs)
+#endif /* USE_ECOS_HAL_SINGLESTEP */
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+#define breakpoint() bsp_breakpoint()
+#endif /* USE_ECOS_HAL_BREAKPOINTS */
+
+#if defined(__ECOS__) && defined(CYGHWR_HAL_RESET_DEFINED)
+   extern void __reset(void);
+#else // defined(__ECOS__) && defined(CYGHWR_HAL_RESET_DEFINED)
+#  define __reset    bsp_reset
+#endif // defined(__ECOS__) && defined(CYGHWR_HAL_RESET_DEFINED)
+
+#else
+extern void xprintf(const char *fmt, ...);
+extern void xsprintf(char *str, const char *fmt, ...);
+extern void xvprintf(const char *fmt, va_list ap);
+
+#ifdef HAS_USER_IO
+#define xputchar   putUserChar
+#define xgetchar   getUserChar
+#else
+extern void putDebugChar(int ch);
+extern int  getDebugChar(void);
+#define xputchar   putDebugChar
+#define xgetchar   getDebugChar
+#endif
+#define xungetchar ungetDebugChar
+#endif
+
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+struct bp {
+  mem_addr_t address;
+  bp_inst_t  old_inst;
+  char       in_memory;
+  struct bp  *next;
+};
+#endif // USE_ECOS_HAL_BREAKPOINTS
+
+struct regstruct
+{
+  char *registername;
+  int  registernumber;
+#ifdef HAVE_BSP
+#if defined(CYGPKG_HAL_ARM) || !defined(__ECOS__)
+  int  registertype;
+#endif // defined(CYGPKG_HAL_ARM) || !defined(__ECOS__)
+#endif
+#ifdef REG_VALID_FIELD_IN_REGSTRUCT
+  int registervalid;
+#endif
+};
+
+
+
+#ifdef HAVE_BSP
+#define REGTYPE_INT    1
+#define REGTYPE_FLOAT  2
+#define REGTYPE_DOUBLE 3
+
+union target_reg
+{
+    unsigned long  i;  /* integer register (32/64 bit) */
+#if HAVE_FLOAT_REGS
+    float          f;  /* float register (32bit)       */
+#endif
+#if HAVE_DOUBLE_REGS
+    double         d;  /* double register (64bit)      */
+#endif
+};
+
+typedef union target_reg target_regval_t;
+
+
+/* This is a template for what should be defined in  the board specific
+   header file composed, board.h */
+#if ! defined(MEM_ADDR_DEFINED)
+#define MEM_ADDR_DEFINED 1
+typedef struct mem_addr {
+  unsigned long addr;
+} mem_addr_t;
+#endif
+
+#if !defined(BP_INST_T_DEFINED)
+#define BP_INST_T_DEFINED 1
+typedef unsigned char bp_inst_t ;
+#endif
+
+#if ! defined(MAKE_STD_ADDR)
+#define MAKE_STD_ADDR(SRC, DST) ((DST)->addr = (SRC))
+#endif
+
+
+#if ! defined(ADD_OFFSET)
+#define ADD_OFFSET(SRC,DST,OFFSET) ((DST)->addr = (SRC)->addr + (OFFSET))
+#endif
+
+#if ! defined(ADD_ALIGN)
+#define ADD_ALIGN(SRC,DST,ALIGN) \
+              ((DST)->addr = (SRC)->addr - ((SRC)->addr % (ALIGN)))
+#endif
+
+#if ! defined(MEM_ADDR_EQ_P)
+#define MEM_ADDR_EQ_P(A, B) ((A).addr == (B).addr)     
+#endif
+
+#if ! defined(MEM_ADDR_DIFF)
+#define MEM_ADDR_DIFF(A, B) ((A).addr - (B).addr)
+#endif
+
+#if ! defined(MEM_ADDR_ASI)
+#define MEM_ADDR_ASI(A) -1
+#endif
+
+#endif  /* HAVE_BSP */
+
+#if defined(NO_MALLOC) && ! defined(MAX_NUM_BP)
+#define MAX_NUM_BP 64
+#endif
+
+extern struct regstruct regtab[];
+
+extern char **argvect;
+
+#ifdef HAVE_BSP
+#define VERSION "release 2.0"
+#else
+#define VERSION "release 1.2"
+#endif
+
+#define MAXLINELEN 80
+#define PROMPT "cygmon> "
+#if ! defined MAX_HIST_ENTS
+#define MAX_HIST_ENTS 10
+#endif
+
+/*
+ * From monitor.c
+ */
+extern mem_addr_t last_pc;
+extern int        stub_is_active;
+#ifdef HAVE_BSP
+extern void *mon_saved_regs;
+#else
+extern int (*user_signal_handler)(int);
+#endif
+
+extern void clear_user_state (void);
+extern int  transfer_to_stub (void);
+extern void version (void);
+#ifdef MONITOR_CONTROL_INTERRUPTS
+/* Enable interrupts within the monitor. */
+extern void monitor_enable_interrupts (void);
+
+/* Disable interrupts within the monitor. */
+extern void monitor_disable_interrupts (void);
+
+/* Returns 1 if interrupts have been enabled within the monitor, 0
+   otherwise. */
+extern int monitor_interrupt_state (void);
+#endif /* MONITOR_CONTROL_INTERRUPTS */
+
+
+/*
+ * From utils.c
+ */
+extern int switch_to_stub_flag;
+extern int input_char (void);
+extern target_register_t str2int (char *str, int base);
+#if HAVE_DOUBLE_REGS
+extern double str2double (char *str, int base);
+#endif
+extern target_register_t str2intlen (char *str, int base, int len);
+extern int hex2bytes(char *string, char *dest, int maxsize);
+extern char *int2str (target_register_t number, int base, int numdigs);
+#ifndef NO_MALLOC
+extern char *strdup(const char *str);
+#endif
+extern target_register_t get_pc(void);
+extern char *get_register_str (regnames_t which, int detail, int valid);
+extern void store_register (regnames_t which, char *string);
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+/*
+ * From breakpoints.c
+ */
+extern int add_mon_breakpoint (mem_addr_t location);
+extern void install_breakpoints (void);
+extern void clear_breakpoints (void);
+extern int  show_breakpoints (void);
+extern int clear_mon_breakpoint (mem_addr_t location);
+#endif /* USE_ECOS_HAL_BREAKPOINTS */
+
+
+/*
+ * From do-dis.c
+ */
+extern mem_addr_t do_dis (mem_addr_t *addr);
+extern void flush_dis (void);
+
+
+/*
+ * From architecture-mon.c
+ */
+#ifdef HAVE_BSP
+extern void initialize_mon(void);
+extern target_register_t get_register(regnames_t reg);
+extern void put_register (regnames_t which, target_register_t value);
+#endif
+
+
+/* Lame. */
+#ifndef ITIMER_REAL
+#define ITIMER_REAL 0
+#endif
+
+#endif /* ASM */
+#endif
diff --git a/packages/cygmon/v2_0/misc/monitor_cmd.c b/packages/cygmon/v2_0/misc/monitor_cmd.c
new file mode 100644 (file)
index 0000000..0a46fb8
--- /dev/null
@@ -0,0 +1,2549 @@
+//==========================================================================
+//
+//      monitor_cmd.c
+//
+//      Monitor commands for the CygMON ROM monitor
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      Monitor commands for the CygMON ROM monitor
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#ifdef HAVE_BSP
+#include "cpu_info.h"
+#include <bsp/bsp.h>
+#include <bsp/cpu.h>
+#include <bsp/hex-utils.h>
+#ifdef __BOARD_HEADER__
+#include __BOARD_HEADER__
+#endif
+#endif
+#include <board.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <monitor.h>
+#include <ledit.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef HAVE_BSP
+#include "fmt_util.h"
+#include "tservice.h"
+#endif
+
+#ifdef __ECOS__
+#include <cyg/hal/hal_stub.h>
+#endif
+
+#if USE_CYGMON_PROTOTYPES
+/* Use common prototypes */
+/* Some of the composed board.h files compose these
+   prototypes redundently, but if they dont,
+   these are the common definitions */
+#include "fmt_util.h"   /* Interface to string formatting utilities */
+#include "tservice.h"   /* Interface to target specific services */
+#include "generic-stub.h" /* from libstub */
+#endif /* USE_CYGMON_PROTOTYPES */
+
+static int history_cmd(cmdmode_t mode) ;
+
+#ifndef MAXLINELEN
+#define MAXLINELEN 80
+#endif
+
+#define MAXLINES 23
+
+char inbuf[MAXLINELEN] ;
+static char cmd[MAXLINELEN];
+
+#if ! defined(PROVIDE_CRASH_CMD)
+#define PROVIDE_CRASH_CMD 0
+#endif
+
+#if PROVIDE_CRASH_CMD
+/*
+ * The crash command is used while debugging cygmon itself
+ */
+static int crash_cmd(cmdmode_t mode) ; /* Command to trap into cygmon */
+#endif
+
+struct cmdentry cmdtab[] = {
+  {NULL, "baud",        set_serial_speed_cmd},
+  {"b",  "break",       breakpoint_cmd},
+#if HAVE_CACHE
+  {NULL, "cache",       cache_cmd},
+#endif
+  {NULL, "copy",        copy_cmd},
+#if PROVIDE_CRASH_CMD
+  {NULL, "crash",       crash_cmd},
+#endif
+  {NULL, "crc",         checksumcmd},
+  {"d",  "disassemble", disassemble_cmd},
+  {NULL, "dump",        dump_cmd},
+#if defined(NVRAM_ETH_ADDR)
+  {NULL, "ethaddr",     ethaddr_cmd},
+#endif
+  {NULL, "fill",        fill_cmd},
+  {NULL, "go",          go_cmd},
+  {NULL, "help",        help_cmd},
+  {"his","history",     history_cmd},
+#ifdef MONITOR_CONTROL_INTERRUPTS
+  {NULL, "interrupt",   int_cmd},
+#endif
+#if defined(NVRAM_IP_ADDR)
+  {NULL, "ipaddr",      ipaddr_cmd},
+#endif
+  {NULL, "load",        load_cmd},
+  {"m",  "memory",      mem_cmd},
+#ifdef OTHERNAMES_CMD
+  {"o",  "othernames",  othernames_cmd},
+#endif
+  {NULL, "port",        set_serial_port_cmd},
+  {"r",  "register",    reg_cmd},
+  {NULL, "reset",       reset_cmd},
+#ifndef HAVE_BSP
+  {NULL, "setargs",     set_program_args_cmd},
+#endif
+  {"si", "step",        step_cmd},
+  {NULL, "swapmem",     swapmem_cmd},
+#if defined(NVRAM_TCP_PORT)
+  {NULL, "tcpport",     tcpport_cmd},
+#endif
+  {NULL, "terminal",    set_term_cmd},
+#ifdef HAS_TIMER
+  {NULL, "timer",       timer_cmd},
+#endif
+#if !defined(__ECOS__) || defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+  {NULL, "transfer",    transfer_cmd},
+#endif
+  {"u",  "unbreak",     clear_breakpoint_cmd},
+#if HAVE_USAGE
+  {NULL, "usage",       memusage_cmd},
+#endif
+  {NULL, "version",     version_cmd},
+  /* Really need to redo the way commands are done--there should be a
+     dynamic list (perhaps in addition to the static one). */
+#ifdef TARGET_COMMANDS
+  TARGET_COMMANDS
+#endif
+
+  {NULL, NULL, NULL}
+};
+
+static int 
+alias_compare (char *cmd)
+{
+  int m = 0;
+  int match = -1;
+  int num_matches = 0;
+
+  while (cmdtab[m].cmd != NULL)
+    {
+      if (cmdtab[m].alias != NULL && !strcmp (cmd, cmdtab[m].alias))
+       {
+         match = m;
+         num_matches++;
+         /* We're expecting that aliases will be defined 
+            uniquely, but just in case, we let the user know 
+            if there is a conflict */
+         if (num_matches > 1)
+           {
+             xprintf ("Alias conflict. Executing last matching alias.\n");
+           }
+       }
+      m++;
+    }
+  return match;
+}
+
+static int
+command_compare (char *cmd)
+{
+  int m = 0;
+  int match = -1;
+  int num_matches = 0;
+  int cmdlen = strlen(cmd) ;
+  while (cmdtab[m].cmd != NULL)
+    {
+      if (!(strncmp (cmd,cmdtab[m].cmd, cmdlen)))
+       {
+         /* we found a match */
+         num_matches++;
+         if (num_matches == 2)  /* we found a second match */
+           {
+             xprintf ("Ambiguous command.  Possibilities are:\n%s\n%s\n",
+                      cmdtab[match].cmd,
+                      cmdtab[m].cmd);
+           }
+         else if (num_matches > 2)  /* we found another match */
+           {
+             /* Show the new possibility we just found */
+             xprintf ("%s\n", cmdtab[m].cmd);
+           }
+          /* Point the match at the command we just looked at.
+            We have to wait until now so that the first duplicate
+            found can output the earlier match as well */
+         match = m;
+       }
+      m++;
+    }
+  return ((num_matches == 1) ? match : -1);
+}
+
+#ifdef USE_HELP
+void
+usage (char *string)
+{
+  xprintf ("Usage: %s\n", string);
+}
+
+void
+short_help (char *string)
+{
+  xprintf ("%s\n", string);
+}
+
+void
+long_help (char *string)
+{
+  int linecnt = 0;
+  int do_leave = 0;
+
+  for (; *string && !do_leave; string++)
+    {
+      xprintf ("%c", *string);
+      if (*string == '\n')
+       {
+         linecnt++;
+         if (linecnt == MAXLINES)
+           {
+             int i;
+
+             xprintf ("-More-");
+             while ((i = input_char ()) >= 0)
+               {
+                 if (i == '\r' || i == '\n')
+                   {
+                     linecnt--;
+                     break;
+                   }
+                 else if (i == ' ')
+                   {
+                     linecnt = 0;
+                     break;
+                   }
+                 else if (i == 'q' || i == 'Q')
+                   {
+                     do_leave = 1;
+                     break;
+                   }
+                 else
+                   beep ();
+               }
+           }
+       }
+    }
+  xprintf ("\n");
+}
+
+void
+example (char *example)
+{
+  xprintf ("Example: %s\n", example);
+}
+
+#else
+void
+no_help (void)
+{
+  xprintf ("No help available.\n");
+}
+
+void
+no_help_usage (void)
+{
+  xprintf ("Incorrect usage.\n");
+}
+#endif
+
+int 
+help_cmd (cmdmode_t mode) 
+{
+  int command_number = -2;
+
+  if (mode == USAGE)
+    {
+      usage ("help [command]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("The help command");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      help_cmd (USAGE);
+      long_help ("\
+The help command without arguments shows a list of all available commands\n\
+with a short description of each one.  With a command name as an argument\n\
+it shows usage for the command and a paragraph describing the command.\n\
+Usage is shown as command name followed by names of extensions or arguments.\n\
+Arguments in [brackets] are optional, plain text arguments are required.\n\
+Note that all commands can be invoked by typing enough of the command name\n\
+to uniquely specify the command.  Some commands have aliases, which are one\n\
+letter abbreviations for commands which do not have unique first letters.\n\
+Aliases for all commands are shown in the help screen, which displays\n\
+commands in the format:\n\
+command name: (alias, if any)  description of command \n");
+      example("\
+help foo \n\
+Shows the help screen for the command foo.");
+      return 0;
+    }
+
+  if (argvect[1] != NULL)
+    {
+      if (argvect[2] == NULL)
+       {
+         command_number = command_compare (argvect[1]);
+         if (command_number < 0)
+           {
+             xprintf ("No such command as %s\n", argvect[1]);
+           }
+       }
+      
+      if (command_number < 0)
+       {
+         return help_cmd (USAGE);
+       }
+      else
+       {
+         return cmdtab[command_number].function (LONG_HELP);
+       }
+    }
+  else
+    {
+      int i;
+      
+      xprintf ("Available commands are:\n");
+      for (i = 0; cmdtab[i].cmd != NULL; i++)
+       {
+         int x = strlen (cmdtab[i].cmd) + 2;
+
+         xprintf ("%s: ", cmdtab[i].cmd);
+         if (cmdtab[i].alias != NULL)
+           {
+             xprintf("(%s)", cmdtab[i].alias);
+             x += 2 + strlen(cmdtab[i].alias);
+           }
+         for (; x < 20; x++)
+           {
+             xprintf (" ");
+           }
+         cmdtab[i].function (SHORT_HELP);
+         if ((i > 0) && (i % MAXLINES) == 0)
+           {
+             xprintf ("-More-");
+             input_char ();
+             xprintf ("\n");
+           }
+       }
+    }
+  return 0;
+}
+
+#if PROVIDE_CRASH_CMD
+static int crash_cmd(cmdmode_t mode)
+{
+  switch (mode)
+    {
+    case USAGE : usage("crash")  ; break ;
+    case SHORT_HELP : short_help("invoke the breakpoint function");
+      break ;
+    case LONG_HELP :
+      long_help("The crash command calls the breakpoint function() which is useful\n\
+only if you are using an additional debugger to debug this software and,\n\
+the general exception handler is hooked to the other debugger\n") ;
+      break ;
+    case INVOCATION :
+      dbg_breakpoint() ;
+      break ;
+    }
+  return 0 ;
+}
+#endif /* provide_crash_command */
+
+
+
+static int history_cmd(cmdmode_t mode)
+{
+    switch (mode)
+    {
+    case USAGE : usage("history")  ; break ;
+    case SHORT_HELP : short_help("Print help about line editing features.");
+      break ;
+    case INVOCATION :
+      printHistoryList();
+      break;
+    case LONG_HELP :
+      long_help("Cygmon line editing allows you to repeat previously entered 
+commands. The line editing commands are:
+        CR '\\n'  Execute the currently displayed command
+        ctl-a    move to Beginning of line
+        ctl-e    End of line
+        ctl-f    Forward char
+        ctl-b    Backward char
+        ctl-k    Delete to end of line
+        ctl-y    yank Character (undelete)
+        ctl-d    Delete current character
+        ctl-p    edit previous command
+        ctl-u    Erase Line
+        ctl-n    Edit next command") ;
+      break ;
+    }
+  return 0 ;
+} /* history_cmd */
+
+#ifdef OTHERNAMES_CMD
+/* Switch to using the othernames (ie alternate register names) */
+int
+othernames_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("othernames");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Switch between alternate register names.");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      othernames_cmd (USAGE);
+      long_help ("\
+The othernames command allows you to switch between alternate register
+names for a given target.");
+      example ("\
+othernames\n\
+Switches to the alternate register name set..");
+      return 0;
+    }
+  OTHERNAMES_CMD();
+
+  return 0;
+}
+#endif /* OTHERNAMES_CMD */
+
+
+#if defined(NVRAM_ETH_ADDR)
+int
+ethaddr_cmd (cmdmode_t mode)
+{
+  int      i, n;
+  unsigned char addr[6];
+  char     *p;
+
+  if (mode == USAGE)
+    {
+      usage ("ethaddr [xx:xx:xx:xx:xx:xx]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("get/set NVRAM backed ethernet address");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      ethaddr_cmd (USAGE);
+      long_help ("\
+The ethaddr command is used to view and modify the non-volatile ethernet\n\
+address. The address is specified by 6 colon-seperated 2 digit hexadecimal\n\
+numbers. If no address is specified, the current address is displayed.\n");
+      example ("ethaddr 00:00:8B:F1:36:01");
+      return 0;
+    }
+
+  if (argvect[1] != NULL)
+    {
+      if (strlen(argvect[1]) != 17 || argvect[2] != NULL)
+       {
+         return ethaddr_cmd (USAGE);
+       }
+
+      for (i = 0, p = argvect[1]; i < 6; i++, p++)
+       {
+         n = __hex(*p++);
+         if (n < 0)
+           return ethaddr_cmd (USAGE);
+         addr[i] = (n << 4);
+         n = __hex(*p++);
+         if (n < 0)
+           return ethaddr_cmd (USAGE);
+         addr[i] |= n;
+
+         if (*p != ':' && !(i == 5 && *p == '\0'))
+           return ethaddr_cmd (USAGE);
+       }
+      for (i = 0; i < 6; i++)
+       NVRAM_ETH_ADDR(i) = addr[i];
+    }
+  else
+    {
+      for (i = 0; i < 5; i++)
+       xprintf("%02x:", NVRAM_ETH_ADDR(i));
+      xprintf("%02x\n", NVRAM_ETH_ADDR(i));
+    }
+
+  return 0;
+}
+#endif /* NVRAM_ETH_ADDR */
+
+
+#if defined(NVRAM_IP_ADDR)
+int
+ipaddr_cmd (cmdmode_t mode)
+{
+  int      i, j, n;
+  unsigned char addr[4];
+  char     *p;
+
+  if (mode == USAGE)
+    {
+      usage ("ipaddr [n.n.n.n]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("get/set NVRAM backed ip address");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      ipaddr_cmd (USAGE);
+      long_help ("\
+The ipaddr command is used to view and modify the non-volatile internet\n\
+address. The address is specified by 4 dot-seperated 1-3 digit decimal\n\
+numbers. If no address is specified, the current address is displayed.\n");
+      example ("ipaddr 192.161.0.1");
+      return 0;
+    }
+
+  if (argvect[1] != NULL)
+    {
+      if (argvect[2] != NULL)
+       return ipaddr_cmd (USAGE);
+
+      p = argvect[1];
+
+      for (i = 0; i < 3; i++, p++)
+       {
+         for (j = n = 0; j < 3 && isdigit(*p); j++, p++)
+           n = n*10 + (*p - '0');
+         if (j == 0 || *p != '.' || n > 255)
+           return ipaddr_cmd (USAGE);
+         addr[i] = n;
+       }
+      for (j = n = 0; j < 3 && isdigit(*p); j++, p++)
+       n = n*10 + (*p - '0');
+      if (j == 0 || *p != '\0' || n > 255)
+       return ipaddr_cmd (USAGE);
+      addr[i] = n;
+
+      for (i = 0; i < 4; i++)
+       NVRAM_IP_ADDR(i) = addr[i];
+    }
+  else
+    {
+      for (i = 0; i < 3; i++)
+       xprintf("%d.", NVRAM_IP_ADDR(i));
+      xprintf("%d\n", NVRAM_IP_ADDR(i));
+    }
+
+  return 0;
+}
+#endif /* NVRAM_IP_ADDR */
+
+#if defined(NVRAM_TCP_PORT)
+int
+tcpport_cmd (cmdmode_t mode)
+{
+  int  n;
+  char *p;
+
+  if (mode == USAGE)
+    {
+      usage ("ethaddr [xx:xx:xx:xx:xx:xx]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("get/set NVRAM backed tcp port number");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      tcpport_cmd (USAGE);
+      long_help ("\
+The tcpport command is used to view and modify the non-volatile tcp port\n\
+address used for debugging. The address is specified by decimal numer in\n\
+the range of 1-65535. If no port number is specified, the current port is\n\
+displayed.\n");
+      example ("tcpport 1000");
+      return 0;
+    }
+
+  if (argvect[1] != NULL)
+    {
+      if (argvect[2] != NULL)
+       return tcpport_cmd (USAGE);
+
+      p = argvect[1];
+      n = 0;
+      while (isdigit(*p))
+       {
+         n = n*10 + (*p++ - '0');
+         if (n > 65535)
+           return tcpport_cmd (USAGE);
+       }
+      if (*p != '\0')
+       return tcpport_cmd (USAGE);
+
+      NVRAM_TCP_PORT(0) = (n >> 8) & 0xff;
+      NVRAM_TCP_PORT(1) = n & 0xff;
+    }
+  else
+    xprintf("%d\n", (NVRAM_TCP_PORT(0) << 8) + NVRAM_TCP_PORT(1));
+
+  return 0;
+}
+#endif /* NVRAM_TCP_PORT */
+
+
+#ifdef __ECOS__
+#  if (CYG_BYTEORDER == CYG_LSBFIRST)
+#    define LITTLE_ENDIAN_TARGET
+#  else
+#    define BIG_ENDIAN_TARGET
+#  endif
+#endif
+
+#ifdef LITTLE_ENDIAN_TARGET
+static int swap_bytes = 1;
+#else
+static int swap_bytes = 0;
+#endif
+
+int
+get_memory_display_mode (void)
+{
+  return swap_bytes;
+}
+
+void
+set_memory_display_mode (int mode)
+{
+  swap_bytes = mode;
+}
+
+
+/* Just to make DEFAULT_SIZE something usable, this may go elsewhere later.*/
+#ifndef DEFAULT_SIZE
+#define DEFAULT_SIZE 1
+#endif
+
+static int
+get_cmd_size (void)
+{
+  int size = 0;
+  char *sizestr;
+
+  sizestr = strchr (argvect[0], '.');
+
+  if (sizestr == NULL || sizestr[0] == '\0' || sizestr[1] == '\0')
+    {
+      size = DEFAULT_SIZE;
+    }
+  else
+    {
+      size = str2int (sizestr + 1, 10) / 8;
+    }
+  if (size != 1 && size != 2 && size != 4 && size != 8)
+    {
+      xprintf ("Invalid size.\n");
+      return -1;
+    }
+  return size;
+}
+
+
+void
+display_memory (char *value, int size, int littleEndian)
+{
+  int x;
+  int start = littleEndian ? size - 1 : 0 ;
+  int end = littleEndian ? -1 : size;
+  int incr = littleEndian ? -1 : 1;
+
+  if (value)
+    {
+      for (x = start; x != end; x += incr)
+        xprintf ("%02x", value[x] & 0xff);
+    }
+  else
+    {
+      for (x = start; x != end; x += incr)
+        xprintf ("..");
+    }
+}
+
+
+static int
+peek (void)
+{
+  mem_addr_t addr;
+  int size = get_cmd_size ();
+
+  if (size > 0)
+    {
+      /* We already checked to see if the command was legal when we called the
+        function, so there's no need to worry about that here. */
+
+      if (argvect[1] != 0)
+       {
+         char value[8];
+
+         str2addr (argvect[1], &addr);
+         if (read_memory (&addr, size, 1, value))
+           {
+             xprintf ("Memory read failed\n");
+           }
+         else
+           {
+             display_memory (value, size, get_memory_display_mode ());
+             xprintf ("\n");
+           }
+       }
+      else
+       {
+         xprintf ("Not enough arguments\n");
+         return mem_cmd (USAGE);
+       }
+    }
+  return 0;
+}
+
+/* Poke a single byte in memory. */
+
+static int 
+poke (void)
+{
+  int size = 0;
+
+  size = get_cmd_size ();
+  if (size > 0)
+    {
+      /* We already checked to see if the command was legal when we called the
+        function, so there's no need to worry about that here. */
+
+      if ((argvect[1] != 0) && (argvect[2] != 0))
+       {
+         char value[8];
+         mem_addr_t addr;
+
+         str2addr (argvect[1], &addr);
+         hex2bytes (argvect[2], value, size);
+
+         if (get_memory_display_mode ())
+           {
+             /* Gotta swap this puppy. */
+             int x;
+
+             for (x = 0; x < (size / 2); x++)
+               {
+                 char tmp = value[x];
+                 value [x] = value [size - 1 - x];
+                 value [size - 1 - x] = tmp;
+               }
+           }
+         if (write_memory (&addr, size, 1, value))
+           {
+             xprintf ("Memory write failed\n");
+           }
+#ifdef HAVE_BSP
+         bsp_flush_dcache((void *)addr.addr, size);
+         bsp_flush_icache((void *)addr.addr, size);
+#endif
+       }
+      else
+       {
+         xprintf ("Not enough arguments\n");
+         return mem_cmd (USAGE);
+       }
+    }
+  return 0;
+}
+
+
+/* I am cheap and easy. */
+int
+mem_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("memory[.size] address [value]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("read/write memory");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      mem_cmd (USAGE);
+      long_help ("\
+The memory command is used to view and modify single locations in memory.\n\
+It can take a size extension, which follows the command name or partial\n\
+command name without a space, and is a period followed by the number of\n\
+bits to be viewed or modified.  Options are 8, 16, 32, and 64.  Without\n\
+a size extension, the memory command defaults to displaying or changing 8\n\
+bits at a time.\n\
+The memory command can take one or two arguments, independent of\n\
+whether a size extension is specified.  With one argument, it displays the\n\
+contents of the specified location.  With two arguments, it replaces the\n\
+contents of the specified location with the specified value.\n");
+      example ("\
+memory.8 45f6b2 57\n\
+Places the 8 bit value 57 at the location 45f6b2.");
+      return 0;
+    }
+
+  if (argvect[1] == NULL || (argvect[2] != NULL && argvect[3] != NULL))
+    {
+      return mem_cmd (USAGE);
+    }
+  if (argvect[1] != NULL && argvect[2] != NULL)
+    return poke ();
+  else
+    return peek ();
+}
+
+/* Memory dump function. */
+
+int 
+dump_cmd (cmdmode_t mode)
+{
+  mem_addr_t addr;
+  char value[8];
+
+  if (mode == USAGE)
+    {
+      usage ("dump[.size] location [count]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Memory dump command");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      dump_cmd (USAGE);
+      long_help ("\
+The dump command displays a region of memory. If no count value is\n\
+supplied, the command displays 16 bytes.  It can take a size\n\
+extension, which follows the command name or partial command name\n\
+without a space, and is a period followed by the number of bits to be\n\
+viewed or modified.  Options are 8, 16, 32, and 64.  Without a size\n\
+extension, the dump command defaults to displaying 8 bits at a time.\n\
+Addresses are aligned to a 16-byte boundary.  Thus, dump 65 would show\n\
+all bytes from 60 through 6f.\n");
+      example ("\
+dump 44f5\n\
+Displays 16 bytes starting with 44f0 and ending with 44ff.");
+      return 0;
+    }
+
+  if (argvect[1] != 0 && (argvect[2] == NULL || argvect[3] == NULL))
+    {
+      mem_addr_t start_addr;
+      char chardumps[32];
+      int offset;
+      int count;
+      int line;
+      int size = get_cmd_size ();
+      int i;
+
+      if (size == -1)
+          /*
+           * Invalid size specified.
+           */
+          return 0;
+
+      str2addr (argvect[1], &addr);
+      if (argvect[2] != NULL)
+       {
+         count = str2int (argvect[2], 10);
+         count = (count + 15) / 16;
+       }
+      else
+       {
+         count = 1;
+       }
+      ADD_ALIGN(&addr, &start_addr, 16);
+      for (line = 0; line < count; line ++)
+       {
+         for (offset = 0; offset < 16; offset += size)
+           {
+             ADD_OFFSET(&start_addr, &addr, offset + line * 16);
+
+             if (offset == 0)
+               {
+                 char buf[32];
+             
+                 addr2str (&addr, buf);
+                  xprintf("%s: ", buf);
+               }
+              if (read_memory (&addr, size, 1, value))
+                {
+                  display_memory (0, size, get_memory_display_mode ());
+                  for (i = 0; i < size; i++)
+                    {
+                      value[i] = 0;
+                    }
+                } else {
+                  display_memory (value, size, get_memory_display_mode ());
+                }
+              xprintf (" ");
+              for (i = 0; i < size; i++)
+                {
+                  chardumps[offset + i] = value[i] & 0x7f;
+                  if (chardumps[offset + i] < 32)
+                    chardumps[offset + i] = '.';
+                }
+           }
+         xprintf (" ");
+         for(i = 0; i < offset; i++)
+           {
+             xprintf ("%c", chardumps[i]);
+           }
+          xprintf ("\n");
+       }
+    }
+  else
+    {
+      dump_cmd (USAGE);
+    }
+  return 0;
+}
+
+static int scnt;
+static int (*srec_input_char) (void);
+
+static inline int
+gethexnibble(void)
+{
+  int ch;
+
+  inbuf[scnt++] = ch = srec_input_char();
+  if (ch >= '0' && ch <= '9')
+    return (ch - '0');
+  if (ch >= 'a' && ch <= 'f')
+    return (ch - 'a' + 10);
+  if (ch >= 'A' && ch <= 'F')
+    return (ch - 'A' + 10);
+
+  inbuf[scnt] = '\0';
+  xprintf("Bad hex char: %s\n", inbuf);
+  return -1;
+}
+
+
+static inline int
+gethexbyte(void)
+{
+  int nib;
+  unsigned char n;
+
+  if ((nib = gethexnibble()) < 0)
+    return -1;
+  n = nib << 4;
+  if ((nib = gethexnibble()) < 0)
+    return -1;
+  n |= nib;
+  return n;
+}
+
+static inline int
+chk_cksum(unsigned int cksum, int rval)
+{
+  int n;
+
+  if ((n = gethexbyte()) < 0)
+    return -1;
+
+  cksum = ~cksum & 0xff;
+
+  if (cksum != n)
+    {
+      inbuf[scnt] = '\0';
+      xprintf("Bad cksum[%02x]: %s\n", cksum, inbuf);
+      return -1;
+    }
+  return rval;
+}
+
+int
+load_srec(srec_input_func_t inp_func)
+{
+  int count, dcount, data, n, addr_bytes = 0, is_term, is_comment;
+  unsigned int address, cksum;
+  unsigned char data_buf[256];
+  mem_addr_t memaddr;
+
+  srec_input_char = inp_func;
+
+  is_comment = is_term = 0;
+
+  while (srec_input_char() != 'S')
+    ;
+
+  scnt = 0;
+  inbuf[scnt++] = 'S';
+
+  if ((n = gethexnibble()) < 0)
+    return -1;
+
+  switch (n)
+    {
+      case 0:
+      case 5:
+       is_comment = 1;
+       break;
+
+      case 1:
+      case 2:
+      case 3:
+       addr_bytes = n + 1;
+       break;
+
+      case 7:
+      case 8:
+      case 9:
+       is_term = 1;
+       addr_bytes = 11 - n;
+       break;
+
+      default:
+       inbuf[scnt] = '\0';
+       xprintf("Bad record type: %s\n", inbuf);
+       return -1;
+    }
+
+  if ((count = gethexbyte()) < 0)
+    return -1;
+  cksum = count;
+
+  --count; /* don't count chksum */
+
+  if (is_comment)
+    {
+      while (count > 0)
+       {
+         if ((n = gethexbyte()) < 0)
+           return -1;
+         cksum += n;
+         --count;
+       }
+      return chk_cksum(cksum, 0);
+    }
+
+  address = 0;
+  while (count > 0 && addr_bytes)
+    {
+      if ((n = gethexbyte()) < 0)
+       return -1;
+      cksum += n;
+      address = (address << 8) | n;
+      --addr_bytes;
+      --count;
+    }
+
+  if (is_term)
+    {
+      if (count || addr_bytes)
+       {
+         inbuf[scnt] = '\0';
+         xprintf("Malformed record cnt[%d] abytes[%d]: %s\n",
+                count, addr_bytes, inbuf);
+         return -1;
+       }
+      if (chk_cksum(cksum, 1) == 1)
+       {
+         set_pc (address);
+         xprintf("Setting start address: 0x%08x\n", address);
+         return 1;
+       }
+      return -1;
+    }
+
+  dcount = 0;
+
+  while (count > 0)
+    {
+      if ((data = gethexbyte()) < 0)
+       return -1;
+      cksum += data;
+      data_buf[dcount++] = data;
+      --count;
+    }
+    
+  if (chk_cksum(cksum, 0))
+    return -1;
+
+  MAKE_STD_ADDR (address, &memaddr);
+  write_memory (&memaddr, 1, dcount, data_buf);
+#ifdef HAVE_BSP
+  bsp_flush_dcache((void *)memaddr.addr, dcount);
+  bsp_flush_icache((void *)memaddr.addr, dcount);
+#endif
+
+  return 0;
+}
+
+
+int 
+load_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("load");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Load srecords into memory");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      load_cmd (USAGE);
+      long_help ("\
+The load command switches the monitor into a state where it takes all input 
+as s-records and stores them in memory.  The monitor exits this mode when a
+termination record is hit, or certain errors (such as an invalid s-record)
+cause the load to fail.");
+      return 0;
+    }
+  
+  if (argvect[1] != NULL)
+    {
+      return load_cmd (USAGE);
+    }
+
+  while (!load_srec(xgetchar))
+      ;
+
+  return 0;
+}
+
+#ifndef REGNAME_EXAMPLE
+# define REGNAME_EXAMPLE "a0"
+#endif
+
+#if !defined(__ECOS__) || defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
+int
+transfer_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("$");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Transfer to gdb stub");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      transfer_cmd (USAGE);
+      long_help ("\
+The transfer or $ command transfers control to the gdb stub.  This function\n\
+does not actually need to be called by the user, as connecting to the board\n\
+with gdb will call it automatically.  The transfer command takes no\n\
+arguments.  The $ command does not wait for a return, but executes\n\
+immediately.  A telnet setup in line mode will require a return when $ is\n\
+executed by the user, as the host computer does not pass any characters to\n\
+the monitor until a return is pressed.  Disconnecting from the board in gdb\n\
+automatically returns control to the monitor.");
+      return 0;
+    }
+  if (argvect[1] == NULL)
+    {
+      return transfer_to_stub ();
+    }
+  else
+    {
+      transfer_cmd (USAGE);
+    }
+  return 0;
+}
+#endif
+
+static void
+display_group (int which_group)
+{
+  int len = 0;
+  int skipping_group = 0;
+  char buf[80];
+  int start_entry = 0;
+  int i;
+
+  if (which_group >= 0)
+    {
+      start_entry = which_group;
+    }
+
+  for (i = start_entry; regtab[i].registername != NULL; i++)
+    {
+      int buflen;
+
+      if (regtab[i].registernumber < 0)
+       {
+         if (which_group >= 0 && i != which_group)
+           {
+             break;
+           }
+
+         if (len > 0)
+           {
+             xprintf ("\n");
+             len = 0;
+           }
+         if (which_group < 0)
+           {
+             if (regtab[i].registernumber == -2)
+               {
+                 skipping_group = 1;
+                 xprintf ("[skipping %s]\n", regtab[i].registername);
+               }
+             else
+               {
+                 skipping_group = 0;
+                 xprintf ("[%s]\n", regtab[i].registername);
+#if 0
+                 len = strlen (regtab[i].registername) + 2;
+                 while (len < MAXLINES)
+                   {
+                     xputchar (' ');
+                     len++;
+                   }
+#endif
+               }
+           }
+       }
+      else 
+       if (!skipping_group)
+         {
+#ifdef REG_VALID_FIELD_IN_REGSTRUCT
+#define REGVALID_VAL regtab[i].registervalid
+#else
+#define REGVALID_VAL 1
+#endif
+           xsprintf(buf, "%4s: %s",
+                    regtab[i].registername,
+                    get_register_str (regtab[i].registernumber, 0 , REGVALID_VAL));
+#undef REGVALID_VAL
+           buflen = strlen (buf);
+           if ((buflen + len + 3) >= 80)
+             {
+               xprintf ("\n");
+               len = 0;
+             }
+           else if(len > 0)
+             {
+               xprintf ("   ");
+               len += 3;
+             }
+
+           xprintf (buf);
+           len += buflen;
+         }
+    }
+  if (len > 0)
+    {
+      xprintf ("\n");
+    }
+}
+
+static int
+getregister (void)
+{
+  int i;
+  
+  if (argvect[1] == 0)
+    {
+      display_group (-1);
+    }
+  else
+    {
+      for (i = 0; regtab[i].registername != NULL; i++)
+       {
+         if (!(strcmp (argvect[1], regtab[i].registername)))
+           {
+             break;
+           }
+       }
+      if (regtab[i].registername == NULL)
+       {
+         xprintf ("No such register\n");
+       }
+      else
+       {
+         if (regtab[i].registernumber < 0)
+           {
+             display_group (i);
+           }
+         else
+           {
+#ifdef REG_VALID_FIELD_IN_REGSTRUCT
+#define REGVALID_VAL regtab[i].registervalid
+#else
+#define REGVALID_VAL 1
+#endif
+             xprintf("%s: %s\n", argvect[1], 
+                     get_register_str (regtab[i].registernumber, 1, REGVALID_VAL));
+#undef REGVALID_VAL
+           }
+       }
+    }
+  return 0;
+}
+
+static int 
+setregister (void)
+{
+  int number = -1;
+  int i;
+  if ((argvect[1] != 0) && (argvect[2] != 0))
+    {
+      i = 0;
+      while (regtab[i].registername != NULL)
+       {
+         if (!(strcmp (argvect[1], regtab[i].registername)))
+           {
+             number = regtab[i].registernumber;
+             break;
+           }
+         i++;
+       }
+      if (number < 0)
+       xprintf ("Unknown register name %s\n", argvect[1]);
+      else
+       store_register (number, argvect[2]);
+    }
+  else
+    {
+      xprintf ("Not enough arguments\n");
+    }
+  return 0;
+}
+
+
+int
+reg_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("register [register name] [value]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("View and manipulate registers");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      reg_cmd (USAGE);
+      long_help ("\
+The register command allows the viewing and manipulation of register\n\
+contents.  It can take zero, one, or two arguments.  When called with zero\n\
+arguments, the register command displays the values of all registers.  When\n\
+called with only the register name argument, it displays the contents of\n\
+the specified register.  When called with both a register name and a value,\n\
+it places that value into the specified register.\n");
+      example ("\
+register " REGNAME_EXAMPLE " 1f\n\
+Places the value 1f in the register " REGNAME_EXAMPLE);
+      return 0;
+    }
+
+  if (argvect[1] != NULL && argvect[2] != NULL)
+    {
+      if (argvect[3] != NULL)
+       {
+         return reg_cmd (USAGE);
+       }
+      return setregister ();
+    }
+  else
+    return getregister ();
+}
+
+
+/* execute the program in memory */
+int 
+go_cmd (cmdmode_t mode)
+{
+#ifdef HAS_TIMER
+  extern tick_type start_tickcount;
+#endif
+
+  if (mode == USAGE)
+    {
+      usage ("go [location]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Start user program execution");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      go_cmd (USAGE);
+      long_help ("\
+The go command starts user program execution.  It can take zero or one\n\
+argument.  If no argument is provided, go starts execution at the current\n\
+pc.  If an argument is specified, go sets the pc to that location, and then\n\
+starts execution at that location.\n");
+      example ("
+go 40020000\n\
+Sets the pc to 40020000, and starts program execution.");
+      return 0;
+    }
+
+  if (argvect[1] != NULL && argvect[2] != NULL)
+    {
+      return go_cmd (USAGE);
+    }
+  if (argvect[1] != NULL)
+    {
+      set_pc (str2int (argvect[1], 16));
+    }
+
+#ifdef HAS_TIMER
+  start_tickcount = __read_ticks ();
+#endif
+  /* We want monitor_loop to exit now. */
+  return 1;
+}
+
+#ifdef HAS_TIMER
+int
+timer_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("timer [state]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Enable and disable timer");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      timer_cmd (USAGE);
+      long_help ("\
+The timer command allows control of the on board timer.  It takes zero\n\
+or one argument.  With zero arguments, it displays the state of the timer,\n\
+with one argument, which can start with  e or d, it enables or disables the\n\
+timer, respectively.\n");
+      example ("\
+timer e\n\
+Enables the timer.");
+      return 0;
+    }
+
+  if (argvect[1] != NULL)
+    {
+      if (argvect[2] != NULL)
+       {
+         return timer_cmd (USAGE);
+       }
+      else if (argvect[1][0] == 'e')
+       {
+         __settimer (0, 0);
+       }
+      else if (argvect[1][0] == 'd')
+       {
+         __disable_timer ();
+       }
+      else
+       {
+         timer_cmd (USAGE);
+       }
+    }
+  if (__timer_enabled ())
+    {
+      xprintf ("Timer is currently enabled.\n");
+    }
+  else
+    {
+      xprintf ("Timer is currently disabled.\n");
+    }
+  return 0;
+}
+#endif
+
+int 
+clear_breakpoint_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("unbreak location");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Clear breakpoint");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      clear_breakpoint_cmd (USAGE);
+      long_help ("\
+The unbreak command removes breakpoints from memory.  It takes one\n\
+argument, the location to remove the breakpoint from.\n");
+      example ("\
+unbreak 4ff5\n\
+Removes a previously set breakpoint at memory location 4ff5.");
+      return 0;
+    }
+  
+  if (argvect[1] == NULL || argvect[2] != NULL)
+    {
+      clear_breakpoint_cmd (USAGE);
+    }
+  else
+    {
+      mem_addr_t location;
+      str2addr (argvect[1], &location);
+      if (clear_mon_breakpoint (location))
+      {
+          xprintf("Unable to remove breakpoint at 0x%08lx\n", location.addr);
+      }
+    }
+  return 0;
+}
+
+
+int
+breakpoint_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("break [location]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Set or display breakpoints");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      breakpoint_cmd (USAGE);
+      long_help ("\
+The break command displays and sets breakpoints in memory.  It takes zero\n\
+or one argument.  With zero arguments, it displays a list of all currently\n\
+set breakpoints.  With one argument it sets a new breakpoint at the\n\
+specified location.\n");
+      example ("\
+break 4ff5\n\
+Sets a breakpoint at address 4ff5.");
+      return 0;
+    }
+  
+  if (argvect[1] == NULL)
+    {
+      return show_breakpoints ();
+    } 
+  else if (argvect[2] != NULL)
+    {
+      breakpoint_cmd (USAGE);
+    }
+  else
+    {
+      mem_addr_t location;
+      
+      str2addr (argvect[1], &location);
+      if (add_mon_breakpoint (location))
+      {
+          xprintf("Unable to set breakpoint at 0x%08lx\n", location.addr);
+      }
+    }
+  return 0;
+}
+
+
+int
+version_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("version");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Display version");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      version_cmd (USAGE);
+      long_help ("\
+The version command displays the version of the monitor.");
+      return 0;
+    }
+  
+  if (argvect[1] == NULL)
+    {
+      version ();
+    }
+  else
+    {
+      version_cmd (USAGE);
+    }
+  return 0;
+}
+
+int
+set_serial_port_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("port [port number]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Set the active serial port");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      set_serial_port_cmd (USAGE);
+      long_help ("\
+The port command allows control over the serial port being used by the\n\
+monitor.  It takes zero or one argument.  Called with zero arguments it\n\
+displays the port currently in use by the monitor.  Called with one\n\
+argument it switches the port in use by the monitor to the one specified.\n\
+It then prints out a message on the new port to confirm the switch.\n");
+      example ("\
+port 1\n\
+Switches the port in use by the monitor to port 1.");
+      return 0;
+    }
+  if (argvect[1] != NULL && argvect[2] != NULL)
+    {
+      set_serial_port_cmd (USAGE);
+      return 0;
+    }
+  if (argvect [1] != NULL)
+    {
+#ifdef HAVE_BSP
+      if (bsp_set_debug_comm(str2int (argvect[1], 10)) < 0)
+       xprintf("Invalid port number.\n");
+      else
+        /* Since we are using the new port, we just need to write
+          something to tell the user that this is the active port */
+        xprintf ("Cygmon I/O now on this port.\n");
+#else
+      __setTty (str2int (argvect[1], 10));
+      /* Since we are using the new port, we just need to write
+        something to tell the user that this is the active port */
+      xprintf ("Cygmon I/O now on this port.\n");
+#endif
+    }
+  else 
+    {
+      xprintf ("serial port currently set to %d\n", __getTty());
+      return 0;
+    }
+  return 0;
+}
+
+int 
+step_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("step [location]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Single step user program");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      step_cmd (USAGE);
+      long_help ("\
+The step command causes one instruction of the user program to execute, then\n\
+returns control to the monitor.  It can take zero or one argument.  If no\n\
+argument is provided, step executes one instruction at the current pc.  If\n\
+a location is specified, step executes one instruction at the specified\n\
+location.\n");
+      example ("
+step\n\
+Executes one instruction at the current pc.");
+      return 0;
+    }
+  
+  if (argvect[1] != NULL && argvect[2] != NULL)
+    {
+      step_cmd (USAGE);
+      return 0;
+    }
+  if (argvect[1] != NULL)
+    set_pc (str2int (argvect[1], 16));
+  
+  __single_step ();
+  return 1;
+
+}
+
+#if HAVE_CACHE
+/* This cache function needs to be in processor-specific files. */
+
+int
+cache_cmd (cmdmode_t mode)
+{
+  int x;
+  int cache_op = CACHE_NOOP;
+  int which_cache = -1;
+
+  if (mode == USAGE)
+    {
+      usage ("cache [type] [state]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Manipulate caches");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      cache_cmd (USAGE);
+      long_help ("\
+The cache command displays and changes the states of the caches.  It takes\n\
+zero, one, or two arguments.  With no arguments, it displays the state of\n\
+both the instruction cache and the data cache.  With one argument, it\n\
+displays the state of the specified type of cache.  With two arguments, it\n\
+changes the state of the specified cache to the specified state.\n");
+      example ("\
+cache i d\n\
+Disables the instruction cache.");
+      return 0;
+    }
+
+  if (argvect[1] != NULL && argvect[2] != NULL && argvect[3] != NULL)
+    {
+      return cache_cmd (USAGE);
+    }
+  if (argvect[1] != NULL)
+    {
+      if (argvect[1][0] == 'd')
+       which_cache = 0;
+      else if (argvect[1][0] == 'i')
+       which_cache = 1;
+      else
+       {
+         xprintf ("unknown cache type %s\n", argvect[1]);
+         return 0;
+       }
+      if (argvect[2] != NULL)
+       {
+         if (argvect[2][0] == 'e')
+           cache_op = CACHE_ENABLE;
+         else if (argvect[2][0] == 'd')
+           cache_op = CACHE_DISABLE;
+         else if (argvect[2][0] == 'f')
+           cache_op = CACHE_FLUSH;
+         else
+           {
+             xprintf ("Unknown cache op %s\n", argvect[2]);
+             return 0;
+           }
+       }
+    }
+  if (which_cache == 0 || which_cache == -1)
+    {
+      __data_cache (cache_op);
+      if (cache_op == CACHE_FLUSH)
+      {
+       xprintf ("Flushed dcache\n");
+      }
+      x = __data_cache (CACHE_NOOP);
+      xprintf ("dcache is ");
+      xprintf (x ? "enabled\n" : "disabled\n");
+    }
+  if (which_cache == 1 || which_cache == -1)
+    {
+      __instruction_cache (cache_op);
+      if (cache_op == CACHE_FLUSH)
+      {
+       xprintf ("Flushed icache\n");
+      }
+      x = __instruction_cache (CACHE_NOOP);
+      xprintf ("icache is ");
+      xprintf (x ? "enabled\n" : "disabled\n");
+    }
+  return 0;
+}
+#endif
+
+int
+set_serial_speed_cmd (cmdmode_t mode)
+{
+    if (mode == USAGE)
+    {
+      usage ("baud speed");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Set serial port baud rate");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      set_serial_speed_cmd (USAGE);
+      long_help ("\
+The baud command sets the speed of the active serial port.  It takes one\n\
+argument, which specifies the speed to which the port will be set.\n");
+      example ("\
+baud 9600\n\
+Sets the speed of the active port to 9600 baud.");
+      return 0;
+    }
+
+  if (argvect[1] == NULL || argvect[2] != NULL)
+    {
+      return set_serial_speed_cmd (USAGE);
+    }
+  else
+    {
+#ifdef HAVE_BSP
+      int channel_id = bsp_set_debug_comm(-1);
+      int baud = str2int (argvect[1], 10);
+
+      xprintf("Setting serial baud rate on channel %d to %d baud\n", 
+            channel_id, baud);
+
+      if (bsp_set_serial_baud(bsp_set_debug_comm(-1),
+                             str2int (argvect[1], 10)) < 0)
+       xprintf("Invalid baud rate\n");
+#else
+      __set_baud_rate (str2int (argvect[1], 10));
+#endif
+    }
+  return 0;
+}
+
+
+int
+set_term_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("terminal type");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Set the terminal type");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      set_term_cmd (USAGE);
+      long_help ("\
+The terminal command sets the type of the current terminal to that specified\n\
+in the type argument.  The only available terminal types are vt100 and dumb.\n\
+This is used by the line editor to determine how to update the terminal\n\
+display.\n");
+      example ("\
+terminal dumb\n\
+Sets the type of the current terminal to a dumb terminal.\n");
+      return 0;
+    }
+
+  if (argvect[1] == NULL || argvect[2] != NULL)
+    set_term_cmd (USAGE);
+  else
+    set_term_name (argvect[1]);
+  return 0;
+}
+
+int
+reset_cmd (cmdmode_t mode)
+{
+    if (mode == USAGE)
+    {
+      usage ("reset");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Reset the board (not on all architectures).");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      reset_cmd (USAGE);
+      long_help ("\
+The reset command resets the board.  This may not be implemented\n\
+on all architectures");
+      return 0;
+    }
+
+  if (argvect[1] != NULL)
+    {
+      reset_cmd (USAGE);
+    }
+  else
+    {
+      __reset ();
+    }
+  return 0;
+}
+
+#if HAVE_USAGE
+int
+memusage_cmd (cmdmode_t mode)
+{
+  extern int sdata, _end;
+
+  if (mode == USAGE)
+    {
+      usage ("usage");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Show monitor memory usage");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      memusage_cmd (USAGE);
+      long_help ("\
+The usage command shows the amount of memory being used by the monitor,\n\
+broken down by category.  Despite its name, it has nothing to do with the\n\
+usage of any other command.\n");
+      return 0;
+    }
+
+  if (argvect[1] != NULL)
+    {
+      return memusage_cmd (USAGE);
+    }
+  else
+    {
+      xprintf ("%d bytes were allocated with sbrk\n", (char *)sbrk (0) - (char *)&_end);
+    }
+  return 0;
+}
+#endif /* HAVE_USAGE */
+
+int
+disassemble_cmd (cmdmode_t mode)
+{
+#ifdef DISASSEMBLER
+  int x;
+
+  if (mode == USAGE)
+    {
+      usage ("disassemble [location]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Disassemble memory");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      disassemble_cmd (USAGE);
+      long_help ("\
+The disassemble command disassembles the contents of memory.  Because of the\n\
+way breakpoints are handled, all instructions are shown and breakpoints are\n\
+not visible in the disassembled code.  The disassemble command takes zero\n\
+or one argument.  When called with zero arguments, it starts disassembling\n\
+from the current (user program) pc.  When called with a location, it starts\n\
+disassembling from the specified location.  When called after a previous\n\
+call and with no arguments, it disassembles the next area of memory after\n\
+the one previously disassembled.\n");
+      example ("\
+disassemble 45667000\n\
+Displays disassembled code starting at location 45667000.");
+      return 0;
+    }
+  if (argvect [1] != NULL && argvect[2] != NULL)
+    {
+      return disassemble_cmd (USAGE);
+    }
+
+  if(argvect [1] != NULL)
+    str2addr (argvect [1], &last_pc);
+  for (x = 0; x < 10; x++)
+    last_pc = do_dis (&last_pc);
+  flush_dis ();
+#else
+#warning "DISASSEMBLER not implemented"
+  xprintf ("disassembler not available\n");
+#endif
+
+  return 0;
+}
+
+int
+copy_cmd (cmdmode_t mode)
+{
+  mem_addr_t src, dst;
+  target_register_t size;
+
+  if (mode == USAGE)
+    {
+      usage ("copy startaddr destaddr amount");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Copies one area of memory to another");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      copy_cmd (USAGE);
+      long_help ("\
+The copy command is used to copy 'amount' bytes of memory\n\
+from 'startaddr' to 'destaddr'\n");
+      example ("\
+copy 10000 20000 300\n\
+Copies 0x300 bytes of memory from 0x10000 to 0x20000.");
+      return 0;
+    }
+  if (argvect[1] == NULL || argvect[2] == NULL || argvect[3] == NULL
+      || argvect[4] != NULL)
+    {
+      return copy_cmd (USAGE);
+    }
+  str2addr (argvect[1], &src);
+  str2addr (argvect[2], &dst);
+  size = str2int (argvect[3], 16);
+  while (size > 0)
+    {
+      char buf[128];
+
+      int msize = (size > 128) ? 128 : size;
+      if (read_memory (&src, 1, msize, buf))
+        {
+          xprintf ("Memory read failed\n");
+          break;
+        }
+      if (write_memory (&dst, 1, msize, buf))
+        {
+          xprintf ("Memory write failed\n");
+          break;
+        }
+#ifdef HAVE_BSP
+      bsp_flush_dcache((void *)dst.addr, msize);
+      bsp_flush_icache((void *)dst.addr, msize);
+#endif
+      ADD_OFFSET (&src, &src, msize);
+      ADD_OFFSET (&dst, &dst, msize);
+      size -= msize;
+    }
+  return 0;
+}
+
+#ifndef HAVE_BSP
+int
+set_program_args_cmd (cmdmode_t mode)
+{
+  int argc;
+
+  if (mode == USAGE)
+    {
+      usage ("setargs [args]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Sets the program arguments passed to main()");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      set_program_args_cmd (SHORT_HELP);
+      return 0;
+    }
+  for (argc = 1; argvect[argc] != NULL; argc++)
+    ;
+  __set_program_args (argc - 1, argvect + 1);
+  return 0;
+}
+#endif
+
+
+int
+fill_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("fill[.size] startaddress endaddress [value]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Fills memory with a specified value");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      fill_cmd (USAGE);
+      long_help("\
+The fill command is used to fill a region of memory from 'startaddress'\n\
+to 'endaddress' with the value in 'value'.  If no value is specificed,\n\
+it uses zero.  It can take a size extension, which follows the command\n\
+name or partial command name without a space, and is a period followed\n\
+by the size of the writes that are used, in bits.  Options are 8, 16,\n\
+32, and 64.  Without a size extension, the fill command defaults to\n\
+changing 8 bits at a time.\n");
+      example ("\
+fill.32 10000 20000 32\n\
+Fills the region between 0x10000 and 0x20000 with the 32 bit value 0x32.");
+      return 0;
+    }
+  if ((argvect[1] == NULL || argvect[2] == NULL)
+      || (argvect[3] != NULL && argvect[4] != NULL))
+    {
+      fill_cmd (USAGE);
+      return 0;
+    } else { 
+      mem_addr_t start,end;
+      char value[8];
+      int size = get_cmd_size();
+      int amt;
+
+      if (size == -1)
+          /*
+           * Invalid size specified.
+           */
+          return 0;
+
+      if (argvect[3] != NULL)
+        {
+          hex2bytes (argvect[3], value, size);
+        }
+      else
+        {
+          hex2bytes ("0", value, size);
+        }
+      str2addr (argvect[1], &start);
+      str2addr (argvect[2], &end);
+      amt = MEM_ADDR_DIFF (end, start);
+      if (amt < 0)
+        {
+          xprintf ("Addresses in incorrect order\n");
+        }
+      else
+        {
+          int x;
+         if (get_memory_display_mode ())
+           {
+             /* Gotta swap this puppy. */
+             int x;
+
+             for (x = 0; x < (size / 2); x++)
+               {
+                 char tmp = value[x];
+                 value [x] = value [size - 1 - x];
+                 value [size - 1 - x] = tmp;
+               }
+           }
+
+          xprintf ("Writing %d units\n", amt / size + 1);
+          for (x = amt / size; x >= 0; x--)
+            {
+              if (write_memory (&start, size, 1, value))
+               {
+                  xprintf ("Memory write failed\n");
+                  break;
+                }
+              ADD_OFFSET (&start, &start, size);
+            }
+        }
+    }
+  return 0;
+}
+
+
+int
+swapmem_cmd (cmdmode_t mode)
+{
+  int display_settings = 0;
+
+  if (mode == USAGE)
+    {
+      usage ("swapmem [little|big]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Sets whether or not memory values are byte-swapped");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      swapmem_cmd (USAGE);
+
+      long_help("\
+The swapmem command is used to determine whether or not memory values are\n\
+displayed and written in little or big-endian byte order. By default, values\n\
+are read and written to match the byte order of the target CPU.\n\
+This command does not alter the CPU state in any way; it only changes the\n\
+way memory values are displayed and written within the monitor.\n");
+      example("\
+swapmem \n\
+Displays the byte order that is currently in effect.");
+      return 0;
+      display_settings = 1;
+    }
+  else
+    {
+      if (argvect[1] != NULL && argvect[2] != NULL)
+       {
+         swapmem_cmd (USAGE);
+         return 0;
+       }
+    }
+  if (display_settings || argvect[1] == NULL)
+    {
+      if (get_memory_display_mode ())
+       {
+         xprintf ("Memory values are read and written in little-endian byte order.\n");
+       }
+      else
+       {
+         xprintf ("Memory values are read and written in big-endian byte order.\n");
+       }
+      return 0;
+    }
+  if (strncmp (argvect[1], "little", strlen (argvect[1])) == 0)
+    {
+      set_memory_display_mode (1);
+      xprintf ("Memory values are now read and written in little-endian order.\n");
+    }
+  else if (strncmp (argvect[1], "big", strlen (argvect[1])) == 0)
+    {
+      set_memory_display_mode (0);
+      xprintf ("Memory values are now read and written in big-endian order.\n");
+    }
+  else
+    {
+      return swapmem_cmd (USAGE);
+    }
+  return 0;
+}
+
+#ifdef MONITOR_CONTROL_INTERRUPTS
+int
+int_cmd (cmdmode_t mode)
+{
+  if (mode == USAGE)
+    {
+      usage ("interrupt [on|off]");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("Enables or disables interrupts within the monitor");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      int_cmd (USAGE);
+      long_help("\
+The interrupt command is used to enable or disable interrupts while the\n\
+monitor is running.");
+      return 0;
+    }
+  if (argvect[1] != NULL && argvect[2] != NULL)
+    {
+      int_cmd (USAGE);
+      return 0;
+    }
+  if (argvect[1] != NULL)
+    {
+      if (strcmp (argvect[1], "on") == 0)
+       {
+         monitor_enable_interrupts ();
+       }
+      else if (strcmp (argvect[1], "off") == 0)
+       {
+         monitor_disable_interrupts ();
+       }
+      else
+       {
+         int_cmd (USAGE);
+         return 0;
+       }
+    }
+  xprintf ("Interrupts ");
+  if (monitor_interrupt_state ())
+    {
+      xprintf ("enabled\n");
+    }
+  else
+    {
+      xprintf ("disabled\n");
+    }
+  return 0;
+}
+#endif
+
+
+/* Table used by the crc32 function to calcuate the checksum. */
+static uint32 crc32_table[256];
+static int crc_initted = 0;
+
+static uint32
+crc32 (unsigned char *buf, int len, uint32 crc)
+{
+  if (! crc_initted)
+    {
+      /* Initialize the CRC table and the decoding table. */
+      int i, j;
+      uint32 c;
+
+      crc_initted = 1;
+      for (i = 0; i < 256; i++)
+       {
+         for (c = i << 24, j = 8; j > 0; --j)
+           c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
+         crc32_table[i] = c;
+       }
+    }
+
+  while (len--)
+    {
+      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
+      buf++;
+    }
+  return crc;
+}
+
+
+int
+checksumcmd (cmdmode_t mode)
+{
+  mem_addr_t start, end;
+  uint32 crc = 0xffffffff;
+
+  if (mode == USAGE)
+    {
+      usage ("crc startaddr endaddr");
+      return 0;
+    }
+  if (mode == SHORT_HELP)
+    {
+      short_help ("checksum an area of memory");
+      return 0;
+    }
+  if (mode == LONG_HELP)
+    {
+      checksumcmd (USAGE);
+      long_help ("\
+The crc command is used to calculate a standard CRC32 checksum of the\n\
+specified memory region. The checksum is printed out as a hexadecimal\n\
+value.");
+      return 0;
+    }
+  if (argvect[1] == NULL || argvect[2] == NULL || argvect[3] != NULL)
+    {
+      return checksumcmd (USAGE);
+    }
+
+  str2addr (argvect[1], &start);
+  str2addr (argvect[2], &end);
+  while (start.addr < end.addr)
+    {
+      char c[1024];
+      int len = end.addr - start.addr;
+      if (len > sizeof(c))
+       len = sizeof(c);
+      
+      read_memory (&start, 1, len, c);
+      crc = crc32 (c, len, crc);
+      start.addr += len;
+    }
+  xprintf("0x%08lx is checksum\n", crc);
+  return 0;
+}
+
+char **argvect;
+static char argvect_cmd[MAXLINELEN];
+
+static char **
+buildargv (char *input)
+{
+  static char *arglist[256];
+  int numargs = 0;
+
+  while (1)
+    {
+      while (isspace ((unsigned char)*input) && *input != 0)
+         input++;
+      if (*input == 0)
+       break;
+      arglist [numargs++] = input;
+      while (!isspace ((unsigned char)*input) && *input != 0)
+       input++;
+      if (*input == 0)
+       break;
+      *(input++) = 0;
+    }
+  arglist [numargs] = NULL;
+  return arglist;
+}
+
+
+int
+monitor_loop (void)
+{
+  int state = 1, return_value = 0;
+
+  while (state == 1)
+    {
+      /* Get a line of input, putting it in the input buffer */
+      lineedit (PROMPT, inbuf, sizeof (inbuf));
+      xprintf ("\n");
+
+      if (switch_to_stub_flag)
+        {
+#ifndef HAVE_BSP
+         switch_to_stub_flag = 0;
+#endif
+          return transfer_to_stub ();
+        }
+
+      /* Separate off the command from any other stuff on the line */
+      
+      strcpy (argvect_cmd, inbuf);
+      argvect = buildargv (argvect_cmd);
+
+      if (argvect[0] != NULL && argvect[0][0] != '\0')
+       {
+         char *ptr;
+         int command_number;
+
+         strcpy (cmd, argvect[0]);
+
+         /* Function to split off . delimiters. */
+         ptr = strchr (cmd, '.');
+
+         if (ptr != NULL && *ptr == '.')
+           *ptr = '\0';
+
+         /* See if it's an alias. */
+         command_number = alias_compare (cmd);
+
+         /* Compare input to command list, check for conflicts. */
+         if (command_number < 0)
+           command_number = command_compare (cmd);
+
+         /* If we found a command, just run the function */
+         if (command_number >= 0)
+           {
+             int status;
+             /* Execute the function, if the function returns a non-zero 
+                value, break out of the loop and return. */
+             status = (*cmdtab[command_number].function) (INVOCATION);
+             if (status)
+               {
+                 state = 0;
+                 if (status < 0)
+                   return_value = 1;
+               }
+           }
+         else
+           {
+             /* If none of the commands or aliases match, complain. */
+             xprintf ("Not a legal command\n");
+           }
+         
+         if (inbuf[0] != '\0')
+           addHistoryCmd (inbuf);
+       }
+    }
+  return return_value;
+}
+
+
diff --git a/packages/cygmon/v2_0/misc/monitor_cmd.h b/packages/cygmon/v2_0/misc/monitor_cmd.h
new file mode 100644 (file)
index 0000000..23535b6
--- /dev/null
@@ -0,0 +1,126 @@
+//==========================================================================
+//
+//      monitor_cmd.h
+//
+//      Monitor command definitions for the CygMON ROM monitor
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      Monitor command definitions for the CygMON ROM monitor
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#ifndef MONITOR_CMD_H
+#define MONITOR_CMD_H
+
+#ifndef ASM
+typedef enum {
+  INVOCATION, USAGE, SHORT_HELP, LONG_HELP
+} cmdmode_t;
+
+struct cmdentry
+{
+  char *alias;
+  char *cmd;
+  int (*function) (cmdmode_t);
+};
+
+extern struct cmdentry cmdtab [];
+
+extern int monitor_loop (void);
+
+extern char inbuf[];
+
+extern char **argvect;
+
+typedef int (*srec_input_func_t)(void);
+
+extern int load_srec(srec_input_func_t inp_func);
+
+#ifdef USE_HELP
+extern void usage (char *string);
+extern void short_help (char *string);
+extern void long_help (char *string);
+extern void example (char *string);
+#else
+#define usage(x) no_help_usage ()
+#define short_help(x) no_help()
+#define long_help(x) no_help()
+#define example(x)
+extern void no_help (void);
+extern void no_help_usage (void);
+#endif
+extern int help_cmd (cmdmode_t mode);
+extern int mem_cmd (cmdmode_t mode);
+
+extern int dump_cmd (cmdmode_t mode);
+extern int ethaddr_cmd (cmdmode_t mode);
+extern int ipaddr_cmd (cmdmode_t mode);
+extern int tcpport_cmd (cmdmode_t mode);
+extern int load_cmd (cmdmode_t mode);
+extern int reg_cmd (cmdmode_t mode);
+extern int go_cmd (cmdmode_t mode);
+extern int othernames_cmd (cmdmode_t mode);
+extern int step_cmd (cmdmode_t mode);
+extern int transfer_cmd (cmdmode_t mode);
+extern int timer_cmd (cmdmode_t mode);
+extern int disassemble_cmd (cmdmode_t mode);
+extern int breakpoint_cmd (cmdmode_t mode);
+extern int clear_breakpoint_cmd (cmdmode_t mode);
+extern int memusage_cmd (cmdmode_t mode);
+extern int set_serial_port_cmd (cmdmode_t mode);
+extern int set_serial_speed_cmd (cmdmode_t mode);
+extern int version_cmd (cmdmode_t mode);
+extern int cache_cmd (cmdmode_t mode);
+extern int set_term_cmd (cmdmode_t mode);
+extern int reset_cmd (cmdmode_t mode);
+extern int copy_cmd (cmdmode_t mode);
+extern int fill_cmd (cmdmode_t mode);
+extern int set_program_args_cmd (cmdmode_t mode);
+extern int swapmem_cmd (cmdmode_t mode);
+extern int checksumcmd (cmdmode_t mode);
+extern int int_cmd (cmdmode_t mode);
+#endif
+
+#endif
diff --git a/packages/cygmon/v2_0/misc/stub-tservice.h b/packages/cygmon/v2_0/misc/stub-tservice.h
new file mode 100644 (file)
index 0000000..10aa56c
--- /dev/null
@@ -0,0 +1,54 @@
+//==========================================================================
+//
+//      stub-tservice.h
+//
+//      
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:   
+// Description:
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Placeholder
diff --git a/packages/cygmon/v2_0/misc/tservice.h b/packages/cygmon/v2_0/misc/tservice.h
new file mode 100644 (file)
index 0000000..1338b37
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef __TSERVICE_H__
+#define __TSERVICE_H__
+//==========================================================================
+//
+//      tservice.h
+//
+//      These are the core functions are expected to be provided by the
+//      target dependent services.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+/* These are the core functions are expected to be provided by the
+   target dependent services. They are used by both cygmon and by
+   libstub
+*/
+
+
+extern int read_memory (mem_addr_t *src, int size, int amt, char *dst);
+
+extern int write_memory (mem_addr_t *dst, int size, int amt, char *src);
+
+
+#ifndef USE_ECOS_HAL_BREAKPOINTS
+extern void set_breakpoint (struct bp *bp);
+extern void clear_breakpoint (struct bp *bp);
+#endif // USE_ECOS_HAL_BREAKPOINTS
+
+#ifndef HAVE_BSP
+extern void set_pc (target_register_t pc);
+#endif
+
+extern target_register_t next_step_pc (void);
+
+extern void enable_interrupts (void);
+
+#endif // __TSERVICE_H__
+
+
+extern void initialize_mon(void);
diff --git a/packages/cygmon/v2_0/misc/unistd.h b/packages/cygmon/v2_0/misc/unistd.h
new file mode 100644 (file)
index 0000000..6bbfe6e
--- /dev/null
@@ -0,0 +1,54 @@
+//==========================================================================
+//
+//      unistd.h
+//
+//      Standard Unix/POSIX environment 
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas
+// Date:         1999-10-20
+// Purpose:      
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+// Placeholder only
diff --git a/packages/cygmon/v2_0/misc/utils.c b/packages/cygmon/v2_0/misc/utils.c
new file mode 100644 (file)
index 0000000..04b6174
--- /dev/null
@@ -0,0 +1,376 @@
+//==========================================================================
+//
+//      utils.c
+//
+//      Monitor utilities.
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    
+// Contributors: gthomas, dmoseley
+// Date:         1999-10-20
+// Purpose:      Monitor utilities.
+// Description:  
+//               
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef HAVE_BSP
+#include <bsp/bsp.h>
+#include <bsp/cpu.h>
+#include <bsp/hex-utils.h>
+#endif
+#include "monitor.h"
+#include "tservice.h"
+
+#if USE_CYGMON_PROTOTYPES
+/* Use common prototypes */
+/* Some of the composed board.h files compose these
+   prototypes redundently, but if they dont,
+   these are the common definitions */
+#include "fmt_util.h"   /* Interface to string formatting utilities */
+#include "generic-stub.h" /* from libstub */
+#endif /* USE_CYGMON_PROTOTYPES */
+
+volatile int switch_to_stub_flag = 0;
+
+/* Input routine for the line editor. */
+int
+input_char (void)
+{
+  int i;
+
+  /* We have to drop the '+' characters on the floor
+     because gdb will send a '+' as the first character
+     when connecting to the target. If we waste time
+     echoing that, slow hw might get a uart overrun. */
+  while ((i = xgetchar ()) == '+');
+
+  if (i == '$')
+    {
+      xungetchar ('$');
+      switch_to_stub_flag = 1;
+      i = '\n';
+    }
+  return i;
+}
+
+
+static char tohex_array[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
+                              '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+#define tohex(X) (tohex_array[(X) & 15])
+
+#ifdef HAVE_BSP
+#define fromhex __hex
+#else
+static int
+fromhex (a)
+{
+  int number = -1;
+
+  if (a >= '0' && a <= '9')
+    number = a - '0';
+  else if (a >= 'a' && a <= 'f')
+    number = a - 'a' + 10;
+  else if (a >= 'A' && a <= 'F')
+    number = a - 'A' + 10;
+  else 
+    xprintf ("Invalid hex digit %c", a);
+
+  return number;
+}
+#endif
+
+
+static unsigned long long
+str2ull (char *str, int base)
+{
+  unsigned long long l = 0;
+
+  if (str[0] == '0' && str[1] == 'x')
+    {
+      str += 2 ;
+      base = 16 ;
+    }
+
+  while (*str != '\0')
+    {
+      if (*str == '.')
+       str++;
+      else
+       l = (l * base) + fromhex(*str++);
+    }
+
+  return l;
+}
+
+
+/* Converts a string to a long, base is the assumed base of the string */
+
+target_register_t
+str2int (char *str, int base)
+{
+  return str2ull(str, base);
+}
+
+/* Converts a string to a double, input is a raw integer string
+ * of the given assumed base. */
+#if HAVE_DOUBLE_REGS
+static double
+str2double (char *str, int base)
+{
+  double d;
+
+  switch (sizeof(double))
+    {
+      case sizeof(unsigned int):
+       *((unsigned int *)&d) = str2ull(str, base);
+       break;
+#if __LONG_MAX__ != __INT_MAX__
+      case sizeof(unsigned long):
+       *((unsigned long *)&d) = str2ull(str, base);
+       break;
+#endif
+#if __LONG_LONG_MAX__ != __LONG_MAX__
+      case sizeof(unsigned long long):
+       *((unsigned long long *)&d) = str2ull(str, base);
+       break;
+#endif
+      default:
+       d = 0.0;
+       break;
+    }
+  return d;
+}
+#endif
+
+target_register_t
+str2intlen (char *str, int base, int len)
+{
+  target_register_t number = 0;
+
+  while ((len--) > 0 && *str != '\0')
+    number = number * base + fromhex (*(str++));
+
+  return number;
+}
+
+int
+hex2bytes (char *str, char *dest, int maxsize)
+{
+  int i;
+  char *ptr;
+
+  for (i = 0; i < maxsize; i++)
+    dest[i] = 0;
+  maxsize--;
+
+  // Don't try and convert 0x prefix
+  if ((str[0] == '0') && (str[1] == 'x'))
+      str += 2;
+
+  ptr = str + strlen(str) - 1;
+  while (maxsize >= 0 && ptr >= str)
+    {
+      dest [maxsize] = fromhex(*ptr);
+      ptr--;
+      if (ptr >= str)
+       {
+         dest [maxsize--] |= fromhex(*ptr) * 16;
+         ptr--;
+       }
+    }
+  return 0;
+}
+
+
+/* Converts an unsigned long long to an ASCII string, adding leading
+   zeroes to pad space up to numdigs. */
+static int use_dots = 1;
+
+#define MAX_NUM_DIGS 51
+
+static char *
+ull2str (unsigned long long number, int base, int numdigs)
+{
+  static char string[MAX_NUM_DIGS+1];
+  int dots, i;
+  char *ptr = string + MAX_NUM_DIGS;
+
+  dots = (use_dots && base == 16);
+
+  *(ptr--) = '\0';
+  *(ptr--) = tohex (number % base);
+  i = 1;
+  number = number / base;
+
+  while (number != 0)
+    {
+      if (dots && (i % 4) == 0)
+       *(ptr--) = '.';
+      *(ptr--) = tohex (number % base);
+      i++;
+      number = number / base;
+    }
+
+  if (numdigs == 0)
+    {
+      numdigs = i;
+    }
+  else
+    {
+      while(i < numdigs)
+       {
+         if (dots && (i % 4) == 0)
+           *(ptr--) = '.';
+         *(ptr--) = '0';
+         i++;
+       }
+    }
+  return ptr + 1;
+}
+
+
+char *
+int2str (target_register_t number, int base, int numdigs)
+{
+  return ull2str((unsigned long long)number, base, numdigs);
+}
+
+#if HAVE_DOUBLE_REGS
+static char *
+double2str(double d)
+{
+  switch(sizeof(double))
+    {
+      case sizeof(unsigned int):
+       return ull2str(*((unsigned int *)&d), 16, sizeof(double) * 2);
+       break;
+#if __LONG_MAX__ != __INT_MAX__
+      case sizeof(unsigned long):
+       return ull2str(*((unsigned long *)&d), 16, sizeof(double) * 2);
+       break;
+#endif
+#if __LONG_LONG_MAX__ != __LONG_MAX__
+      case sizeof(unsigned long long):
+       return ull2str(*((unsigned long long *)&d), 16, sizeof(double) * 2);
+       break;
+#endif
+    }
+  return "....fixme...";
+}
+#endif
+
+#ifndef NO_MALLOC
+char *
+strdup(const char *str)
+{
+  char *x = malloc (strlen (str) + 1);
+  if (x != NULL)
+    strcpy (x, str);
+  return x;
+}
+#endif
+
+
+target_register_t
+get_pc(void)
+{
+    return get_register(REG_PC);
+}
+
+
+#if defined(HAVE_BSP) && !defined(__ECOS__)
+static int
+get_register_type(regnames_t which)
+{
+    int i;
+
+    for (i = 0; regtab[i].registername != NULL; i++)
+      if (regtab[i].registernumber == which)
+       return regtab[i].registertype;
+    return REGTYPE_INT;
+}
+#endif
+
+char *get_register_str (regnames_t which, int detail, int valid)
+{
+#ifdef SPECIAL_REG_OUTPUT
+  char *res;
+
+  if ((res = SPECIAL_REG_OUTPUT (which, detail)) != NULL)
+    {
+      return res;
+    }
+#endif
+  if (valid == 0)
+    {
+      switch (sizeof (target_register_t))
+        {
+        case 1:  return "...";
+        case 2:  return ".....";
+        case 4:  return ".........";
+        case 8:  return ".................";
+        default: return ".........";
+        }
+    }
+  else
+    {
+      return int2str (get_register (which), 16, sizeof (target_register_t) * 2);
+    }
+}
+
+
+void
+store_register (regnames_t which, char *string)
+{
+#ifdef SPECIAL_REG_STORE
+  if (SPECIAL_REG_STORE(which, string))
+    return;
+#endif
+  put_register (which, str2int (string, 16));
+}
+
+
+