--- /dev/null
+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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# 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
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+
+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
--- /dev/null
+#ifndef __LINUX_COMPILER_H__
+#define __LINUX_COMPILER_H__
+
+#define likely(x) (x)
+#define unlikely(x) (x)
+
+#endif /* __LINUX_COMPILER_H__ */
--- /dev/null
+#ifndef __LINUX_COMPLETION_H__
+#define __LINUX_COMPLETION_H__
+
+struct completion { } ;
+
+#endif /* __LINUX_COMPLETION_H__ */
+
--- /dev/null
+#ifndef __LINUX_CONFIG_H__
+#define __LINUX_CONFIG_H__
+
+
+#endif /* __LINUX_CONFIG_H__ */
--- /dev/null
+#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
--- /dev/null
+#include <errno.h>
--- /dev/null
+#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__ */
--- /dev/null
+#ifndef __LINUX_INIT_H__
+#define __LINUX_INIT_H__
+#endif
--- /dev/null
+#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__ */
+
+
+
+
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+#ifndef __LINUX_MTD_COMPATMAC_H__
+#define __LINUX_MTD_COMPATMAC_H__
+
+
+#endif /* __LINUX_MTD_COMPATMAC_H__ */
--- /dev/null
+#ifndef __LINUX_MTD_MTD_H__
+#define __LINUX_MTD_MTD_H__
+
+
+#endif /* __LINUX_MTD_MTD_H__ */
--- /dev/null
+#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__ */
--- /dev/null
+#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 */
--- /dev/null
+#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__
--- /dev/null
+#ifndef __LINUX_SCHED_H__
+#define __LINUX_SCHED_H__
+
+#define cond_resched() do { } while(0)
+#define signal_pending(x) (0)
+
+#endif /* __LINUX_SCHED_H__ */
--- /dev/null
+#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__ */
+
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#ifndef __LINUX_STRING_H__
+#define __LINUX_STRING_H__
+
+#include <string.h>
+
+#endif /* __LINUX_STRING_H__ */
--- /dev/null
+#ifndef __LINUX_TIMER_H__
+#define __LINUX_TIMER_H__
+
+/* Not yet */
+
+struct timer_list { } ;
+
+
+#endif /* __LINUX_TIMER_H__ */
+
--- /dev/null
+#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__ */
+
--- /dev/null
+#ifndef __LINUX_VERSION_H__
+#define __LINUX_VERSION_H__
+
+
+#endif /* __LINUX_VERSION_H__ */
--- /dev/null
+#ifndef __LINUX_VMALLOC_H__
+#define __LINUX_VMALLOC_H__
+#endif
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#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__ */
--- /dev/null
+#ifndef __LINUX_ZUTIL_H__
+#define __LINUX_ZUTIL_H__
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+#endif /* __LINUX_ZUTIL_H__ */
--- /dev/null
+/*========================================================================
+//
+// 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;
+}
--- /dev/null
+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####
--- /dev/null
+# ====================================================================
+#
+# 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
+
+
--- /dev/null
+# ====================================================================
+#
+# 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
+
+
--- /dev/null
+<!-- {{{ 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/IEC
+ 9945-1)[POSIX].
+ </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/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
+ [POSIX]. Online, the Open Group Single Unix
+ Specification [SUS2] 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.
+ [Lewine] covers the process, signal, file and I/O
+ functions, while [Lewis1], [Lewis2],
+ [Nichols] and [Norton] 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 “// TBA”
+ are potential candidates for later implementation.
+ </para>
+
+<!-- }}} -->
+<!-- {{{ Process Primitives -->
+
+<sect1 id="posix-process-primitives">
+<title>Process Primitives [POSIX Section 3]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int kill(pid_t pid, int sig);
+int pthread_kill(pthread_t thread, int sig);
+int sigaction(int sig, const struct sigaction *act,
+ struct sigaction *oact);
+int sigqueue(pid_t pid, int sig, const union sigval value);
+int sigprocmask(int how, const sigset_t *set,
+ sigset_t *oset);
+int pthread_sigmask(int how, const sigset_t *set,
+ sigset_t *oset);
+int sigpending(sigset_t *set);
+int sigsuspend(const sigset_t *set);
+int sigwait(const sigset_t *set, int *sig);
+int sigwaitinfo(const sigset_t *set, siginfo_t *info);
+int sigtimedwait(const sigset_t *set, siginfo_t *info,
+ const struct timespec *timeout);
+int sigemptyset(sigset_t *set);
+int sigfillset(sigset_t *set);
+int sigaddset(sigset_t *set, int signo);
+int sigdelset(sigset_t *set, int signo);
+int sigismember(const sigset_t *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_t fork(void);
+int execl( const char *path, const char *arg, ... );
+int execv( const char *path, char *const argv[] );
+int execle( const char *path, const char *arg, ... );
+int execve( const char *path, char *const argv[],
+ char *const envp[] );
+int execlp( const char *path, const char *arg, ... );
+int execvp( const char *path, char *const argv[] );
+int pthread_atfork( void(*prepare)(void),
+ void (*parent)(void),
+ void (*child)() );
+pid_t wait( int *stat_loc );
+pid_t waitpid( pid_t pid, int *stat_loc,
+ int options );
+void _exit( int status );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+<itemizedlist>
+ <listitem>
+ <para>
+ Signal handling may be enabled or disabled with the
+ CYGPKG_POSIX_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_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_code</emphasis> value,
+ <emphasis>SI_EXCEPT</emphasis>, is defined to
+ distinguish hardware generated exceptions from
+ others.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Extra signals are defined:
+ _SIGTRAP_,_SIGIOT_,
+ _SIGEMT_, and _SIGSYS_. 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 [POSIX Section 4]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int uname( struct utsname *name );
+time_t time( time_t *tloc );
+char *getenv( const char *name );
+int isatty( int fd );
+long sysconf( int name );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<screen>
+pid_t getpid( void );
+pid_t getppid( void );
+uid_t getuid( void );
+uid_t geteuid( void );
+gid_t getgid( void );
+gid_t getegid( void );
+int setuid( uid_t uid );
+int setgid( gid_t gid );
+int getgroups( int gidsetsize, gid_t grouplist[] );
+char *getlogin( void );
+int getlogin_r( char *name, size_t namesize );
+pid_t getpgrp( void );
+pid_t setsid( void );
+int setpgid( pid_t pid, pid_t pgid );
+char *ctermid( char *s);
+char *ttyname( int fd ); // TBA
+int ttyname_r( int fd, char *name, size_t namesize); // TBA
+clock_t times( struct tms *buffer ); // TBA
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+ <itemizedlist>
+ <listitem>
+ <para>The fields of the <emphasis>utsname</emphasis>
+ structure are initialized as follows:
+ <screen>
+ sysname “eCos”
+ nodename “” (gethostname() is currently not available)
+
+ release Major version number of the kernel
+ version Minor version number of the kernel
+ machine “” (Requires some config tool changes)
+ </screen>
+ </para>
+ <para>
+ The sizes of these strings are defined by
+ CYG_POSIX_UTSNAME_LENGTH and
+ CYG_POSIX_UTSNAME_NODENAME_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_LIBC_DEFAULT_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><limits.h></filename>,
+ or zero.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Files and Directories -->
+
+<sect1 id="posix-files-and-directories">
+<title>Files and Directories [POSIX Section 5]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+DIR *opendir( const char *dirname );
+struct dirent *readdir( DIR *dirp );
+int readdir_r( DIR *dirp, struct dirent *entry,
+ struct dirent **result );
+void rewinddir( DIR *dirp );
+int closedir( DIR *dirp );
+int chdir( const char *path );
+char *getcwd( char *buf, size_t size );
+int open( const char * path , int oflag , ... );
+int creat( const char * path, mode_t mode );
+int link( const char *existing, const char *new );
+int mkdir( const char *path, mode_t mode );
+int unlink( const char *path );
+int rmdir( const char *path );
+int rename( const char *old, const char *new );
+int stat( const char *path, struct stat *buf );
+int fstat( int fd, struct stat *buf );
+int access( const char *path, int amode );
+long pathconf(const char *path, int name);
+long fpathconf(int fd, int name);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+mode_t umask( mode_t cmask );
+int mkfifo( const char *path, mode_t mode );
+int chmod( const char *path, mode_t mode ); // TBA
+int fchmod( int fd, mode_t mode ); // TBA
+int chown( const char *path, uid_t owner, gid_t group );
+int utime( const char *path, const struct utimbuf *times ); // TBA
+int ftruncate( int fd, off_t length ); // TBA
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If a call to <function>open()</function> or <function>creat()</function> supplies
+ the third _mode_ 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_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_FILEIO_NFILE option. The maximum number
+ of file descriptors is supplied by the CYGNUM_FILEIO_NFD
+ option.
+ </para>
+ </listitem>
+ </itemizedlist>
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Input and Output -->
+
+<sect1 id="posix-input-and-output">
+<title>Input and Output [POSIX Section 6]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int dup( int fd );
+int dup2( int fd, int fd2 );
+int close(int fd);
+ssize_t read(int fd, void *buf, size_t nbyte);
+ssize_t write(int fd, const void *buf, size_t nbyte);
+int fcntl( int fd, int cmd, ... );
+off_t lseek(int fd, off_t offset, int whence);
+int fsync( int fd );
+int fdatasync( int fd );</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<screen>
+int pipe( int fildes[2] );
+int aio_read( struct aiocb *aiocbp ); // TBA
+int aio_write( struct aiocb *aiocbp ); // TBA
+int lio_listio( int mode, struct aiocb *const list[],
+ int nent, struct sigevent *sig); // TBA
+int aio_error( struct aiocb *aiocbp ); // TBA
+int aio_return( struct aiocb *aiocbp ); // TBA
+int aio_cancel( int fd, struct aiocb *aiocbp ); // TBA
+int aio_suspend( const struct aiocb *const list[],
+ int nent, const struct timespec *timeout ); // TBA
+int aio_fsync( int op, struct aiocb *aiocbp );
+// TBA
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Only the <emphasis>F_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 [POSIX Section 7]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+<screen>
+speed_t cfgetospeed( const struct termios *termios_p );
+int cfsetospeed( struct termios *termios_p, speed_t speed );
+speed_t cfgetispeed( const struct termios *termios_p );
+int cfsetispeed( struct termios *termios_p, speed_t speed );
+int tcgetattr( int fd, struct termios *termios_p );
+int tcsetattr( int fd, int optional_actions,
+ const struct termios *termios_p );
+int tcsendbreak( int fd, int duration );
+int tcdrain( int fd );
+int tcflush( int fd, int queue_selector );
+int tcsendbreak( int fd, int action );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+pid_t tcgetpgrp( int fd );
+int tcsetpgrp( int fd, pid_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
+ “tty” devices, not the “serial”
+ devices. None of the functionality relevant to job
+ control, controlling terminals and sessions is
+ implemented.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Only <emphasis>MIN</emphasis> = 0 and
+ <emphasis>TIME</emphasis> = 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 [POSIX Section 8]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+<screen>
+char *setlocale( int category, const char *locale );
+int fileno( FILE *stream );
+FILE *fdopen( int fd, const char *type );
+int getc_unlocked( FILE *stream);
+int getchar_unlocked( void );
+int putc_unlocked( FILE *stream );
+int putchar_unlocked( void );
+char *strtok_r( char *s, const char *sep,
+ char **lasts );
+char *asctime_r( const struct tm *tm, char *buf );
+char *ctime_r( const time_t *clock, char *buf );
+struct tm *gmtime_r( const time_t *clock,
+ struct tm *result );
+struct tm *localtime_r( const time_t *clock,
+ struct tm *result );
+int rand_r( unsigned int *seed );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<screen>
+void flockfile( FILE *file );
+int ftrylockfile( FILE *file );
+void funlockfile( FILE *file );
+int sigsetjmp( sigjmp_buf env, int savemask ); // TBA
+void siglongjmp( sigjmp_buf env, int val ); // TBA
+void tzset(void); // 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_unlocked()</emphasis>,
+ <emphasis>getchar_unlocked()</emphasis>,
+ <emphasis>putc_unlocked()</emphasis> and
+ <emphasis>putchar_unlocked()</emphasis> are defined
+ but are currently identical to their non-unlocked
+ equivalents.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>strtok_r()</emphasis>, <emphasis>asctime_r()</emphasis>,
+ <emphasis>ctime_r()</emphasis>, <emphasis>gmtime_r()</emphasis>,
+ <emphasis>localtime_r()</emphasis> and
+ <emphasis>rand_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 [POSIX Section 9]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<para>
+<none>
+</para>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+struct group *getgrgid( gid_t gid );
+int getgrgid( gid_t gid, struct group *grp, char *buffer,
+ size_t bufsize, struct group **result );
+struct group *getgrname( const char *name );
+int getgrname_r( const char *name, struct group *grp,
+ char *buffer, size_t bufsize, struct group **result );
+struct passwd *getpwuid( uid_t uid );
+int getpwuid_r( uid_t uid, struct passwd *pwd,
+ char *buffer, size_t bufsize, struct passwd **result );
+struct passwd *getpwnam( const char *name );
+int getpwnam_r( const char *name, struct passwd *pwd,
+ char *buffer, size_t bufsize, struct passwd **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 [POSIX Section 10]</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 [POSIX Section 11]</title>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int sem_init(sem_t *sem, int pshared, unsigned int value);
+int sem_destroy(sem_t *sem);
+int sem_wait(sem_t *sem);
+int sem_trywait(sem_t *sem);
+int sem_post(sem_t *sem);
+int sem_getvalue(sem_t *sem, int *sval);
+int pthread_mutexattr_init( pthread_mutexattr_t *attr);
+int pthread_mutexattr_destroy( pthread_mutexattr_t *attr);
+int pthread_mutex_init(pthread_mutex_t *mutex,
+ const pthread_mutexattr_t *mutex_attr);
+int pthread_mutex_destroy(pthread_mutex_t *mutex);
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+int pthread_condattr_init(pthread_condattr_t *attr);
+int pthread_condattr_destroy(pthread_condattr_t *attr);
+int pthread_cond_init(pthread_cond_t *cond,
+ const pthread_condattr_t *attr);
+int pthread_cond_destroy(pthread_cond_t *cond);
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+int pthread_cond_wait(pthread_cond_t *cond,
+ pthread_mutex_t *mutex);
+int pthread_cond_timedwait(pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct timespec *abstime);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+sem_t *sem_open(const char *name, int oflag, ...); // TBA
+int sem_close(sem_t *sem); // TBA
+int sem_unlink(const char *name); // TBA
+int pthread_mutexattr_getpshared( const pthread_mutexattr_t *attr,
+ int *pshared );
+int pthread_mutexattr_setpshared( const pthread_mutexattr_t *attr,
+ int pshared );
+int pthread_condattr_getpshared( const pthread_condattr_t *attr,
+ int *pshared);
+int pthread_condattr_setpshared( const pthread_condattr_t *attr,
+ int pshared);</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The presence of semaphores is controlled by the
+ CYGPKG_POSIX_SEMAPHORES option. This in turn
+ causes the _POSIX_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_init()</emphasis> is not implemented,
+ its value is ignored.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Functions <emphasis>sem_open()</emphasis>,
+ <emphasis>sem_close()</emphasis> and
+ <emphasis>sem_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
+ _POSIX_THREAD_PRIO_INHERIT and
+ _POSIX_THREAD_PRIO_PROTECT
+ configuration options.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ {_POSIX_THREAD_PROCESS_SHARED} 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_mutexattr_getpshared()</emphasis>,
+ <emphasis>pthread_mutexattr_setpshared()</emphasis>,
+ <emphasis>pthread_condattr_getpshared()</emphasis> and
+ <emphasis>pthread_condattr_setpshared()</emphasis>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Condition variables do not become bound to a particular
+ mutex when
+ <emphasis>pthread_cond_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 [POSIX Section 12]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<para>
+<none>
+</para>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+int mlockall( int flags );
+int munlockall( void );
+int mlock( const void *addr, size_t len );
+int munlock( const void *addr, size_t len );
+void mmap( void *addr, size_t len, int prot, int flags,
+ int fd, off_t off );
+int munmap( void *addr, size_t len );
+int mprotect( const void *addr, size_t len, int prot );
+int msync( void *addr, size_t len, int flags );
+int shm_open( const char *name, int oflag, mode_t mode );
+int shm_unlink( const char *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 [POSIX Section 13]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int sched_yield(void);
+int sched_get_priority_max(int policy);
+int sched_get_priority_min(int policy);
+int sched_rr_get_interval(pid_t pid, struct timespec *t);
+int pthread_attr_setscope(pthread_attr_t *attr, int scope);
+int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);
+int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit);
+int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit);
+int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
+int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
+int pthread_attr_setschedparam( pthread_attr_t *attr, const struct sched_param *param);
+int pthread_attr_getschedparam( const pthread_attr_t *attr,
+ struct sched_param *param);
+int pthread_setschedparam(pthread_t thread, int policy,
+ const struct sched_param *param);
+int pthread_getschedparam(pthread_t thread, int *policy,
+ struct sched_param *param);
+int pthread_mutexattr_setprotocol( pthread_mutexattr_t *attr,
+ int protocol);
+int pthread_mutexattr_getprotocol( pthread_mutexattr_t *attr,
+ int *protocol);
+int pthread_mutexattr_setprioceiling( pthread_mutexattr_t *attr,
+ int prioceiling);
+int pthread_mutexattr_getprioceiling( pthread_mutexattr_t *attr,
+ int *prioceiling);
+int pthread_mutex_setprioceiling( pthread_mutex_t *mutex,
+ int prioceiling,
+ int *old_ceiling);
+int pthread_mutex_getprioceiling( pthread_mutex_t *mutex,
+ int *prioceiling);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<screen>
+int sched_setparam(pid_t pid, const struct sched_param *param);
+int sched_getparam(pid_t pid, struct sched_param *param);
+int sched_setscheduler(pid_t pid, int policy,
+ const struct sched_param *param);
+int sched_getscheduler(pid_t pid);
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The functions <emphasis>sched_setparam()</emphasis>,
+ <emphasis>sched_getparam()</emphasis>,
+ <emphasis>sched_setscheduler()</emphasis> and
+ <emphasis>sched_getscheduler()</emphasis> are present
+ but always return an error.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The scheduler policy <emphasis>SCHED_OTHER</emphasis> is
+ equivalent to <emphasis>SCHED_RR</emphasis>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Only <emphasis>PTHREAD_SCOPE_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_SCOPE_SYSTEM
+ inheritsched PTHREAD_INHERIT_SCHED
+ schedpolicy SCHED_OTHER
+ schedparam.sched 0
+ </screen>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Mutex priority inversion protection is controlled by a
+ number of kernel configuration options.
+ If CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_INHERIT
+ is defined then
+ {_POSIX_THREAD_PRIO_INHERIT}
+ will be defined and PTHREAD_PRIO_INHERIT may
+ be set as the protocol in a
+ <emphasis>pthread_mutexattr_t</emphasis>
+ object.
+ If CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
+ is defined then
+ {_POSIX_THREAD_PRIO_PROTECT}
+ will be defined and PTHREAD_PRIO_PROTECT may
+ be set as the protocol in a
+ <emphasis>pthread_mutexattr_t</emphasis> object.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The default attribute values set by
+ <emphasis>pthread_mutexattr_init()</emphasis>
+ is to set the protocol attribute to
+ PTHREAD_PRIO_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 [POSIX Section 14]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int clock_settime( clockid_t clock_id,
+const struct timespec *tp);
+int clock_gettime( clockid_t clock_id, struct timespec *tp);
+int clock_getres( clockid_t clock_id, struct timespec *tp);
+int timer_create( clockid_t clock_id, struct sigevent *evp,
+ timer_t *timer_id);
+int timer_delete( timer_t timer_id );
+int timer_settime( timer_t timerid, int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue );
+int timer_gettime( timer_t timerid, struct itimerspec *value );
+int timer_getoverrun( timer_t timerid );
+int nanosleep( const struct timespec *rqtp, struct timespec *rmtp);
+</screen>
+
+</sect2>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<para>
+<none>
+</para>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+<itemizedlist>
+ <listitem>
+ <para>
+ Currently <emphasis>timer_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_POSIX_TIMERS allows the timer support to be
+ enabled or disabled, and causes _POSIX_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 [POSIX Section 15]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+mqd_t mq_open( const char *name, int oflag, ... );
+int mq_close( mqd_t mqdes );
+int mq_unlink( const char *name );
+int mq_send( mqd_t mqdes, const char *msg_ptr,
+ size_t msg_len, unsigned int msg_prio );
+ssize_t mq_receive( mqd_t mqdes, char *msg_ptr,
+ size_t msg_len, unsigned int *msg_prio );
+int mq_setattr( mqd_t mqdes, const struct mq_attr *mqstat,
+ struct mq_attr *omqstat );
+int mq_getattr( mqd_t mqdes, struct mq_attr *mqstat );
+int mq_notify( mqd_t mqdes, const struct sigevent *notification );
+</screen>
+<para>From POSIX 1003.1d draft: </para>
+<screen>
+int mq_send( mqd_t mqdes, const char *msg_ptr,
+ size_t msg_len, unsigned int msg_prio,
+ const struct timespec *abs_timeout );
+ssize_t mq_receive( mqd_t mqdes, char *msg_ptr,
+ size_t msg_len, unsigned int *msg_prio,
+ const struct timespec *abs_timeout );
+</screen>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<para>
+<none>
+</para>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+<itemizedlist>
+ <listitem>
+ <para>
+ The presence of message queues is controlled by the
+ CYGPKG_POSIX_MQUEUES option. Setting this will
+ cause [_POSIX_MESSAGE_PASSING] 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 [POSIX Section 16]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int pthread_attr_init(pthread_attr_t *attr);
+int pthread_attr_destroy(pthread_attr_t *attr);
+int pthread_attr_setdetachstate(pthread_attr_t *attr,
+ int detachstate);
+int pthread_attr_getdetachstate(const pthread_attr_t *attr,
+ int *detachstate);
+int pthread_attr_setstackaddr(pthread_attr_t *attr,
+ void *stackaddr);
+int pthread_attr_getstackaddr(const pthread_attr_t *attr,
+ void **stackaddr);
+int pthread_attr_setstacksize(pthread_attr_t *attr,
+ size_t stacksize);
+int pthread_attr_getstacksize(const pthread_attr_t *attr,
+ size_t *stacksize);
+int pthread_create( pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *),
+ void *arg);
+pthread_t pthread_self( void );
+int pthread_equal(pthread_t thread1, pthread_t thread2);
+void pthread_exit(void *retval);
+int pthread_join(pthread_t thread, void **thread_return);
+int pthread_detach(pthread_t thread);
+int pthread_once(pthread_once_t *once_control,
+ void (*init_routine)(void));
+</screen>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+
+<para>
+<none>
+</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_CREATE_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_MEMALLOC_MALLOC_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_STACK_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_THREADS_MAX is supplied by
+ the CYGNUM_POSIX_PTHREAD_THREADS_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_POSIX_MAIN_DEFAULT_PRIORITY option.
+ </para>
+ </listitem>
+</itemizedlist>
+
+</sect2>
+</sect1>
+
+<!-- }}} -->
+<!-- {{{ Thread-Specific Data -->
+
+<sect1 id="posix-thread-specific-data">
+<title>Thread-Specific Data [POSIX Section 17]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int pthread_key_create(pthread_key_t *key,
+ void (*destructor)(void *));
+int pthread_setspecific(pthread_key_t key, const void *pointer);
+void *pthread_getspecific(pthread_key_t key);
+int pthread_key_delete(pthread_key_t key);
+</screen>
+
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<para>
+<none>
+</para>
+</sect2>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Notes</title>
+
+<itemizedlist>
+ <listitem>
+ <para>
+ The value of PTHREAD_DESTRUCTOR_ITERATIONS is
+ provided by the
+ CYGNUM_POSIX_PTHREAD_DESTRUCTOR_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_KEYS_MAX is provided
+ by the CYGNUM_POSIX_PTHREAD_KEYS_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 [POSIX Section 18]</title>
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Implemented</title>
+
+<screen>
+int pthread_cancel(pthread_t thread);
+int pthread_setcancelstate(int state, int *oldstate);
+int pthread_setcanceltype(int type, int *oldtype);
+void pthread_testcancel(void);
+void pthread_cleanup_push( void (*routine)(void *),
+ void *arg);
+void pthread_cleanup_pop( int execute);
+</screen>
+</sect2>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Functions Omitted</title>
+<para>
+<none>
+</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/O Functions</title>
+<screen>
+int ioctl( int fd, CYG_ADDRWORD com, CYG_ADDRWORD data );
+int select( int nfd, fd_set *in, fd_set *out, fd_set *ex, struct timeval *tv);
+</screen>
+</sect2>
+
+
+<!-- =================================================================== -->
+
+<sect2>
+<title>Socket Functions</title>
+<screen>
+int socket( int domain, int type, int protocol);
+int bind( int s, const struct sockaddr *sa, unsigned int len);
+int listen( int s, int len);
+int accept( int s, struct sockaddr *sa, socklen_t *addrlen);
+int connect( int s, const struct sockaddr *sa, socklen_t len);
+int getpeername( int s, struct sockaddr *sa, socklen_t *len);
+int getsockname( int s, struct sockaddr *sa, socklen_t *len);
+int setsockopt( int s, int level, int optname, const void *optval,
+ socklen_t optlen);
+int getsockopt( int s, int level, int optname, void *optval,
+ socklen_t *optlen);
+ssize_t recvmsg( int s, struct msghdr *msg, int flags);
+ssize_t recvfrom( int s, void *buf, size_t len, int flags,
+ struct sockaddr *from, socklen_t *fromlen);
+ssize_t recv( int s, void *buf, size_t len, int flags);
+ssize_t sendmsg( int s, const struct msghdr *msg, int flags);
+ssize_t sendto( int s, const void *buf, size_t len, int flags,
+ const struct sockaddr *to, socklen_t tolen);
+ssize_t send( int s, const void *buf, size_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>[Lewine]</bibliomisc>
+ <author>
+ <firstname>Donald</firstname>
+ <othername>A.</othername>
+ <surname>Lweine</surname>
+ </author>
+ <title>Posix Programmer’s Guide: Writing Portable Unix
+ Programs With the POSIX.1 Standard O’Reilly &
+ Associates; ISBN: 0937175730.</title></bibliomixed>
+
+ <bibliomixed>
+ <bibliomisc>[Lewis1]</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>[Lewis2]</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>[Nichols]</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’Reilly Nutshell)</title>
+ <publisher><publishername>O’Reilly & Associates</publishername>
+ </publisher>
+ <isbn>ISBN: 1565921151</isbn>
+ </bibliomixed>
+
+ <bibliomixed>
+ <bibliomisc>[Norton]</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>[POSIX]</bibliomisc>
+ <title>Portable Operating System Interface(POSIX) -
+Part 1: System Application Programming Interface (API)[C
+Language]</title>
+ <corpauthor>ISO/IEC 9945-1:1996, IEEE</corpauthor></bibliomixed>
+
+ <bibliomixed>
+ <bibliomisc>[SUS2]</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>
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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 */
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+/*========================================================================
+//
+// 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( ¬ifyme, (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 */
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+#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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+/*========================================================================
+//
+// 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 */
--- /dev/null
+/*========================================================================
+//
+// 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 */
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# 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."
+ }
+}
--- /dev/null
+# ====================================================================
+#
+# 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."
+ }
+}
--- /dev/null
+# ====================================================================
+#
+# 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."
+}
--- /dev/null
+# ====================================================================
+#
+# 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."
+}
--- /dev/null
+# ====================================================================
+#
+# 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."
+ }
+}
--- /dev/null
+# ====================================================================
+#
+# 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."
+}
--- /dev/null
+# ====================================================================
+#
+# 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."
+ }
+ }
+}
--- /dev/null
+# ====================================================================
+#
+# 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."
+}
--- /dev/null
+<!-- {{{ 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>µITRON</title>
+<CHAPTER id="compat-uitron-microitron-api">
+<TITLE><!-- <xref> -->µITRON API</TITLE>
+<SECT1 id="compat-uitron-introduction">
+<TITLE><!-- <index></index> -->Introduction to µITRON</TITLE>
+<PARA>The <!-- <index></index> -->µ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 µ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 µITRON specification exist.
+ In this release, <EMPHASIS>eCos</EMPHASIS> supports the
+ µITRON version 3.02 specification, with complete
+ “Standard functionality” (level S), plus many
+ “Extended” (level E) functions. The definitive
+ reference on µITRON is Dr. Sakamura’s book:
+ <CITETITLE>µ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> -->µITRON and <EMPHASIS>eCos</EMPHASIS></TITLE>
+<PARA>The <EMPHASIS>eCos</EMPHASIS> kernel implements the functionality
+used by the µITRON compatibility subsystem.
+The configuration of the kernel influences the behavior of µ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 µ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 µ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 µ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 µITRON
+compatibility layer, even though it only allows one task at each
+priority and as such is not µITRON
+compliant, but it supports only priority ordering of task queues.
+So which queueing scheme is supported is not really a property of
+the µITRON compatibility layer; it
+depends on the kernel. </PARA>
+<PARA>In this version of the µ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 “stops” 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 µITRON layer
+are dependent on its configuration and the configuration of other components
+that it uses. The µ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 µITRON
+compatibility layer is “Option: Return Error Codes for Bad Params”
+(
+<LITERAL>CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS</LITERAL>
+), which allows a lot of the error
+checking code in the µ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 µITRON
+functions which are implemented in this release. Note that all C
+and C++ source files should have the following <literal>#include</literal> statement: </PARA>
+<PROGRAMLISTING>#include <cyg/compat/uitron/uit_func.h></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->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->tskatr) are
+ignored; current versions of <EMPHASIS>eCos</EMPHASIS> do not need
+to know whether a task is written in assembler or C/C++ so
+long as the procedure call standard appropriate to the CPU is followed.</PARA>
+<PARA>Extended information (pk_ctsk->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
+“Static initializers”, and “Default stack size”.
+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
+µ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 “Return Error Codes for Bad
+Params”):</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 µITRON
+conformance and it queues tasks in FIFO order, so requests to create
+an object with priority queueing of tasks (<literal>pk_cxxx->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->exinf)
+is ignored. </PARA>
+<PARA>For semaphores, the initial semaphore count (pk_csem->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->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->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->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->mbxatr</LITERAL>
+ must be
+<LITERAL>TA_TFIFO + 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 “return” 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><cyg/compat/uitron/uit_ifnc.h></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 ‘i’ prefix)
+instead, and do not call any µ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
+µ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->mplsz) or the number of fixed-size
+blocks (pk_cmpf->mpfcnt) times the block size
+(pk_cmpf->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 µITRON conformance and
+it queues tasks in FIFO order, so requests to create an object with
+priority queueing of tasks (pk_cxxx->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->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->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->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
+“Option: Static initializers”.
+ In
+<FUNCTION>cre_mpl()</FUNCTION>
+
+<LITERAL>pk_cmpl->mplsz</LITERAL>
+ is the field of interest</PARA>
+</LISTITEM>
+<LISTITEM>
+<PARA>In
+<FUNCTION>cre_mpf()</FUNCTION>
+ the product of
+<LITERAL>pk_cmpf->blfsz</LITERAL>
+ and
+<LITERAL>pk_cmpf->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> -->µITRON Configuration FAQ</TITLE>
+<PARA><EMPHASIS>Q: How are µ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
+µ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,&foo)</FUNCTION>, and all will be well.
+</PARA>
+<PARA><EMPHASIS>Q: How are µ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> —
+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>
+— to create a semaphore initializer — and
+<LITERAL>CYG_UIT_SEMA_NOEXS</LITERAL>
+— to invoke a dummy initializer —
+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 µ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, &stack1, sizeof( stack1 )), \
+ CYG_UIT_TASK("worker 2" , 9, worktask, &stack2, sizeof( stack2 )), \
+ CYG_UIT_TASK("worker 3" , 9, worktask, &stack3, sizeof( stack3 )), \
+ CYG_UIT_TASK("low task" ,20, lowtask, &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 “main task” runs a routine
+called <FUNCTION>startup()</FUNCTION> at priority 8. Two
+“worker” tasks run both a priority 9, and a “low
+priority” 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 | &stack1 | CYGNUM...
+ 2 | Yes | worktask | 9 | &stack2 | CYGNUM...
+ 3 | Yes | worktask | 9 | &stack3 | CYGNUM...
+ 4 | Yes | lowtask | 20 | &stack4 | CYGNUM...
+--------+-----------+----------+----------+---------+----------
+</screen>
+<PARA><EMPHASIS>Q: How can I create µ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, &stack1, sizeof( stack1 ) ), \
+ CYG_UIT_TASK_NOEXS( "slave", &stack2, sizeof( stack2 ) ), \
+ CYG_UIT_TASK_NOEXS( "slave2", &stack3, sizeof( stack3 ) ), \
+ CYG_UIT_TASK_NOEXS( "slave3", &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–4 at
+runtime.
+</PARA>
+<screen>
+Task ID | Exists at | Function | Priority | Stack | Stack
+ number | startup | entry | | address | size
+--------+-----------+----------+----------+---------+----------
+ 1 | Yes | startup | 8 | &stack1 | CYGNUM...
+ 2 | No | N/A | N/A | &stack2 | CYGNUM...
+ 3 | No | N/A | N/A | &stack3 | CYGNUM...
+ 4 | No | N/A | N/A | &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 µ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 µ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, &stack1, CYGNUM_UITRON_STACK_SIZE ), \
+ CYG_UIT_TASK( "t2", 2, task2, &stack2, CYGNUM_UITRON_STACK_SIZE ), \
+ CYG_UIT_TASK( "t3", 3, task3, &stack3, CYGNUM_UITRON_STACK_SIZE ), \
+ CYG_UIT_TASK( "t4", 4, task4, &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, &stack1, sizeof( stack1 ) ), \
+ CYG_UIT_TASK( "t2", 2, task2, &stack2, sizeof( stack2 ) ), \
+ CYG_UIT_TASK( "t3", 3, task3, &stack3, sizeof( stack3 ) ), \
+ CYG_UIT_TASK( "t4", 4, task4, &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, &stack1, sizeof( stack1 ) ), \
+ CYG_UIT_TASK( "t2", 2, task2, &stack2, sizeof( stack2 ) ), \
+ CYG_UIT_TASK( "t3", 3, task3, &stack3, sizeof( stack3 ) ), \
+ CYG_UIT_TASK( "t4", 4, task4, &stack4, sizeof( stack4 ) )
+</PROGRAMLISTING>
+</SECT1>
+</CHAPTER>
+</part>
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+//===========================================================================
+//
+// 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
--- /dev/null
+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####
+//===========================================================================
--- /dev/null
+# ====================================================================
+#
+# 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,$^))
+ }
+ }
+}
--- /dev/null
+===========================================================================
+#####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.
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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 */
--- /dev/null
+//==========================================================================
+//
+// 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;
+}
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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 = ®s_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 = ®s_array[bsp_regbyte(Rs)];
+ unsigned char *Rm_ptr = ®s_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 = ®s_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 = ®s_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 = ®s_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 = ®s_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 = ®s_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 = ®s_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 = ®s_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;
+}
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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
+}
+
--- /dev/null
+//==========================================================================
+//
+// 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);
+ }
+}
--- /dev/null
+//==========================================================================
+//
+// 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);
+}
+
+
--- /dev/null
+//==========================================================================
+//
+// 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) */
+
--- /dev/null
+#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__
+
+
--- /dev/null
+//==========================================================================
+//
+// 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);
+}
+
+
--- /dev/null
+//==========================================================================
+//
+// 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);
+}
+
+
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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;
+}
--- /dev/null
+//==========================================================================
+//
+// 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;
+}
+
+
--- /dev/null
+//==========================================================================
+//
+// 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);
+}
+
+
+
--- /dev/null
+//==========================================================================
+//
+// 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;
+
+
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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);
+}
+
+
--- /dev/null
+//==========================================================================
+//
+// 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;
+}
+
+
--- /dev/null
+/* 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
--- /dev/null
+//==========================================================================
+//
+// 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;
+}
+
+
+
--- /dev/null
+//==========================================================================
+//
+// 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:
+}
+
+
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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.
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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.
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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;
+}
--- /dev/null
+//==========================================================================
+//
+// 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)
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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));
+}
--- /dev/null
+//==========================================================================
+//
+// 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
+}
+
+
+
--- /dev/null
+//==========================================================================
+//
+// 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);
+ }
+}
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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);
+}
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+#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__
--- /dev/null
+//==========================================================================
+//
+// 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);
+}
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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;
+}
+
+
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+#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);
--- /dev/null
+//==========================================================================
+//
+// 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
--- /dev/null
+//==========================================================================
+//
+// 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));
+}
+
+
+