From 41ab696625ec33c00b1788f200bc6e25edf30c8d Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 12 Jun 2000 20:06:59 +0000 Subject: Patch from John Cotton , Charles-Antoine Gauthier , and Darlene A. Stewart to add support for a number of very significant things: + BSPs for many variations on the Motorola MBX8xx board series + Cache Manager including initial support for m68040 and PowerPC + Rework of mpc8xx libcpu code so all mpc8xx CPUs now use same code base. + Rework of eth_comm BSP to utiltize above. John reports this works on the 821 and 860 --- c/src/tests/libffi/Makefile.am | 13 + c/src/tests/libffi/configure.in | 46 ++ c/src/tests/libffi/ffitest/Makefile.am | 43 ++ c/src/tests/libffi/ffitest/ffitest.c | 735 +++++++++++++++++++++ c/src/tests/libffi/ffitest/init.c | 35 + c/src/tests/libffi/ffitest/system.h | 36 + c/src/tests/libffi/libffi.am | 11 + c/src/tests/sptests/threaditerate/Makefile.am | 43 ++ c/src/tests/sptests/threaditerate/init.c | 202 ++++++ c/src/tests/sptests/threaditerate/itrontask.c | 52 ++ c/src/tests/sptests/threaditerate/pthread.c | 46 ++ c/src/tests/sptests/threaditerate/rtemstask.c | 47 ++ c/src/tests/sptests/threaditerate/system.h | 98 +++ c/src/tests/sptests/threaditerate/threadinfo.c | 178 +++++ .../tests/sptests/threaditerate/threaditerate.scn | 205 ++++++ make/custom/mbx821_001.cfg | 12 + make/custom/mbx860_002.cfg | 12 + make/custom/mbx8xx.cfg | 196 ++++++ 18 files changed, 2010 insertions(+) create mode 100644 c/src/tests/libffi/Makefile.am create mode 100644 c/src/tests/libffi/configure.in create mode 100644 c/src/tests/libffi/ffitest/Makefile.am create mode 100644 c/src/tests/libffi/ffitest/ffitest.c create mode 100644 c/src/tests/libffi/ffitest/init.c create mode 100644 c/src/tests/libffi/ffitest/system.h create mode 100644 c/src/tests/libffi/libffi.am create mode 100644 c/src/tests/sptests/threaditerate/Makefile.am create mode 100644 c/src/tests/sptests/threaditerate/init.c create mode 100644 c/src/tests/sptests/threaditerate/itrontask.c create mode 100644 c/src/tests/sptests/threaditerate/pthread.c create mode 100644 c/src/tests/sptests/threaditerate/rtemstask.c create mode 100644 c/src/tests/sptests/threaditerate/system.h create mode 100644 c/src/tests/sptests/threaditerate/threadinfo.c create mode 100644 c/src/tests/sptests/threaditerate/threaditerate.scn create mode 100644 make/custom/mbx821_001.cfg create mode 100644 make/custom/mbx860_002.cfg create mode 100644 make/custom/mbx8xx.cfg diff --git a/c/src/tests/libffi/Makefile.am b/c/src/tests/libffi/Makefile.am new file mode 100644 index 0000000000..9710c7d2dd --- /dev/null +++ b/c/src/tests/libffi/Makefile.am @@ -0,0 +1,13 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 +ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal + +SUBDIRS = ffitest + +EXTRA_DIST = libffi.am + +include $(top_srcdir)/../../../../automake/subdirs.am +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/tests/libffi/configure.in b/c/src/tests/libffi/configure.in new file mode 100644 index 0000000000..760a4bd771 --- /dev/null +++ b/c/src/tests/libffi/configure.in @@ -0,0 +1,46 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl $Id$ + +AC_PREREQ(2.13) +AC_INIT(ffitest) +RTEMS_TOP(../../../..) +AC_CONFIG_AUX_DIR(../../../..) + +RTEMS_CANONICAL_TARGET_CPU + +AM_INIT_AUTOMAKE(rtems-c-src-tests-libffi,$RTEMS_VERSION,no) +AM_MAINTAINER_MODE + +RTEMS_ENABLE_INLINES +RTEMS_ENABLE_CXX +RTEMS_ENABLE_GCC28 +RTEMS_ENABLE_BARE + +RTEMS_ENV_RTEMSBSP +RTEMS_CHECK_CPU +RTEMS_CANONICAL_HOST + +RTEMS_PROJECT_ROOT + +RTEMS_PROG_CC_FOR_TARGET + +if test "$RTEMS_HAS_CPLUSPLUS" = "yes"; then + RTEMS_PROG_CXX_FOR_TARGET +fi + +RTEMS_CANONICALIZE_TOOLS + +RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP) +RTEMS_CHECK_CXX(RTEMS_BSP) + +AC_SUBST(BARE_CPU_CFLAGS) +AC_SUBST(BARE_CPU_MODEL) + +AM_CONDITIONAL(HAS_CXX,test "$HAS_CPLUSPLUS" = "yes") + +# Explicitly list all Makefiles here +AC_OUTPUT( +Makefile +ffitest/Makefile +) diff --git a/c/src/tests/libffi/ffitest/Makefile.am b/c/src/tests/libffi/ffitest/Makefile.am new file mode 100644 index 0000000000..8ea12d706e --- /dev/null +++ b/c/src/tests/libffi/ffitest/Makefile.am @@ -0,0 +1,43 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 +TEST = ffitest + +MANAGERS = io + +C_FILES = init.c ffitest.c +C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o) + +H_FILES = system.h +noinst_HEADERS = $(H_FILES) + +DOCTYPES = scn +DOCS = $(DOCTYPES:%=$(TEST).%) + +SRCS = $(DOCS) $(C_FILES) $(H_FILES) +OBJS = $(C_O_FILES) + +PRINT_SRCS = $(DOCS) + +PGM = ${ARCH}/$(TEST).exe + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/leaf.cfg +include $(top_srcdir)/libffi.am + +# +# (OPTIONAL) Add local stuff here using += +# + +LD_LIBS += -lffi + +${PGM}: $(OBJS) $(LINK_FILES) + $(make-exe) + +all: ${ARCH} $(TMPINSTALL_FILES) + +EXTRA_DIST = $(C_FILES) $(DOCS) + +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/tests/libffi/ffitest/ffitest.c b/c/src/tests/libffi/ffitest/ffitest.c new file mode 100644 index 0000000000..abc09a97b7 --- /dev/null +++ b/c/src/tests/libffi/ffitest/ffitest.c @@ -0,0 +1,735 @@ +/* ----------------------------------------------------------------------- + ffitest.c - Copyright (c) 1996, 1997, 1998 Cygnus Solutions + + $Id$ + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include + +/* This is lame. Long double support is barely there under SunOS 4.x */ +#if defined(SPARC) && (SIZEOF_LONG_DOUBLE != 16) +#define BROKEN_LONG_DOUBLE +#endif + +#define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0 + +static int fail(char *file, int line) +{ + fprintf(stderr, "Test failure: %s line %d\n", file, line); + exit(EXIT_FAILURE); + /*@notreached@*/ + return 0; +} + +#define MAX_ARGS 256 + +static size_t my_strlen(char *s) +{ + return (strlen(s)); +} + +static int promotion(signed char sc, signed short ss, + unsigned char uc, unsigned short us) +{ + int r = (int) sc + (int) ss + (int) uc + (int) us; + + return r; +} + +static signed char return_sc(signed char sc) +{ + return sc; +} + +static unsigned char return_uc(unsigned char uc) +{ + return uc; +} + +static long long return_ll(long long ll) +{ + return ll; +} + +static int floating(int a, float b, double c, long double d, int e) +{ + int i; + +#if 0 + /* This is ifdef'd out for now. long double support under SunOS/gcc + is pretty much non-existent. You'll get the odd bus error in library + routines like printf(). */ + printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e); +#endif + + i = (int) ((float)a/b + ((float)c/(float)d)); + + return i; +} + +static float many(float f1, + float f2, + float f3, + float f4, + float f5, + float f6, + float f7, + float f8, + float f9, + float f10, + float f11, + float f12, + float f13) +{ +#if 0 + printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", + (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, + (double) f6, (double) f7, (double) f8, (double) f9, (double) f10, + (double) f11, (double) f12, (double) f13); +#endif + + return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); +} + +static double dblit(float f) +{ + return f/3.0; +} + +static long double ldblit(float f) +{ + return (long double) (((long double) f)/ (long double) 3.0); +} + +typedef struct +{ + unsigned char uc; + double d; + unsigned int ui; +} test_structure_1; + +typedef struct +{ + double d1; + double d2; +} test_structure_2; + +typedef struct +{ + int si; +} test_structure_3; + +typedef struct +{ + unsigned ui1; + unsigned ui2; + unsigned ui3; +} test_structure_4; + +typedef struct +{ + char c1; + char c2; +} test_structure_5; + +static test_structure_1 struct1(test_structure_1 ts) +{ + /*@-type@*/ + ts.uc++; + /*@=type@*/ + ts.d--; + ts.ui++; + + return ts; +} + +static test_structure_2 struct2(test_structure_2 ts) +{ + ts.d1--; + ts.d2--; + + return ts; +} + +static test_structure_3 struct3(test_structure_3 ts) +{ + ts.si = -(ts.si*2); + + return ts; +} + +static test_structure_4 struct4(test_structure_4 ts) +{ + ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; + + return ts; +} + +static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2) +{ + ts1.c1 += ts2.c1; + ts1.c2 -= ts2.c2; + + return ts1; +} + +/* Take an int and a float argument, together with int userdata, and */ +/* return the sum. */ +static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata) +{ + *(int*)resp = + *(int *)args[0] + (int)(*(float *)args[1]) + (int)(long)userdata; +} + +typedef int (*closure_test_type)(int, float); + +int ffi_main( void ) +{ + ffi_cif cif; + ffi_type *args[MAX_ARGS]; + void *values[MAX_ARGS]; + char *s; + signed char sc; + unsigned char uc; + signed short ss; + unsigned short us; + unsigned long ul; + long long ll; + float f; + double d; + long double ld; + signed int si1; + signed int si2; + +#if defined(ALPHA) || defined(IA64) || defined(SPARC64) || (defined(MIPS) && (_MIPS_SIM == _ABIN32)) + long long rint; +#else + int rint; +#endif + long long rlonglong; + + ffi_type ts1_type; + ffi_type ts2_type; + ffi_type ts3_type; + ffi_type ts4_type; + ffi_type ts5_type; + ffi_type *ts1_type_elements[4]; + ffi_type *ts2_type_elements[3]; + ffi_type *ts3_type_elements[2]; + ffi_type *ts4_type_elements[4]; + ffi_type *ts5_type_elements[3]; + + ts1_type.size = 0; + ts1_type.alignment = 0; + ts1_type.type = FFI_TYPE_STRUCT; + + ts2_type.size = 0; + ts2_type.alignment = 0; + ts2_type.type = FFI_TYPE_STRUCT; + + ts3_type.size = 0; + ts3_type.alignment = 0; + ts3_type.type = FFI_TYPE_STRUCT; + + ts4_type.size = 0; + ts4_type.alignment = 0; + ts4_type.type = FFI_TYPE_STRUCT; + + ts5_type.size = 0; + ts5_type.alignment = 0; + ts5_type.type = FFI_TYPE_STRUCT; + + /*@-immediatetrans@*/ + ts1_type.elements = ts1_type_elements; + ts2_type.elements = ts2_type_elements; + ts3_type.elements = ts3_type_elements; + ts4_type.elements = ts4_type_elements; + ts5_type.elements = ts5_type_elements; + /*@=immediatetrans@*/ + + ts1_type_elements[0] = &ffi_type_uchar; + ts1_type_elements[1] = &ffi_type_double; + ts1_type_elements[2] = &ffi_type_uint; + ts1_type_elements[3] = NULL; + + ts2_type_elements[0] = &ffi_type_double; + ts2_type_elements[1] = &ffi_type_double; + ts2_type_elements[2] = NULL; + + ts3_type_elements[0] = &ffi_type_sint; + ts3_type_elements[1] = NULL; + + ts4_type_elements[0] = &ffi_type_uint; + ts4_type_elements[1] = &ffi_type_uint; + ts4_type_elements[2] = &ffi_type_uint; + ts4_type_elements[3] = NULL; + + ts5_type_elements[0] = &ffi_type_schar; + ts5_type_elements[1] = &ffi_type_schar; + ts5_type_elements[2] = NULL; + + ul = 0; + + /* return value tests */ + { +#if defined(MIPS) /* || defined(ARM) */ + puts ("long long tests not run. This is a known bug on this architecture."); +#else + args[0] = &ffi_type_sint64; + values[0] = ≪ + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint64, args) == FFI_OK); + + for (ll = 0LL; ll < 100LL; ll++) + { + ul++; + ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); + CHECK(rlonglong == ll); + } + + for (ll = 55555555555000LL; ll < 55555555555100LL; ll++) + { + ul++; + ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); + CHECK(rlonglong == ll); + } +#endif + + args[0] = &ffi_type_schar; + values[0] = ≻ + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_schar, args) == FFI_OK); + + for (sc = (signed char) -127; + sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/) + { + ul++; + ffi_call(&cif, FFI_FN(return_sc), &rint, values); + CHECK(rint == (int) sc); + } + + args[0] = &ffi_type_uchar; + values[0] = &uc; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_uchar, args) == FFI_OK); + + for (uc = (unsigned char) '\x00'; + uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/) + { + ul++; + ffi_call(&cif, FFI_FN(return_uc), &rint, values); + CHECK(rint == (signed int) uc); + } + + printf("%lu return value tests run\n", ul); + } + +#ifdef BROKEN_LONG_DOUBLE + printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n"); +#else + /* float arg tests */ + { + args[0] = &ffi_type_float; + values[0] = &f; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_longdouble, args) == FFI_OK); + + f = 3.14159; + +#if 0 + /* This is ifdef'd out for now. long double support under SunOS/gcc + is pretty much non-existent. You'll get the odd bus error in library + routines like printf(). */ + printf ("%Lf\n", ldblit(f)); +#endif + ld = 666; + ffi_call(&cif, FFI_FN(ldblit), &ld, values); + +#if 0 + /* This is ifdef'd out for now. long double support under SunOS/gcc + is pretty much non-existent. You'll get the odd bus error in library + routines like printf(). */ + printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); +#endif + + /* These are not always the same!! Check for a reasonable delta */ + /*@-realcompare@*/ + if (ld - ldblit(f) < LDBL_EPSILON) + /*@=realcompare@*/ + puts("long double return value tests ok!"); + else + CHECK(0); + } + + /* float arg tests */ + { + args[0] = &ffi_type_sint; + values[0] = &si1; + args[1] = &ffi_type_float; + values[1] = &f; + args[2] = &ffi_type_double; + values[2] = &d; + args[3] = &ffi_type_longdouble; + values[3] = &ld; + args[4] = &ffi_type_sint; + values[4] = &si2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5, + &ffi_type_sint, args) == FFI_OK); + + si1 = 6; + f = 3.14159; + d = (double)1.0/(double)3.0; + ld = 2.71828182846L; + si2 = 10; + + floating (si1, f, d, ld, si2); + + ffi_call(&cif, FFI_FN(floating), &rint, values); + + printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2)); + + CHECK(rint == floating(si1, f, d, ld, si2)); + + printf("float arg tests ok!\n"); + } +#endif + + /* strlen tests */ + { + args[0] = &ffi_type_pointer; + values[0] = (void*) &s; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_sint, args) == FFI_OK); + + s = "a"; + ffi_call(&cif, FFI_FN(my_strlen), &rint, values); + CHECK(rint == 1); + + s = "1234567"; + ffi_call(&cif, FFI_FN(my_strlen), &rint, values); + CHECK(rint == 7); + + s = "1234567890123456789012345"; + ffi_call(&cif, FFI_FN(my_strlen), &rint, values); + CHECK(rint == 25); + + printf("strlen tests passed\n"); + } + + /* float arg tests */ + { + args[0] = &ffi_type_float; + values[0] = &f; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ffi_type_double, args) == FFI_OK); + + f = 3.14159; + + ffi_call(&cif, FFI_FN(dblit), &d, values); + + /* These are not always the same!! Check for a reasonable delta */ + /*@-realcompare@*/ + CHECK(d - dblit(f) < DBL_EPSILON); + /*@=realcompare@*/ + + printf("double return value tests ok!\n"); + } + + /* many arg tests */ + { + float ff; + float fa[13]; + + for (ul = 0; ul < 13; ul++) + { + args[ul] = &ffi_type_float; + values[ul] = &fa[ul]; + fa[ul] = (float) ul; + } + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, + &ffi_type_float, args) == FFI_OK); + + /*@-usedef@*/ + ff = many(fa[0], fa[1], + fa[2], fa[3], + fa[4], fa[5], + fa[6], fa[7], + fa[8], fa[9], + fa[10],fa[11],fa[12]); + /*@=usedef@*/ + + ffi_call(&cif, FFI_FN(many), &f, values); + + /*@-realcompare@*/ + if (f - ff < FLT_EPSILON) + /*@=realcompare@*/ + printf("many arg tests ok!\n"); + else +#ifdef POWERPC + printf("many arg tests failed! This is a gcc bug.\n"); +#else + CHECK(0); +#endif + } + + /* promotion tests */ + { + args[0] = &ffi_type_schar; + args[1] = &ffi_type_sshort; + args[2] = &ffi_type_uchar; + args[3] = &ffi_type_ushort; + values[0] = ≻ + values[1] = &ss; + values[2] = &uc; + values[3] = &us; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, + &ffi_type_sint, args) == FFI_OK); + + us = 0; + ul = 0; + + for (sc = (signed char) -127; + sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/) + for (ss = -30000; ss <= 30000; ss += 10000) + for (uc = (unsigned char) 0; + uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/) + for (us = 0; us <= 60000; us += 10000) + { + ul++; + ffi_call(&cif, FFI_FN(promotion), &rint, values); + CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us); + } + printf("%lu promotion tests run\n", ul); + } + + /* struct tests */ + { + test_structure_1 ts1_arg; + /* This is a hack to get a properly aligned result buffer */ + test_structure_1 *ts1_result = + (test_structure_1 *) malloc (sizeof(test_structure_1)); + if (! ts1_result ) + rtems_panic("Could not get memory for struct 1 result."); + args[0] = &ts1_type; + values[0] = &ts1_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ts1_type, args) == FFI_OK); + + ts1_arg.uc = '\x01'; + ts1_arg.d = 3.14159; + ts1_arg.ui = 555; + + ffi_call(&cif, FFI_FN(struct1), ts1_result, values); + + CHECK(ts1_result->ui == 556); + CHECK(ts1_result->d == 3.14159 - 1); + + puts ("structure test 1 ok!\n"); + + free (ts1_result); + } + + /* struct tests */ + { + test_structure_2 ts2_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_2 *ts2_result = + (test_structure_2 *) malloc (sizeof(test_structure_2)); + + args[0] = &ts2_type; + values[0] = &ts2_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ts2_type, args) == FFI_OK); + + ts2_arg.d1 = 5.55; + ts2_arg.d2 = 6.66; + + printf ("%g\n", ts2_result->d1); + printf ("%g\n", ts2_result->d2); + + ffi_call(&cif, FFI_FN(struct2), ts2_result, values); + + printf ("%g\n", ts2_result->d1); + printf ("%g\n", ts2_result->d2); + + CHECK(ts2_result->d1 == 5.55 - 1); + CHECK(ts2_result->d2 == 6.66 - 1); + + printf("structure test 2 ok!\n"); + + free (ts2_result); + } + + /* struct tests */ + { + int compare_value; + test_structure_3 ts3_arg; + test_structure_3 *ts3_result = + (test_structure_3 *) malloc (sizeof(test_structure_3)); + + args[0] = &ts3_type; + values[0] = &ts3_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ts3_type, args) == FFI_OK); + + ts3_arg.si = -123; + compare_value = ts3_arg.si; + + ffi_call(&cif, FFI_FN(struct3), ts3_result, values); + + printf ("%d %d\n", ts3_result->si, -(compare_value*2)); + + if (ts3_result->si == -(ts3_arg.si*2)) + puts ("structure test 3 ok!"); + else + { + puts ("Structure test 3 found structure passing bug."); + puts (" Current versions of GCC are not 100% compliant with the"); + puts (" n32 ABI. There is a known problem related to passing"); + puts (" small structures. Send a bug report to the gcc maintainers."); + } + + free (ts3_result); + } + + /* struct tests */ + { + test_structure_4 ts4_arg; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_4 *ts4_result = + (test_structure_4 *) malloc (sizeof(test_structure_4)); + + args[0] = &ts4_type; + values[0] = &ts4_arg; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + &ts4_type, args) == FFI_OK); + + ts4_arg.ui1 = 2; + ts4_arg.ui2 = 3; + ts4_arg.ui3 = 4; + + ffi_call (&cif, FFI_FN(struct4), ts4_result, values); + + if (ts4_result->ui3 == 2U * 3U * 4U) + puts ("structure test 4 ok!"); + else + puts ("Structure test 4 found GCC's structure passing bug."); + + free (ts4_result); + } + + /* struct tests */ + { + test_structure_5 ts5_arg1, ts5_arg2; + + /* This is a hack to get a properly aligned result buffer */ + test_structure_5 *ts5_result = + (test_structure_5 *) malloc (sizeof(test_structure_5)); + + args[0] = &ts5_type; + args[1] = &ts5_type; + values[0] = &ts5_arg1; + values[1] = &ts5_arg2; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ts5_type, args) == FFI_OK); + + ts5_arg1.c1 = 2; + ts5_arg1.c2 = 6; + ts5_arg2.c1 = 5; + ts5_arg2.c2 = 3; + + ffi_call (&cif, FFI_FN(struct5), ts5_result, values); + + if (ts5_result->c1 == 7 + && ts5_result->c2 == 3) + puts ("structure test 5 ok!"); + else + puts ("Structure test 5 found GCC's structure passing bug."); + + free (ts5_result); + } + +# if FFI_CLOSURES + /* A simple closure test */ + { + ffi_closure cl; + ffi_type * cl_arg_types[3]; + + cl_arg_types[0] = &ffi_type_sint; + cl_arg_types[1] = &ffi_type_float; + cl_arg_types[2] = NULL; + + /* Initialize the cif */ + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, + &ffi_type_sint, cl_arg_types) == FFI_OK); + + CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn, + (void *) 3 /* userdata */) + == FFI_OK); + CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6); + } +# endif + + /* If we arrived here, all is good */ + (void) puts("\nLooks good. No surprises.\n"); + + /*@-compdestroy@*/ + + return 0; +} + diff --git a/c/src/tests/libffi/ffitest/init.c b/c/src/tests/libffi/ffitest/init.c new file mode 100644 index 0000000000..30086c51c2 --- /dev/null +++ b/c/src/tests/libffi/ffitest/init.c @@ -0,0 +1,35 @@ +/* Init + * + * This routine is the initialization task for this test program. + * It is called from init_exec and has the responsibility for creating + * and starting the tasks that make up the test. If the time of day + * clock is required for the test, it should also be set to a known + * value by this function. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + */ + +#define TEST_INIT +#include "system.h" + +extern int ffi_main ( void ); + +rtems_task Init( + rtems_task_argument ignored +) +{ + printf( "\n\n*** LIBFFI TEST ***\n" ); + ffi_main(); + printf( "*** END OF LIBFFI TEST ***\n" ); + exit( 0 ); +} \ No newline at end of file diff --git a/c/src/tests/libffi/ffitest/system.h b/c/src/tests/libffi/ffitest/system.h new file mode 100644 index 0000000000..45163f3596 --- /dev/null +++ b/c/src/tests/libffi/ffitest/system.h @@ -0,0 +1,36 @@ +/* system.h + * + * This include file contains information that is included in every + * function in the test set. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include + +/* functions */ + +rtems_task Init( + rtems_task_argument argument +); + +/* configuration information */ + +#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + + +#include + +/* global variables */ + +TEST_EXTERN rtems_id Global_variable; /* example global variable */ + +/* end of include file */ diff --git a/c/src/tests/libffi/libffi.am b/c/src/tests/libffi/libffi.am new file mode 100644 index 0000000000..577bac9fd2 --- /dev/null +++ b/c/src/tests/libffi/libffi.am @@ -0,0 +1,11 @@ +project_bspdir=$(PROJECT_ROOT)/@RTEMS_BSP@ + +$(project_bspdir)/tests: + @$(mkinstalldirs) $@ + +$(project_bspdir)/tests/$(TEST)$(LIB_VARIANT).exe: $(PGM) + $(INSTALL_PROGRAM) $< $@ + +TMPINSTALL_FILES += \ +$(project_bspdir)/tests \ +$(project_bspdir)/tests/$(TEST)$(LIB_VARIANT).exe diff --git a/c/src/tests/sptests/threaditerate/Makefile.am b/c/src/tests/sptests/threaditerate/Makefile.am new file mode 100644 index 0000000000..b52b949e2c --- /dev/null +++ b/c/src/tests/sptests/threaditerate/Makefile.am @@ -0,0 +1,43 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 +TEST = threaditerate + +MANAGERS = all + +C_FILES = init.c threadinfo.c rtemstask.c pthread.c itron_task.c +C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o) + +H_FILES = system.h +noinst_HEADERS =$(H_FILES) + +DOCTYPES = scn doc +DOCS = $(DOCTYPES:%=$(TEST).%) + +SRCS = $(C_FILES) $(H_FILES) +OBJS = $(C_O_FILES) + +PRINT_SRCS = $(DOCS) + +PGM = ${ARCH}/$(TEST).exe + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(RTEMS_ROOT)/make/leaf.cfg +include $(top_srcdir)/sptests.am + +# +# (OPTIONAL) Add local stuff here using += +# + +AM_CPPFLAGS = -I$(top_srcdir)/../psxtests/include + +${PGM}: $(OBJS) $(LINK_FILES) + $(make-exe) + +all: $(ARCH) $(TMPINSTALL_FILES) + +EXTRA_DIST = $(C_FILES) $(DOCS) + +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/tests/sptests/threaditerate/init.c b/c/src/tests/sptests/threaditerate/init.c new file mode 100644 index 0000000000..58743986af --- /dev/null +++ b/c/src/tests/sptests/threaditerate/init.c @@ -0,0 +1,202 @@ +/* Init + * + * This routine is the initialization task for this test program. + * It is a user initialization task and has the responsibility for creating + * and starting the tasks that make up the test. If the time of day + * clock is required for the test, it should also be set to a known + * value by this function. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#define TEST_INIT +#include "system.h" + +rtems_task Init( + rtems_task_argument argument +) +{ + rtems_time_of_day time; + rtems_status_code rtems_status; + +#ifdef RTEMS_POSIX_API + int posix_status; +#endif + +#ifdef RTEMS_ITRON_API + ER itron_status; + T_CTSK pk_ctsk; +#endif + + puts( "\n\n*** Thread Iteration Test ***" ); + + build_time( &time, 12, 31, 2000, 9, 0, 0, 0 ); + rtems_status = rtems_clock_set( &time ); + directive_failed( rtems_status, "rtems_clock_set" ); + + Task_name[ 1 ] = rtems_build_name( 'T', 'A', '1', ' ' ); + Task_name[ 2 ] = rtems_build_name( 'T', 'A', '2', ' ' ); + Task_name[ 3 ] = rtems_build_name( 'T', 'A', '3', ' ' ); + + rtems_status = rtems_task_create( + Task_name[ 1 ], + 1, + RTEMS_MINIMUM_STACK_SIZE * 2, + RTEMS_INTERRUPT_LEVEL(31), + RTEMS_DEFAULT_ATTRIBUTES, + &Task_id[ 1 ] + ); + directive_failed( rtems_status, "rtems_task_create of TA1" ); + + rtems_status = rtems_task_create( + Task_name[ 2 ], + 1, + RTEMS_MINIMUM_STACK_SIZE * 2, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &Task_id[ 2 ] + ); + directive_failed( rtems_status, "rtems_task_create of TA2" ); + + rtems_status = rtems_task_create( + Task_name[ 3 ], + 1, + RTEMS_MINIMUM_STACK_SIZE * 3, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &Task_id[ 3 ] + ); + directive_failed( rtems_status, "rtems_task_create of TA3" ); + + rtems_status = rtems_task_start( Task_id[ 1 ], RTEMS_task_1_through_3, 0 ); + if ( rtems_status == RTEMS_SUCCESSFUL ) + printf("Created and started an RTEMS task with id = 0x%08x\n", Task_id[1] ); + else + directive_failed( rtems_status, "rtems_task_start of TA1" ); + + rtems_status = rtems_task_start( Task_id[ 2 ], RTEMS_task_1_through_3, 0 ); + if ( rtems_status == RTEMS_SUCCESSFUL ) + printf("Created and started an RTEMS task with id = 0x%08x\n", Task_id[2] ); + else + directive_failed( rtems_status, "rtems_task_start of TA2" ); + + rtems_status = rtems_task_start( Task_id[ 3 ], RTEMS_task_1_through_3, 0 ); + if ( rtems_status == RTEMS_SUCCESSFUL ) + printf("Created and started an RTEMS task with id = 0x%08x\n", Task_id[3] ); + else + directive_failed( rtems_status, "rtems_task_start of TA3" ); + +#ifdef RTEMS_POSIX_API + posix_status = pthread_create( &pthread_id[0], NULL, pthread_1_through_3, NULL ); + if ( !posix_status ) + printf("Created and started a pthread with id = 0x%08x\n", pthread_id[0] ); + else + assert( !posix_status ); + + posix_status = pthread_create( &pthread_id[1], NULL, pthread_1_through_3, NULL ); + if ( !posix_status ) + printf("Created and started a pthread with id = 0x%08x\n", pthread_id[1] ); + else + assert( !posix_status ); + + posix_status = pthread_create( &pthread_id[2], NULL, pthread_1_through_3, NULL ); + if ( !posix_status ) + printf("Created and started a pthread with id = 0x%08x\n", pthread_id[2] ); + else + assert( !posix_status ); + +#endif + +#ifdef RTEMS_ITRON_API + +#define ITRON_GET_TASK_ID(_index) \ + _ITRON_Task_Information.local_table[_index]->id + + pk_ctsk.exinf = NULL; + pk_ctsk.tskatr = TA_HLNG; + pk_ctsk.itskpri = 1; + pk_ctsk.task = ITRON_task_2_through_4; + pk_ctsk.stksz = RTEMS_MINIMUM_STACK_SIZE * 2; + + itron_status = cre_tsk( 2, &pk_ctsk ); + directive_failed( itron_status, "cre_tsk of task" ); + + pk_ctsk.stksz = RTEMS_MINIMUM_STACK_SIZE * 2; + itron_status = cre_tsk( 3, &pk_ctsk ); + directive_failed( itron_status, "cre_tsk of TA2" ); + + pk_ctsk.stksz = RTEMS_MINIMUM_STACK_SIZE * 3; + itron_status = cre_tsk( 4, &pk_ctsk ); + directive_failed( itron_status, "cre_tsk of TA3" ); + + itron_status = sta_tsk( 2, 0 ); + if ( !itron_status ) + printf("Created and started an ITRON task with id = 0x%08x\n", ITRON_GET_TASK_ID( 2 ) ); + else + directive_failed( itron_status, "sta_tsk of ITRON task 2" ); + + itron_status = sta_tsk( 3, 0 ); + if ( !itron_status ) + printf("Created and started an ITRON task with id = 0x%08x\n", ITRON_GET_TASK_ID( 3 ) ); + else + directive_failed( itron_status, "sta_tsk of ITRON task 3" ); + + itron_status = sta_tsk( 4, 0 ); + if ( !itron_status ) + printf("Created and started an ITRON task with id = 0x%08x\n", ITRON_GET_TASK_ID( 4 ) ); + else + directive_failed( itron_status, "sta_tsk of ITRON task 4" ); +#endif + + printf( "Sleeping for 5 seconds\n" ); + fflush( stdout ); + + rtems_status = rtems_task_wake_after( 5 * TICKS_PER_SECOND ); + directive_failed( rtems_status, "rtems_task_wake_after" ); + + printf( "\nLooking for all threads\n\n" ); + _Thread_Local_iterate( print_thread_info, NULL, FALSE ); + + printf( "That was it. Sleeping for 20 seconds.\n" ); + + rtems_status = rtems_task_wake_after( 20 * TICKS_PER_SECOND ); + directive_failed( rtems_status, "rtems_task_wake_after" ); + + /* If we get here, all threads were created */ + printf( "\nDeleting the second thread of each type\n\n" ); + + rtems_status = rtems_task_suspend( Task_id[2] ); + directive_failed( rtems_status, "rtems_task_suspend" ); + rtems_status = rtems_task_delete( Task_id[2] ); + directive_failed( rtems_status, "rtems_task_delete" ); + +#ifdef RTEMS_POSIX_API + posix_status = pthread_cancel( pthread_id[2] ); + assert( !posix_status ); +#endif + +#ifdef RTEMS_ITRON_API + itron_status = ter_tsk( 3 ); + directive_failed( itron_status, "ter_tsk of ITRON task 3" ); +#endif + + printf( "\nLooking for all threads\n\n" ); + _Thread_Local_iterate( print_thread_info, NULL, FALSE ); + + printf( "That was it. Exiting\n" ); + fflush( stdout ); + + exit( 0 ); +} diff --git a/c/src/tests/sptests/threaditerate/itrontask.c b/c/src/tests/sptests/threaditerate/itrontask.c new file mode 100644 index 0000000000..8ae8364d66 --- /dev/null +++ b/c/src/tests/sptests/threaditerate/itrontask.c @@ -0,0 +1,52 @@ +/* Task_1_through_3 + * + * This routine serves as a test task. It verifies the basic task + * switching capabilities of the executive. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include "system.h" + +void ITRON_task_2_through_4( void ) +{ + ID tid; + int tid_index; + rtems_time_of_day time; + ER status; + char name[30]; + + status = get_tid( &tid ); + directive_failed( status, "get_tid"); + + tid_index = tid - 1; /* account for init tasks */ + + status = rtems_task_wake_after( 10 * TICKS_PER_SECOND ); + directive_failed( status, "rtems_task_wake_after" ); + + sprintf(name, "ITRON task %d", tid_index); + + while( FOREVER ) { + status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time ); + directive_failed( status, "rtems_clock_get" ); + + printf(name); + print_time( " - rtems_clock_get - ", &time, "\n" ); + + status = rtems_task_wake_after( 30 * TICKS_PER_SECOND ); + directive_failed( status, "rtems_task_wake_after" ); + } +} + diff --git a/c/src/tests/sptests/threaditerate/pthread.c b/c/src/tests/sptests/threaditerate/pthread.c new file mode 100644 index 0000000000..0dd76fcb91 --- /dev/null +++ b/c/src/tests/sptests/threaditerate/pthread.c @@ -0,0 +1,46 @@ +/* pthread_1_through_3 + * + * This routine serves as a test task. It verifies the basic task + * switching capabilities of the executive. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include "system.h" +#include + +void * pthread_1_through_3( void *argument ) +{ + int status; + struct timespec tv; + struct timespec tr; + time_t remaining; + + remaining = sleep( 10 ); + assert( !remaining ); + + while( FOREVER ) { + status = clock_gettime( CLOCK_REALTIME, &tv ); + posix_service_failed( status, "clock_gettime" ); + + printf( "pthread: ID is 0x%08x\n", pthread_self() ); + printf( " - clock_gettime - %s\n", ctime( &tv.tv_sec ) ); + + remaining = sleep( 30 ); + assert( !remaining ); + } + + return NULL; /* just so the compiler thinks we returned something */ +} diff --git a/c/src/tests/sptests/threaditerate/rtemstask.c b/c/src/tests/sptests/threaditerate/rtemstask.c new file mode 100644 index 0000000000..4a15ebec5f --- /dev/null +++ b/c/src/tests/sptests/threaditerate/rtemstask.c @@ -0,0 +1,47 @@ +/* Task_1_through_3 + * + * This routine serves as a test task. It verifies the basic task + * switching capabilities of the executive. + * + * Input parameters: + * argument - task argument + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include "system.h" + +rtems_task RTEMS_task_1_through_3( + rtems_task_argument argument +) +{ + rtems_id tid; + rtems_time_of_day time; + rtems_status_code status; + + status = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &tid ); + directive_failed( status, "rtems_task_ident" ); + + status = rtems_task_wake_after( 10 * TICKS_PER_SECOND ); + directive_failed( status, "rtems_task_wake_after" ); + + while( FOREVER ) { + status = rtems_clock_get( RTEMS_CLOCK_GET_TOD, &time ); + directive_failed( status, "rtems_clock_get" ); + + put_name( Task_name[ task_number( tid ) ], FALSE ); + print_time( " - rtems_clock_get - ", &time, "\n" ); + + status = rtems_task_wake_after( 30 * TICKS_PER_SECOND ); + directive_failed( status, "rtems_task_wake_after" ); + } +} diff --git a/c/src/tests/sptests/threaditerate/system.h b/c/src/tests/sptests/threaditerate/system.h new file mode 100644 index 0000000000..7792073f62 --- /dev/null +++ b/c/src/tests/sptests/threaditerate/system.h @@ -0,0 +1,98 @@ +/* system.h + * + * This include file contains information that is included in every + * function in the test set. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +/* RTEMS API */ + +#include +#include +#include +#include +#include + +unsigned32 print_thread_info( Thread_Control *thread, void * arg ); + +#include + +/* functions */ + +rtems_task Init( rtems_task_argument argument ); +rtems_task RTEMS_task_1_through_3( rtems_task_argument argument ); + +/* global variables */ + +TEST_EXTERN rtems_id Task_id[ 4 ]; /* array of task ids */ +TEST_EXTERN rtems_name Task_name[ 4 ]; /* array of task names */ + +/* configuration information */ + +#define CONFIGURE_SPTEST + +#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_EXTRA_TASK_STACKS (4 * RTEMS_MINIMUM_STACK_SIZE) + + + +/* POSIX API */ + +#ifdef RTEMS_POSIX_API + +#include +#include +#include +#include + +/* functions */ + +void *pthread_1_through_3( void *argument ); + +/* global variables */ + +TEST_EXTERN pthread_t pthread_id[3]; /* array of pthread ids */ + +/* configuration information */ + +#define CONFIGURE_MAXIMUM_POSIX_THREADS 3 + +#endif + + + +/* ITRON API */ + +#ifdef RTEMS_ITRON_API + +#include +#include + +/* functions */ + +void ITRON_task_2_through_4( void ); + +/* global variables */ + +TEST_EXTERN Objects_Locations location; + + +/* configuration information */ + +#endif + +#include + +/* end of include file */ diff --git a/c/src/tests/sptests/threaditerate/threadinfo.c b/c/src/tests/sptests/threaditerate/threadinfo.c new file mode 100644 index 0000000000..baf4822a5a --- /dev/null +++ b/c/src/tests/sptests/threaditerate/threadinfo.c @@ -0,0 +1,178 @@ +/* threadinfo.c + * + * Routines to print out information about threads. + */ + +#include "system.h" +#include + +#define PTR unsigned int +#define PTR_MASK "0x%08x" + +/* + * Return a pointer to a string describing the object type. + */ + +const char * _Objects_Type_to_String( Objects_Control * object ) +{ + switch( _Objects_Get_class( object->id ) ) { + case OBJECTS_NO_CLASS: + return "NO_CLASS"; + + case OBJECTS_INTERNAL_THREADS: + return "INTERNAL_THREADS"; + + case OBJECTS_RTEMS_TASKS: + return "RTEMS_TASKS"; + + case OBJECTS_POSIX_THREADS: + return "POSIX_THREADS"; + + case OBJECTS_ITRON_TASKS: + return "ITRON_TASKS"; + + case OBJECTS_RTEMS_TIMERS: + return "RTEMS_TIMERS"; + + case OBJECTS_RTEMS_SEMAPHORES: + return "RTEMS_SEMAPHORES"; + + case OBJECTS_RTEMS_MESSAGE_QUEUES: + return "RTEMS_MESSAGE_QUEUES"; + + case OBJECTS_RTEMS_PARTITIONS: + return "RTEMS_PARTITIONS"; + + case OBJECTS_RTEMS_REGIONS: + return "RTEMS_REGIONS"; + + case OBJECTS_RTEMS_PORTS: + return "RTEMS_PORTS"; + + case OBJECTS_RTEMS_PERIODS: + return "RTEMS_PERIODS"; + + case OBJECTS_RTEMS_EXTENSIONS: + return "RTEMS_EXTENSIONS"; + + case OBJECTS_POSIX_KEYS: + return "POSIX_KEYS"; + + case OBJECTS_POSIX_INTERRUPTS: + return "POSIX_INTERRUPTS"; + + case OBJECTS_POSIX_MESSAGE_QUEUES: + return "POSIX_MESSAGE_QUEUES"; + + case OBJECTS_POSIX_MUTEXES: + return "POSIX_MUTEXES"; + + case OBJECTS_POSIX_SEMAPHORES: + return "POSIX_SEMAPHORES"; + + case OBJECTS_POSIX_CONDITION_VARIABLES: + return "POSIX_CONDITION_VARIABLES"; + + case OBJECTS_ITRON_EVENTFLAGS: + return "ITRON_EVENTFLAGS"; + + case OBJECTS_ITRON_MAILBOXES: + return "ITRON_MAILBOXES"; + + case OBJECTS_ITRON_MESSAGE_BUFFERS: + return "ITRON_MESSAGE_BUFFERS"; + + case OBJECTS_ITRON_PORTS: + return "ITRON_PORTS"; + + case OBJECTS_ITRON_SEMAPHORES: + return "ITRON_SEMAPHORES"; + + case OBJECTS_ITRON_VARIABLE_MEMORY_POOLS: + return "ITRON_VARIABLE_MEMORY_POOLS"; + + case OBJECTS_ITRON_FIXED_MEMORY_POOLS: + return "ITRON_FIXED_MEMORY_POOLS"; + + default: + return "UNKNOWN"; + } +} + + +/* + * Return a pointer to a string describing the thread state + */ + +const char * _Thread_State_to_String( States_Control state ) +{ + States_Control orig_state = state; + int i; + int first_entry = TRUE; + static char buffer[256]; + static const char *desc[] = { + "READY", /* 0 - 0x00000 */ + "DORMANT", /* 1 - 0x00001 */ + "SUSPENDED", /* 2 - 0x00002 */ + "TRANSIENT", /* 3 - 0x00004 */ + "DELAYING", /* 4 - 0x00008 */ + "WAITING_FOR_TIME", /* 5 - 0x00010 */ + "WAITING_FOR_BUFFER", /* 6 - 0x00020 */ + "WAITING_FOR_SEGMENT", /* 7 - 0x00040 */ + "WAITING_FOR_MESSAGE", /* 8 - 0x00080 */ + "WAITING_FOR_EVENT", /* 9 - 0x00100 */ + "WAITING_FOR_SEMAPHORE", /* 10 - 0x00200 */ + "WAITING_FOR_MUTEX", /* 11 - 0x00400 */ + "WAITING_FOR_CONDITION_VARIABLE", /* 12 - 0x00800 */ + "WAITING_FOR_JOIN_AT_EXIT", /* 13 - 0x01000 */ + "WAITING_FOR_RPC_REPLY", /* 14 - 0x02000 */ + "WAITING_FOR_PERIOD", /* 15 - 0x04000 */ + "WAITING_FOR_SIGNAL", /* 16 - 0x08000 */ + "INTERRUPTIBLE_BY_SIGNAL", /* 17 - 0x10000 */ + "UNKNOWN" /* 18 - all higher bits */ + }; + + if( state == STATES_READY ) + return desc[0]; + + memset( buffer, '\0', sizeof( buffer ) ); + for ( i = 1; i < 18; i++ ) { + if ( state & 0x1 ) { + if ( !first_entry ) { + strcat ( buffer, " | " ); + } + strcat ( buffer, desc[i] ); + first_entry = FALSE; + } + state = state >> 1; + } + + if ( state != 0 ) { + if ( !first_entry ) { + strcat ( buffer, " | " ); + } + strcat ( buffer, desc[18] ); + } + + return buffer; +} + + +/* + * Callback function to print out thread Ids, thread priorities, and thread stack + * information. + */ + +unsigned32 print_thread_info( Thread_Control *thread, void * arg ) +{ + printf( "Thread ID 0x%08x at "PTR_MASK"\n", thread->Object.id, (PTR)thread ); + printf( "\ttype = %s\n", _Objects_Type_to_String( &(thread->Object) ) ); + printf( "\tstate = %s\n", _Thread_State_to_String( thread->current_state ) ); + printf( "\treal priority = %d\n", thread->real_priority ); + printf( "\tcurrent priority = %d\n", thread->current_priority ); + printf( "\tstack base = "PTR_MASK"\n", (PTR)thread->Start.Initial_stack.area ); + printf( "\tstack size = 0x%08x\n", thread->Start.Initial_stack.size ); + /* printf( "\tstack pointer = "PTR_MASK"\n", */ + printf( "\n" ); + return 0; +} diff --git a/c/src/tests/sptests/threaditerate/threaditerate.scn b/c/src/tests/sptests/threaditerate/threaditerate.scn new file mode 100644 index 0000000000..9aeb43a212 --- /dev/null +++ b/c/src/tests/sptests/threaditerate/threaditerate.scn @@ -0,0 +1,205 @@ +*** Thread Iteration Test *** +Created and started an RTEMS task with id = 0x08010002 +Created and started an RTEMS task with id = 0x08010003 +Created and started an RTEMS task with id = 0x08010004 +Created and started a pthread with id = 0x0c010001 +Created and started a pthread with id = 0x0c010002 +Created and started a pthread with id = 0x0c010003 +Created and started an ITRON task with id = 0x10010002 +Created and started an ITRON task with id = 0x10010003 +Created and started an ITRON task with id = 0x10010004 +Sleeping for 5 seconds + +Looking for all threads + +Thread ID 0x04010001 at 0x00192364 + type = INTERNAL_THREADS + state = READY + real priority = 255 + current priority = 255 + stack base = 0x0018cde8 + stack size = 0x00002008 + +Thread ID 0x08010001 at 0x00191390 + type = RTEMS_TASKS + state = READY + real priority = 1 + current priority = 1 + stack base = 0x0018ac54 + stack size = 0x00002008 + +Thread ID 0x08010002 at 0x001914ec + type = RTEMS_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x00186ac0 + stack size = 0x00004008 + +Thread ID 0x08010003 at 0x00191648 + type = RTEMS_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x0018292c + stack size = 0x00004008 + +Thread ID 0x08010004 at 0x001917a4 + type = RTEMS_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x0017c798 + stack size = 0x00006008 + +Thread ID 0x0c010001 at 0x0018fbf4 + type = POSIX_THREADS + state = DELAYING | INTERRUPTIBLE_BY_SIGNAL + real priority = 1 + current priority = 1 + stack base = 0x00178604 + stack size = 0x00004008 + +Thread ID 0x0c010002 at 0x0018fd50 + type = POSIX_THREADS + state = DELAYING | INTERRUPTIBLE_BY_SIGNAL + real priority = 1 + current priority = 1 + stack base = 0x00174470 + stack size = 0x00004008 + +Thread ID 0x0c010003 at 0x0018feac + type = POSIX_THREADS + state = DELAYING | INTERRUPTIBLE_BY_SIGNAL + real priority = 1 + current priority = 1 + stack base = 0x001702dc + stack size = 0x00004008 + +Thread ID 0x10010002 at 0x0018ef58 + type = ITRON_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x0016c148 + stack size = 0x00004008 + +Thread ID 0x10010003 at 0x0018f0b4 + type = ITRON_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x00167f24 + stack size = 0x00004008 + +Thread ID 0x10010004 at 0x0018f210 + type = ITRON_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x00161d00 + stack size = 0x00006008 + +That was it. Sleeping for 20 seconds. +TA1 - rtems_clock_get - 09:00:10 12/31/2000 +TA2 - rtems_clock_get - 09:00:10 12/31/2000 +TA3 - rtems_clock_get - 09:00:10 12/31/2000 +pthread: ID is 0x0c010001 + - clock_gettime - Sun Dec 31 09:00:10 2000 + +pthread: ID is 0x0c010002 + - clock_gettime - Sun Dec 31 09:00:10 2000 + +pthread: ID is 0x0c010003 + - clock_gettime - Sun Dec 31 09:00:10 2000 +ITRON task 1 - rtems_clock_get - 09:00:10 12/31/2000 + +ITRON task 2 - rtems_clock_get - 09:00:10 12/31/2000 +ITRON task 3 - rtems_clock_get - 09:00:10 12/31/2000 + +Deleting the second thread of each type + + +Looking for all threads + +Thread ID 0x04010001 at 0x00192364 + type = INTERNAL_THREADS + state = READY + real priority = 255 + current priority = 255 + stack base = 0x0018cde8 + stack size = 0x00002008 + +Thread ID 0x08010001 at 0x00191390 + type = RTEMS_TASKS + state = READY + real priority = 1 + current priority = 1 + stack base = 0x0018ac54 + stack size = 0x00002008 + +Thread ID 0x08010002 at 0x001914ec + type = RTEMS_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x00186ac0 + stack size = 0x00004008 + +Thread ID 0x08010004 at 0x001917a4 + type = RTEMS_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x0017c798 + stack size = 0x00006008 + +Thread ID 0x0c010001 at 0x0018fbf4 + type = POSIX_THREADS + state = DELAYING | INTERRUPTIBLE_BY_SIGNAL + real priority = 1 + current priority = 1 + stack base = 0x00178604 + stack size = 0x00004008 + +Thread ID 0x0c010002 at 0x0018fd50 + type = POSIX_THREADS + state = DELAYING | INTERRUPTIBLE_BY_SIGNAL + real priority = 1 + current priority = 1 + stack base = 0x00174470 + stack size = 0x00004008 + +Thread ID 0x0c010003 at 0x0018feac + type = POSIX_THREADS + state = DELAYING | INTERRUPTIBLE_BY_SIGNAL + real priority = 1 + current priority = 1 + stack base = 0x001702dc + stack size = 0x00004008 + +Thread ID 0x10010002 at 0x0018ef58 + type = ITRON_TASKS + state = DELAYING + real priority = 1 + current priority = 1 + stack base = 0x0016c148 + stack size = 0x00004008 + +Thread ID 0x10010003 at 0x0018f0b4 + type = ITRON_TASKS + state = DORMANT + real priority = 1 + current priority = 1 + stack base = 0x00167f24 + stack size = 0x00004008 + +Thread ID 0x10010004 at 0x0018f210 + type = ITRON_TASKS + state = DELAYING + real priority =1 + current priority = 1 + stack base = 0x00161d00 + stack size = 0x00006008 + +That was it. Exiting diff --git a/make/custom/mbx821_001.cfg b/make/custom/mbx821_001.cfg new file mode 100644 index 0000000000..8f8a3327f6 --- /dev/null +++ b/make/custom/mbx821_001.cfg @@ -0,0 +1,12 @@ +# +# Config file for a PowerPC MPC860-based MBX821-001 card. +# + +# +# All MBX8xx configurations share the same base file, only a few +# parameters differ. +# + +RTEMS_MBX_MODEL=mbx821_001 + +include $(RTEMS_ROOT)/make/custom/mbx8xx.cfg diff --git a/make/custom/mbx860_002.cfg b/make/custom/mbx860_002.cfg new file mode 100644 index 0000000000..0558456004 --- /dev/null +++ b/make/custom/mbx860_002.cfg @@ -0,0 +1,12 @@ +# +# Config file for a PowerPC MPC860-based MBX860-002 card. +# + +# +# All MBX8xx configurations share the same base file, only a few +# parameters differ. +# + +RTEMS_MBX_MODEL=mbx860_002 + +include $(RTEMS_ROOT)/make/custom/mbx8xx.cfg diff --git a/make/custom/mbx8xx.cfg b/make/custom/mbx8xx.cfg new file mode 100644 index 0000000000..f868c2fb52 --- /dev/null +++ b/make/custom/mbx8xx.cfg @@ -0,0 +1,196 @@ +# +# Config file for a PowerPC MPC821- or MPC860-based MBX card +# +# This file is derived from: +# +# Config file for a PowerPC 403 based helas403 card +# Config file for MPC860 based Ethernet Comm Board +# + +include $(RTEMS_ROOT)/make/custom/default.cfg + +RTEMS_CPU=powerpc +RTEMS_CPU_MODEL=mpc8xx + +# This is the actual bsp directory used during the build process. +RTEMS_BSP_FAMILY=mbx8xx + +# The value assigned to RTEMS_CPU, RTEMS_CPU_MODEL and RTEMS_BSP get +# #defined in targopts.h. Source code can switch on these values with #ifdef +# to select what code to compile for a specific CPU family member and specific +# board. The RTEMS_CPU_MODEL is also used as the name of the libcpu directory, +# while the RTEMS_BSP_FAMILY is used as the name of the libbsp directory. +# For the MBX860 and MBX821, the boards and processors are sufficiently +# similar that the ports are unified and use RTEMS_CPU_MODEL=mpc8xx and +# RTEMS_BSP_FAMILY=mbx8xx. Because there are minor differences in the CPUs +# and the boards, it is necessary to specify them fully during the build. +# Do a "make RTEMS_BSP= " See below for a list of valid +# values for . + +ifeq ($(findstring mbx821,$(RTEMS_MBX_MODEL)),mbx821) +CPU_TYPE=821 +else +ifeq ($(findstring mbx860,$(RTEMS_MBX_MODEL)),mbx860) +CPU_TYPE=860 +else +RTEMS_BSP = mbx860_002 +RTEMS_MBX_MODEL = mbx860_002 +TARGET_ARCH=o-mbx860_002 +CPU_TYPE=860 +endif # mbx860 +endif # mbx821 + +# This section makes the target dependent options file. +# +# Note that RTEMS_BSP matches the RTEMS_MBX_MODEL. Its value must be +# defined in targopts.h, so the few places that require different code +# for different MBX models can be distinguished. The value of +# RTEMS_BSP is already defined in targopts.h and is one of: +# mbx860_001 mbx821_001 +# mbx860_002 mbx821_002 +# mbx860_003 mbx821_003 +# mbx860_004 mbx821_004 +# mbx860_005 mbx821_005 +# mbx860_001b mbx821_001b +# mbx860_002b mbx821_002b +# mbx860_003b mbx821_003b +# mbx860_004b mbx821_004b +# mbx860_005b mbx821_005b +# mbx860_006b mbx821_006b + +# The specific CPU model is defined, so the few places that require +# different code for the MPC860 and MPC821 can be distinguished. +# Either mpc860 or mpc821 is defined. +# +# MBX8xx-specific options: +# +# CONSOLE_MINOR (BSP--console driver) +# Must be defined to be one of SMC1_MINOR, SMC2_MINOR, SCC2_MINOR, +# SCC3_MINOR, or SCC4_MINOR. Determines which device will be registered +# as /dev/console. +# +# UARTS_USE_INTERRUPTS (BSP--console driver) +# Define if you want interrupt-driven I/O instead of polling. Superceeded +# by EPPCBUG_SMC1 on SMC1. +# +# EPPCBUG_SMC1 (BSP--console driver) +# If defined, the I/O through the SCM1 is done through the EPPCBug firmware. +# Because of limitations in revision 1.1 of the firmware, EPPCBug must be +# configured to use SMC1 as its console. If not defined, I/O through SMC1 +# is done through a RTEMS device driver. +# +# EPPCBUG_VECTORS (BSP--RTEMS) +# If defined, the most vectors branch to EPPCBug, except the following: +# 0x500 (external interrupt), 0x900 (decrementer). +# +# INSTRUCTION_CACHE_ENABLE (BSP--RTEMS) +# If defined, the instruction cache will be enabled after address translation +# is turned on. +# +# DATA_CACHE_ENABLE (BSP--RTEMS) +# If defined, the data cache will be enabled after address translation +# is turned on. +# +# PowerPC-specific options: +# +# PPC_USE_SPRG (RTEMS PowerPC port) +# If defined (=1), then the PowerPC specific code in RTEMS will use some +# of the special purpose registers to slightly optimize interrupt +# response time. The use of these registers can conflict with +# other tools like debuggers. This should be 0 when using EPPCBug +# because its uses most SPRGs (don't believe the documentation!). +# +# PPC_USE_DATA_CACHE (RTEMS PowerPC port) +# If defined, then the PowerPC specific code in RTEMS will use +# data cache instructions to optimize the context switch code. +# This code can conflict with debuggers or emulators. +# +# RTEMS generic options: +# +# NDEBUG (C library) +# If defined, asserts do not generate code. This is commonly used +# as a command line option. +# +# RTEMS_TEST_NO_PAUSE (RTEMS tests) +# If defined, do not pause between screens of output in the rtems tests. +# +# STACK_CHECKER_ON (RTEMS support code) +# If defined, stack bounds checking is enabled. +# +# STACK_CHECKER_REPORT_USAGE (RTEMS support code) +# If this and STACK_CHECKER_ON are defined, then a report on stack usage +# per task is printed when the program exits. +# +# RTEMS_DEBUG (RTEMS) +# If defined, debug checks in RTEMS and support library code are enabled. + +define make-target-options + @echo "#ifdef mpc$(CPU_TYPE)" >>$@ + @echo "#undef mpc$(CPU_TYPE)" >>$@ + @echo "#endif" >>$@ + @echo "#define mpc$(CPU_TYPE) 1" >>$@ + @echo >>$@ + @echo "#define CONSOLE_MINOR SMC2_MINOR" >>$@ + @echo "#define UARTS_USE_INTERRUPTS 1" >>$@ + @echo "#define EPPCBUG_SMC1 1" >>$@ + @echo "#define EPPCBUG_VECTORS 1" >>$@ + @echo "#define INSTRUCTION_CACHE_ENABLE 1" >>$@ + @echo "#define DATA_CACHE_ENABLE 1" >>$@ + @echo >>$@ + @echo "#define PPC_VECTOR_FILE_BASE 0x0000" >>$@ + @echo "#define PPC_USE_SPRG 0" >>$@ + @echo "/* #define PPC_USE_DATA_CACHE 1" */ >>$@ + @echo >>$@ + @echo "/* #define NDEBUG 1 */ " >>$@ + @echo "#define RTEMS_TEST_NO_PAUSE 1" >>$@ + @echo "/* #define STACK_CHECKER_ON 1 */" >>$@ + @echo "/* #define STACK_CHECKER_REPORT_USAGE 1 */" >>$@ + @echo "/* #define RTEMS_DEBUG 1 */" >>$@ +endef + +# This contains the compiler options necessary to select the CPU model +# and (hopefully) optimize for it. +# +CPU_CFLAGS = -mcpu=$(CPU_TYPE) + +CFLAGS_DEBUG_V += -ggdb +CXXFLAGS_DEBUG_V += -ggdb + +# optimize flag: typically -O, could use -O4 or -fast +# -O4 is ok for RTEMS +# NOTE: some level of -O may be actually required by inline assembler +# CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions +CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions +CXXFLAGS_OPTIMIZE_V=-O4 + +# The following are definitions of make-exe which will work using ld as +# is currently required. It is expected that as of gcc 2.8, the end user +# will be able to override parts of the compilers specs and link using gcc. + +ifeq ($(RTEMS_USE_GCC272),yes) +# The --defsym arguments define arguments which are required by the linkcmds +# file which is designed for gcc 2.8 +define make-exe + $(LD) $(XLDFLAGS) -T $(LINKCMDS) \ + --defsym __fini=0 --defsym __init=0 \ + -o $@ -u atexit -u __vectors -u start \ + $(START_FILE) $(LINK_OBJS) --start-group $(LINK_LIBS) --end-group + $(NM) -g -n $@ > $(basename $@).num + $(STRIP) -o $(basename $@).elf $@ + $(SIZE) $@ +endef +else +define make-exe + $(CC) $(CFLAGS) $(CPU_CFLAGS) $(XLDFLAGS) -o $(basename $@).exe \ + $(LINK_OBJS) $(LINK_LIBS) + $(NM) -g -n $@ > $(basename $@).nm + $(STRIP) -o $(basename $@) $@ + $(SIZE) $@ +endef +endif + +# Miscellaneous additions go here + +# Override default start file +START_BASE= + -- cgit v1.2.3