Mercurial > ecos-v2_0-branch
changeset 34:29bc183297e1 ecos-sw-1999-09-02
Merge from eCos master repository on 1999-09-02-16:26:10-BST
line wrap: on
line diff
--- a/packages/compat/uitron/current/ChangeLog +++ b/packages/compat/uitron/current/ChangeLog @@ -1,3 +1,48 @@ +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> + + + * 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-05-26 Jesper Skov <jskov@cygnus.co.uk> * tests/testcx7.cxx: Include new stackmon header.
--- a/packages/compat/uitron/current/include/pkgconf/uitron.h +++ b/packages/compat/uitron/current/include/pkgconf/uitron.h @@ -935,6 +935,53 @@ static char vpool1[ 2000 ], \ #endif #endif // NOT SUPPORTED +// ------------------------------------------------------------------------ +// Interrupt-safe functions [ixxx_yyy()]: +// +// These can queue up requests for execution in a DSR or maybe execute +// immediately if safe so to do. + +/* {{CFG_DATA + cdl_component CYGPKG_UITRON_INTERRUPT_FUNCTIONS { + display "Interrupt-safe functions" + type dummy + parent CYGPKG_UITRON + 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 + type boolean + 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 + type enum + legal_values 4 8 16 32 64 128 256 + 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." + } + }}CFG_DATA */ + +#define CYGSEM_UITRON_ISRFUNCS_TRY_IMMEDIATE_EXECUTION +#define CYGNUM_UITRON_ISR_ACTION_QUEUESIZE 32 + // ======================================================================== // ------------------------------------------------------------------------ // uITRON VERSION INFORMATION @@ -1057,8 +1104,7 @@ static char vpool1[ 2000 ], \ response to a get_ver() system call. Do NOT change this value." } - }}CFG_DATA - */ + }}CFG_DATA */ // these constants are returned by the get_ver API call.
new file mode 100644 --- /dev/null +++ b/packages/compat/uitron/current/include/uit_ifnc.h @@ -0,0 +1,164 @@ +#ifndef CYGONCE_COMPAT_UITRON_UIT_IFNC_H +#define CYGONCE_COMPAT_UITRON_UIT_IFNC_H +//=========================================================================== +// +// uit_ifnc.h +// +// uITRON compatibility functions +// +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####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: + +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) ? 0 : 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) + +// ======================================================================== +// 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. + +void cyg_uitron_dsr( unsigned int vector, unsigned int count, unsigned int data ); + +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_ifnc.inl> +#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW + +// ------------------------------------------------------------------------ +#endif // CYGPKG_UITRON + +#endif // CYGONCE_COMPAT_UITRON_UIT_IFNC_H +// EOF uit_ifnc.h
new file mode 100644 --- /dev/null +++ b/packages/compat/uitron/current/include/uit_ifnc.inl @@ -0,0 +1,207 @@ +#ifndef CYGONCE_COMPAT_UITRON_UIT_IFNC_INL +#define CYGONCE_COMPAT_UITRON_UIT_IFNC_INL +//=========================================================================== +// +// uit_ifnc.inl +// +// uITRON compatibility functions +// +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####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
--- a/packages/compat/uitron/current/src/PKGconf.mak +++ b/packages/compat/uitron/current/src/PKGconf.mak @@ -32,7 +32,7 @@ PACKAGE := uitron include ../../../../pkgconf/pkgconf.mak LIBRARY := libtarget.a -COMPILE := uit_func.cxx uit_objs.cxx +COMPILE := uit_func.cxx uit_objs.cxx uit_ifnc.cxx OTHER_OBJS := OTHER_TARGETS := OTHER_CLEAN :=
new file mode 100644 --- /dev/null +++ b/packages/compat/uitron/current/src/uit_ifnc.cxx @@ -0,0 +1,129 @@ +//=========================================================================== +// +// uit_ifnc.cxx +// +// uITRON compatibility functions +// +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####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 +#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
--- a/packages/compat/uitron/current/tests/PKGconf.mak +++ b/packages/compat/uitron/current/tests/PKGconf.mak @@ -34,8 +34,9 @@ include ../../../../pkgconf/pkgconf.mak TESTS := test1 test2 test3 test4 test5 \ test6 test7 test8 test9 \ testcxx testcx2 testcx3 testcx4 testcx5 \ - testcx6 testcx7 testcx8 testcx9 - + testcx6 testcx7 testcx8 testcx9 \ + testintr + include $(COMPONENT_REPOSITORY)/pkgconf/makrules.tst
new file mode 100644 --- /dev/null +++ b/packages/compat/uitron/current/tests/testintr.cxx @@ -0,0 +1,735 @@ +//=========================================================================== +// +// testintr.c +// +// uITRON "C" test program for ixxx_yyy interrupt safe operators +// +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): hmt +// Contributors:hmt +// Date: 1998-08-20 +// 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/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 + +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 ); +} + +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 + +unsigned int +isr_wup_tsk( unsigned int vector, unsigned int data ) +{ + // Hit TASKS in range 2..4 + static int wtid = 2; + ACK_CLOCK(); + 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(); + 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(); + 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(); + 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(); + 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(); \ + } 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 + smalldelay = SMALLDELAYSIM; + events = EVENTSSIM; + } + + 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 3" ); + 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> + + +// 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_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC ); + HAL_DISABLE_INTERRUPTS(old_ints); + prtc->interrupt.detach(); + HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse ); + CYG_TEST_CHECK( !inuse, "Failed to detach clock ISR" ); + 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_RESTORE_INTERRUPTS(old_ints); + HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC ); +} + +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_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC ); + HAL_DISABLE_INTERRUPTS(old_ints); + uit_intr.detach(); + HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse ); + CYG_TEST_CHECK( !inuse, "Failed to detach my ISR" ); + prtc->interrupt.attach(); + HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse ); + CYG_TEST_CHECK( inuse, "Failed to attach clock ISR" ); + ACK_CLOCK(); + HAL_RESTORE_INTERRUPTS(old_ints); + HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC ); +} + + +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 +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
--- a/packages/devs/watchdog/current/ChangeLog +++ b/packages/devs/watchdog/current/ChangeLog @@ -1,3 +1,14 @@ +1999-08-27 Jesper Skov <jskov@cygnus.co.uk> + + * tests/watchdog_reset.cxx: + * tests/PKGconf.mak (TESTS): + Added test for watchdog devices that reset the board. + +1999-08-24 Nick Garnett <nickg@cygnus.co.uk> + + * src/mn10300.cxx: Turn watchdog off in Cyg_Watchdog::trigger() to + prevent it repeating. + 1999-08-18 Nick Garnett <nickg@cygnus.co.uk> * include/pkgconf/watchdog.h: Made test for use of a non-emulated
--- a/packages/devs/watchdog/current/include/pkgconf/watchdog.h +++ b/packages/devs/watchdog/current/include/pkgconf/watchdog.h @@ -77,6 +77,8 @@ #undef CYGIMP_WATCHDOG_EMULATE #endif + + /* -------------------------------------------------------------------- */ #endif /* CYGONCE_PKGCONF_WATCHDOG_H */ /* EOF watchdog.h */
--- a/packages/devs/watchdog/current/src/mn10300.cxx +++ b/packages/devs/watchdog/current/src/mn10300.cxx @@ -182,6 +182,9 @@ Cyg_Watchdog::trigger() // Disable interrupt just in case interrupt.detach(); + // Turn watchdog off to prevent it re-triggering. + HAL_WRITE_UINT8( WATCHDOG_CONTROL, 0 ); + Cyg_Watchdog_Action *act = action_list; while( 0 != act )
--- a/packages/devs/watchdog/current/tests/PKGconf.mak +++ b/packages/devs/watchdog/current/tests/PKGconf.mak @@ -33,6 +33,11 @@ include ../../../../pkgconf/pkgconf.mak TESTS := watchdog +# Invoke make with RUN_BY_HAND=1 as argument +ifdef RUN_BY_HAND +TESTS += watchdog_reset +endif + include $(COMPONENT_REPOSITORY)/pkgconf/makrules.tst
new file mode 100644 --- /dev/null +++ b/packages/devs/watchdog/current/tests/watchdog_reset.cxx @@ -0,0 +1,173 @@ +//========================================================================== +// +// watchdog_reset.cxx +// +// Watchdog reset test +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov (based on watchdog.cxx) +// Contributors: jskov, nickg +// Date: 1999-08-27 +// Description: Tests that the watchdog timer resets the board. +// This test needs to be run by an operator - automatic +// testing not possible. +//####DESCRIPTIONEND#### +// ------------------------------------------------------------------------- + +#include <pkgconf/system.h> + +#include <cyg/infra/testcase.h> +#include <cyg/infra/diag.h> + +// Package requirements +#if defined(CYGPKG_KERNEL) + +#include <pkgconf/kernel.h> + +// Package option requirements +#if defined(CYGFUN_KERNEL_THREADS_TIMER) && \ + defined(CYGVAR_KERNEL_COUNTERS_CLOCK) + + +#include <cyg/kernel/thread.inl> + +#include <cyg/hal/hal_cache.h> + +#include <cyg/devs/watchdog.hxx> + + +// ------------------------------------------------------------------------- +// Data for the test + +#ifdef CYGNUM_HAL_STACK_SIZE_TYPICAL +#define STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL +#else +#define STACKSIZE (2*1024) // size of thread stack +#endif + +char thread_stack[STACKSIZE]; + +inline void *operator new(size_t size, void *ptr) { return ptr; }; + +// array of threads. +char thread[sizeof(Cyg_Thread)]; + +Cyg_Thread *th; + +//cyg_tick_count one_sec; +cyg_tick_count watchdog_delay; + +// ------------------------------------------------------------------------- +// Thread body + +volatile int watchdog_accuracy = 50; + +void watchdog_thread( CYG_ADDRWORD id ) +{ + diag_printf("Test of watchdog timer accuracy. Expect the test to run\n" + "for at least 10 times the watchdog timeout time. After\n" + "that time you may have to reset the board manually and/or\n" + "restart GDB which tends to get a little confused.\n"); + diag_printf("When you get contact with the board again, read the value\n" + "in watchdog_accuracy - it should be close to 100 if the\n" + "watchdog timer is accurate.\n"); + + // Disable data cache so the variable in memory gets updated. + HAL_DCACHE_SYNC(); + HAL_DCACHE_DISABLE(); + + Cyg_Watchdog::watchdog.start(); + Cyg_Watchdog::watchdog.reset(); + + while (watchdog_accuracy < 400) { + Cyg_Watchdog::watchdog.reset(); + th->delay( watchdog_delay*watchdog_accuracy/100 ); + watchdog_accuracy += 5; + } + + CYG_TEST_FAIL_FINISH("Watchdog failed to reset board. " + "Timer value is off by at least a factor of 4!"); +} + +// ------------------------------------------------------------------------- + + +externC void +cyg_start( void ) +{ + CYG_TEST_INIT(); + +#if !defined(CYGIMP_WATCHDOG_EMULATE) && defined(CYGPKG_HAL_MN10300_STDEVAL1) + // Workaround for PR 17974 + if( cyg_test_is_simulator ) + CYG_TEST_NA("Watchdog device not implemented in MN10300 simulator."); +#endif + + + Cyg_Clock::cyg_resolution res = Cyg_Clock::real_time_clock->get_resolution(); + + cyg_uint64 wres = Cyg_Watchdog::watchdog.get_resolution(); + + // Calculate how many clock ticks there are in a watchdog cycle. + + watchdog_delay = ((cyg_tick_count)wres * (cyg_tick_count)res.divisor ); + watchdog_delay /= res.dividend; + + th = new((void *)&thread) Cyg_Thread(CYG_SCHED_DEFAULT_INFO, + watchdog_thread, + 0, + "watchdog_thread", + (CYG_ADDRESS)thread_stack, + STACKSIZE + ); + + th->resume(); + + // Get the world going + Cyg_Scheduler::scheduler.start(); + +} + +#else // CYGFUN_KERNEL_THREADS_TIMER etc... +#define N_A_MSG "Needs kernel RTC/threads timer" +#endif + +#else // CYGPKG_KERNEL +#define N_A_MSG "Needs Kernel" +#endif + +#ifdef N_A_MSG +void +cyg_start( void ) +{ + CYG_TEST_INIT(); + CYG_TEST_NA( N_A_MSG); +} +#endif // N_A_MSG + +// ------------------------------------------------------------------------- +// EOF watchdog_reset.cxx
--- a/packages/hal/arm/arch/current/ChangeLog +++ b/packages/hal/arm/arch/current/ChangeLog @@ -1,3 +1,17 @@ +1999-08-24 Hugo Tyson <hmt@masala.cygnus.co.uk> + + * src/vectors.S (handle_IRQ_or_FIQ): Set up the pointer-to-regset + in r2 for calling the ISR as well as the DSR. This is needed for + the cyg_hal_gdb_isr() for those platforms that handle ^C's + incoming that way - the ISR needs a regset to know where to plant + a breakpoint to stop the system in the interrupted context. + +1999-08-23 Jesper Skov <jskov@cygnus.co.uk> + + * src/arm_stub.c + (target_ins): Check whether branches execute. + (ins_will_execute): Fixed HI and LS. + 1999-08-06 Jesper Skov <jskov@cygnus.co.uk> CR 101032 * src/vectors.S (handle_IRQ_or_FIQ): Moved setup of register_frame
--- a/packages/hal/arm/arch/current/src/arm_stub.c +++ b/packages/hal/arm/arch/current/src/arm_stub.c @@ -110,10 +110,10 @@ ins_will_execute(unsigned long ins) res = (psr & PS_V) == 0; break; case 0x8: // HI - res = ((psr & PS_Z) != 0) && ((psr & PS_C) == 0); + res = ((psr & PS_C) != 0) && ((psr & PS_Z) == 0); break; case 0x9: // LS - res = ((psr & PS_Z) == 0) || ((psr & PS_C) != 0); + res = ((psr & PS_C) == 0) || ((psr & PS_Z) != 0); break; case 0xA: // GE res = ((psr & (PS_N|PS_V)) == (PS_N|PS_V)) || @@ -321,10 +321,15 @@ target_ins(unsigned long *pc, unsigned l } } else { // Branch - offset = (ins & 0x00FFFFFF) << 2; - if (ins & 0x00800000) offset |= 0xFC000000; // sign extend - new_pc = (unsigned long)(pc+2) + offset; - return ((unsigned long *)new_pc); + if (ins_will_execute(ins)) { + offset = (ins & 0x00FFFFFF) << 2; + if (ins & 0x00800000) offset |= 0xFC000000; // sign extend + new_pc = (unsigned long)(pc+2) + offset; + return ((unsigned long *)new_pc); + } else { + // Falls through + return (pc+1); + } } case 0x3: // Coprocessor & SWI return (pc+1);
--- a/packages/hal/arm/arch/current/src/vectors.S +++ b/packages/hal/arm/arch/current/src/vectors.S @@ -568,6 +568,8 @@ 10: ldr r1,[r1,v1,lsl #2] // handler data ldr r2,.hal_interrupt_handlers ldr v3,[r2,v1,lsl #2] // handler (indexed by vector #) + mov r2,v6 // register frame (this is necessary + // for the ISR too, for ^C detection) mov lr,pc // invoke handler (call indirect mov pc,v3 // thru v3) @@ -656,18 +658,19 @@ hal_interrupt_stack_call_pending_DSRs: #endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK -// Dummy functions +// Dummy/support functions .global __gccmain + .global _psr + .global _sp + __gccmain: mov pc,lr - .global _psr _psr: mrs r0,cpsr mov pc,lr - .global _sp _sp: mov r0,sp mov pc,lr
--- a/packages/hal/common/current/ChangeLog +++ b/packages/hal/common/current/ChangeLog @@ -1,3 +1,53 @@ +1999-09-01 Gary Thomas <gthomas@cygnus.co.uk> + + * include/pkgconf/hal.h: Always include target and platform package + include (pkgconf) files. + +1999-08-26 Jonathan Larmour <jlarmour@cygnus.co.uk> + + * src/generic-stub.c (__hex2mem_helper): + Use target_register_t when casting to address type, rather than long + Since the compiler can choose arbitrary alignment of unions, force + to use byte array only + Restore use of loop termination test for *hexMemSrc, just in case + since that's how it used to be + Increment destination, not source at end of loop + + (__mem2hex_helper): + Use target_register_t when casting to address type, rather than long. + Since the compiler can choose arbitrary alignment of unions, force + to use byte array only. Therefore use single __read_mem_safe() call + + * src/hal_stub.c (__do_copy_mem): Reassign back from dst/src at start + of each "if" clause in case we go round the loop again. + +1999-08-24 Gary Thomas <gthomas@cygnus.co.uk> + + * src/hal_stub.c (__do_copy_mem): Move temp variables to top of + function - potentially safer if there is an error. + +1999-08-23 Jonathan Larmour <jlarmour@cygnus.co.uk> + + * src/generic-stub.c (__process_packet): For 'g' and 'G' packets, + when the register size differs from sizeof(target_register_t) we must + adjust according to the endianness + + * include/hal_stub.h: Ensure __LITTLE_ENDIAN__ is defined on + little-endian targets + + * src/hal_stub.c (__build_t_packet): Use the correct register sizes + for PC and SP rather than assuming they are the same as target_register_t + +1999-08-23 Gary Thomas <gthomas@cygnus.co.uk> + + * include/generic-stub.h: Change prototypes for internal functions. + + * src/hal_stub.c (__do_copy_mem): + * src/generic-stub.c (__mem2hex_helper): Rework to perform aligned, + multi-byte operations when conditions allow. This should handle + most "hardware register" access cases. Note: there currently is + no good way to force GDB to require/use such accesses. + 1999-08-17 Jonathan Larmour <jlarmour@cygnus.co.uk> * tests/intr.c (cyg_start): Use CYG_TEST_NA rather than a pass saying
--- a/packages/hal/common/current/include/generic-stub.h +++ b/packages/hal/common/current/include/generic-stub.h @@ -101,16 +101,16 @@ extern void __send_exit_status (int stat ADDR is assumed to live in the user program's space. Returns number of bytes successfully read (caller must check to see if less than requested). */ -extern int __read_mem_safe (unsigned char *buf, - target_register_t addr, +extern int __read_mem_safe (void *buf, + void *addr, int count); /* Copy COUNT bytes of memory from BUF to ADDR. ADDR is assumed to live in the user program's space. Returns number of bytes successfully read (caller must check to see if less than requested). */ -extern int __write_mem_safe (unsigned char *buf, - target_register_t addr, +extern int __write_mem_safe (void *buf, + void *addr, int count); /* Set to a non-zero value if a memory fault occurs while
--- a/packages/hal/common/current/include/hal_stub.h +++ b/packages/hal/common/current/include/hal_stub.h @@ -51,7 +51,7 @@ #include <cyg/hal/basetype.h> // HAL_LABEL_NAME #include <cyg/hal/hal_arch.h> // HAL header -#include <cyg/infra/cyg_type.h> +#include <cyg/infra/cyg_type.h> // cyg_uint32 and CYG_BYTEORDER typedef cyg_uint32 uint32; #include <cyg/hal/plf_stub.h> @@ -66,6 +66,11 @@ extern "C" { #define __set_mem_fault_trap(x) ({__mem_fault = 0; x(); __mem_fault;}) +#if (CYG_BYTEORDER==CYG_LSBFIRST) && \ + (!defined(__LITTLE_ENDIAN__) || !defined(_LITTLE_ENDIAN)) +# define __LITTLE_ENDIAN__ +#endif + //---------------------------------------------------------------------------- // Signal definitions to avoid 'signal.h'/ #define SIGHUP 1 /* hangup */
--- a/packages/hal/common/current/include/pkgconf/hal.h +++ b/packages/hal/common/current/include/pkgconf/hal.h @@ -460,9 +460,8 @@ #endif -#if defined(CYGPKG_HAL_MIPS) || defined(CYGPKG_HAL_MN10300) #include CYGBLD_HAL_TARGET_H -#endif +#include CYGBLD_HAL_PLATFORM_H /* -------------------------------------------------------------------*/ #endif /* CYGONCE_PKGCONF_HAL_H */
--- a/packages/hal/common/current/src/generic-stub.c +++ b/packages/hal/common/current/src/generic-stub.c @@ -391,7 +391,7 @@ static void */ int -__read_mem_safe (unsigned char *dst, target_register_t src, int count) +__read_mem_safe (void *dst, target_register_t src, int count) { memCount = count; memSrc = (unsigned char *) src; @@ -429,23 +429,45 @@ static int may_fault_mode; static void __mem2hex_helper (void) { - __mem_fault = 0; - while (hexMemCount-- > 0) - { - unsigned char ch; + union { + unsigned long long_val; + unsigned char bytes[sizeof(long)]; + } val; + int len, i; + unsigned char ch; + __mem_fault = 0; + while (hexMemCount > 0) { + if (may_fault_mode) { + if ((hexMemCount >= sizeof(long)) && + (((target_register_t)hexMemSrc & (sizeof(long)-1)) == 0)) { + // Should be safe to access via a long + len = sizeof(long); + } else if ((hexMemCount >= sizeof(short)) && + (((target_register_t)hexMemSrc & (sizeof(short)-1)) == 0)) { + // Should be safe to access via a short + len = sizeof(short); + } else { + len = 1; + } + __read_mem_safe(&val.bytes[0], hexMemSrc, len); + } else { + len = 1; + val.bytes[0] = *hexMemSrc; + } + if (__mem_fault) + return; - if (may_fault_mode) - __read_mem_safe (&ch, (target_register_t) (hexMemSrc++), 1); - else - ch = *(hexMemSrc++); - if (__mem_fault) - return; - *(hexMemDst++) = hexchars[(ch >> 4) & 0xf]; - if (__mem_fault) - return; - *(hexMemDst++) = hexchars[ch & 0xf]; - if (__mem_fault) - return; + for (i = 0; i < len; i++) { + ch = val.bytes[i]; + *(hexMemDst++) = hexchars[(ch >> 4) & 0xf]; + if (__mem_fault) + return; + *(hexMemDst++) = hexchars[ch & 0xf]; + if (__mem_fault) + return; + } + hexMemCount -= len; + hexMemSrc += len; } } @@ -486,24 +508,49 @@ char * static void __hex2mem_helper (void) { - target_register_t i; - unsigned char ch; + union { + unsigned long long_val; + unsigned char bytes[sizeof(long)]; + } val; + int len, i; + unsigned char ch = '\0'; - __mem_fault = 0; - for (i=0; i < hexMemCount && *hexMemSrc; i++) - { - ch = stubhex (*(hexMemSrc++)) << 4; - if (__mem_fault) - return; - ch |= stubhex (*(hexMemSrc++)); - if (__mem_fault) - return; - if (may_fault_mode) - __write_mem_safe (&ch, (target_register_t) (hexMemDst++), 1); - else - *(hexMemDst++) = ch; - if (__mem_fault) - return; + __mem_fault = 0; + while (hexMemCount > 0 && *hexMemSrc) { + if (may_fault_mode) { + if ((hexMemCount >= sizeof(long)) && + (((target_register_t)hexMemDst & (sizeof(long)-1)) == 0)) { + len = sizeof(long); + } else if ((hexMemCount >= sizeof(short)) && + (((target_register_t)hexMemDst & (sizeof(short)-1)) == 0)) { + len = sizeof(short); + } else { + len = 1; + } + } else { + len = 1; + } + + for (i = 0; i < len; i++) { + // Check for short data? + ch = stubhex (*(hexMemSrc++)) << 4; + if (__mem_fault) + return; + ch |= stubhex (*(hexMemSrc++)); + if (__mem_fault) + return; + val.bytes[i] = ch; + } + + if (may_fault_mode) + __write_mem_safe (&val.bytes[0], hexMemDst, len); + else + *hexMemDst = ch; + + if (__mem_fault) + return; + hexMemCount -= len; + hexMemDst += len; } } @@ -831,8 +878,16 @@ int else addr = get_register (regnum); - vptr = ((char *) &addr) + sizeof (addr) - REGSIZE (regnum); - if (sizeof (addr) < REGSIZE (regnum)) + vptr = ((char *) &addr); + if (sizeof (addr) > REGSIZE(regnum)) + { + /* May need to cope with endian-ness */ + +#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN) + vptr += sizeof (addr) - REGSIZE (regnum); +#endif + } + else if (sizeof (addr) < REGSIZE (regnum)) { int off = REGSIZE (regnum) - sizeof (addr); int x; @@ -944,7 +999,10 @@ int else #endif { - vptr = ((char *) &value) + sizeof (value) - REGSIZE (x); + vptr = ((char *) &value); +#if !defined(__LITTLE_ENDIAN__) && !defined(_LITTLE_ENDIAN) + vptr += sizeof (value) - REGSIZE (x); +#endif __hex2mem (ptr, vptr, REGSIZE (x), 0); put_register (x, value); } @@ -999,7 +1057,7 @@ int if ((buf[i] = *ptr++) == 0x7d) buf[i] = 0x20 | (*ptr++ & 0xff); - if (__write_mem_safe (buf, addr, i) != i) + if (__write_mem_safe (buf, (void *)addr, i) != i) break; length -= i; @@ -1229,11 +1287,11 @@ int { d = stubhex (remcomInBuffer[3 + i * 2]) * 16; d |= stubhex (remcomInBuffer[3 + i * 2 + 1]); - __write_mem_safe (&d, dest + i, 1); + __write_mem_safe (&d, (void *)(dest + i), 1); } /* Write the trailing \0. */ d = '\0'; - __write_mem_safe (&d, dest + i, 1); + __write_mem_safe (&d, (void *)(dest + i), 1); return len; } @@ -1292,7 +1350,7 @@ int { char c; - __read_mem_safe (&c, str + x, 1); + __read_mem_safe (&c, (void *)(str + x), 1); buf[x*2+1] = hexchars[(c >> 4) & 0xf]; buf[x*2+2] = hexchars[c % 16]; } @@ -1434,7 +1492,7 @@ char ** { __free_program_args (); } - __write_mem_safe ((char *) &program_argc, argcPtr, sizeof (program_argc)); + __write_mem_safe ((char *) &program_argc, (void *)argcPtr, sizeof (program_argc)); return program_argv; } @@ -1473,7 +1531,7 @@ crc32 (ptr, len, crc) { unsigned char ch; - __read_mem_safe (&ch, (target_register_t) ptr, 1); + __read_mem_safe (&ch, (void *)ptr, 1); if (__mem_fault) { break;
--- a/packages/hal/common/current/src/hal_stub.c +++ b/packages/hal/common/current/src/hal_stub.c @@ -390,13 +390,13 @@ void *ptr++ = __tohex (PC); *ptr++ = ':'; addr = get_register (PC); - ptr = __mem2hex((char *)&addr, ptr, sizeof(addr), 0); + ptr = __mem2hex((char *)&addr, ptr, REGSIZE(PC), 0); *ptr++ = ';'; *ptr++ = __tohex (SP >> 4); *ptr++ = __tohex (SP); *ptr++ = ':'; - ptr = __mem2hex((char *)&sp, ptr, sizeof(sp), 0); + ptr = __mem2hex((char *)&sp, ptr, REGSIZE(SP), 0); *ptr++ = ';'; *ptr++ = 0; @@ -481,20 +481,51 @@ static volatile target_register_t memCou static void __do_copy_mem (unsigned char* src, unsigned char* dst) { - __mem_fault = 1; // Defaults to 'fail'. Is cleared - // when the copy loop completes. - __mem_fault_handler = &&err; + unsigned long *long_dst; + unsigned long *long_src; + unsigned short *short_dst; + unsigned short *short_src; + + __mem_fault = 1; /* Defaults to 'fail'. Is cleared */ + /* when the copy loop completes. */ + __mem_fault_handler = &&err; + + // See if it's safe to do multi-byte, aligned operations + while (memCount) { + if ((memCount >= sizeof(long)) && + (((target_register_t)dst & (sizeof(long)-1)) == 0) && + (((target_register_t)src & (sizeof(long)-1)) == 0)) { + + long_dst = (unsigned long *)dst; + long_src = (unsigned long *)src; - while (memCount) - { - *dst++ = *src++; - memCount--; + *long_dst++ = *long_src++; + memCount -= sizeof(long); + + dst = (unsigned char *)long_dst; + src = (unsigned char *)long_src; + } else if ((memCount >= sizeof(short)) && + (((target_register_t)dst & (sizeof(short)-1)) == 0) && + (((target_register_t)src & (sizeof(short)-1)) == 0)) { + + short_dst = (unsigned short *)dst; + short_src = (unsigned short *)src; + + *short_dst++ = *short_src++; + memCount -= sizeof(short); + + dst = (unsigned char *)short_dst; + src = (unsigned char *)short_src; + } else { + *dst++ = *src++; + memCount--; + } } - __mem_fault = 0; + __mem_fault = 0; err: - __mem_fault_handler = (void *)0; + __mem_fault_handler = (void *)0; } /* @@ -503,7 +534,7 @@ static void */ int -__read_mem_safe (unsigned char *dst, target_register_t src, int count) +__read_mem_safe (void *dst, void *src, int count) { memCount = count; __do_copy_mem((unsigned char*) src, (unsigned char*) dst); @@ -516,7 +547,7 @@ int */ int -__write_mem_safe (unsigned char *src, target_register_t dst, int count) +__write_mem_safe (void *src, void *dst, int count) { memCount = count; __do_copy_mem((unsigned char*) src, (unsigned char*) dst);
--- a/packages/hal/mips/arch/current/ChangeLog +++ b/packages/hal/mips/arch/current/ChangeLog @@ -1,3 +1,7 @@ +1999-08-19 Nick Garnett <nickg@cygnus.co.uk> + + * include/hal_io.h: Added include of plf_io.h. + 1999-08-10 Jonathan Larmour <jlarmour@cygnus.co.uk> * src/mipsfp.c (cyg_hal_mips_process_fpe): CYG_REPORT_FUNCNAMETYPE()
--- a/packages/hal/mips/arch/current/include/hal_io.h +++ b/packages/hal/mips/arch/current/include/hal_io.h @@ -48,8 +48,12 @@ // //============================================================================= +#include <pkgconf/hal.h> + #include <cyg/infra/cyg_type.h> +#include <cyg/hal/plf_io.h> + //----------------------------------------------------------------------------- // IO Register address. // This type is for recording the address of an IO register. @@ -128,7 +132,7 @@ typedef volatile CYG_ADDRWORD HAL_IO_REG for( _i_ = 0, _j_ = 0; _i_ < (_count_); _i_++, _j_ += (_step_)) \ ((volatile CYG_WORD32 *)(_register_))[_j_] = (_buf_)[_i_]; \ } - + //----------------------------------------------------------------------------- #endif // ifndef CYGONCE_HAL_HAL_IO_H // End of hal_io.h
--- a/packages/hal/mips/jmr3904/current/ChangeLog +++ b/packages/hal/mips/jmr3904/current/ChangeLog @@ -1,3 +1,18 @@ +1999-08-25 Nick Garnett <nickg@cygnus.co.uk> + + * include/platform.inc: Rearranged code a little to avoid + assembler warning messages. + + * src/plf_misc.c (hal_platform_init): No longer disable cache when + enabling TOE. A better solution to this has been made elsewhere. + + * include/pkgconf/hal_mips_tx39_jmr3904.h: Removed some now-bogus + comments and generally tidied things a little. + +1999-08-19 Nick Garnett <nickg@cygnus.co.uk> + + * include/plf_io.h: Added this file to match other platforms. + 1999-06-21 Nick Garnett <nickg@cygnus.co.uk> * src/plf_misc.c (hal_ctrlc_isr): Changed return value from 0 to 2
--- a/packages/hal/mips/jmr3904/current/include/pkgconf/hal_mips_tx39_jmr3904.h +++ b/packages/hal/mips/jmr3904/current/include/pkgconf/hal_mips_tx39_jmr3904.h @@ -94,14 +94,14 @@ #define CYGHWR_HAL_MIPS_TX39_JMR3904_DRAM_CONFIG_INIT 0x08024030 // 16MByte //#define CYGHWR_HAL_MIPS_TX39_JMR3904_DRAM_CONFIG_INIT 0x08013020 // 4 or 8MByte -/* Bus Timeout Detection */ +/* -------------------------------------------------------------------*/ +/* Bus Timeout Detection */ + -/* Note: If you enable this option the caches are disabled by default. - * If you enable caches in your code, Spurious Bus Time Outs might - * fire. - */ +//#define CYGHWR_HAL_MIPS_TX39_JMR3904_ENABLE_TOE -// #define CYGHWR_HAL_MIPS_TX39_JMR3904_ENABLE_TOE +/* -------------------------------------------------------------------*/ +/* Clock frequency initialization */ #include <pkgconf/hal_mips.h> // Make sure clock frequency is defined
--- a/packages/hal/mips/jmr3904/current/include/platform.inc +++ b/packages/hal/mips/jmr3904/current/include/platform.inc @@ -53,7 +53,6 @@ #ifndef CYGPKG_HAL_MIPS_MON_DEFINED - .macro hal_mon_init #if defined(CYG_HAL_STARTUP_ROM) || \ ( defined(CYG_HAL_STARTUP_RAM) && \ !defined(CYG_HAL_USE_ROM_MONITOR)) @@ -61,6 +60,7 @@ # If we are starting up from ROM, or we are starting in # RAM and NOT using a ROM monitor, initialize the VSR table. + .macro hal_mon_init la a0,__default_interrupt_vsr la a1,__default_exception_vsr la a3,hal_vsr_table @@ -83,22 +83,27 @@ sw a1,32*4(a3) sw a1,33*4(a3) + .endm -#endif - -#if defined(CYG_HAL_STARTUP_RAM) && defined(CYG_HAL_USE_ROM_MONITOR) +#elif defined(CYG_HAL_STARTUP_RAM) && defined(CYG_HAL_USE_ROM_MONITOR) # Initialize the VSR table entries # We only take control of the interrupt vector, # the rest are left to the ROM for now... + .macro hal_mon_init la a0,__default_interrupt_vsr la a3,hal_vsr_table sw a0,0(a3) - + .endm + +#else + + .macro hal_mon_init + .endm + #endif - .endm #define CYGPKG_HAL_MIPS_MON_DEFINED
new file mode 100644 --- /dev/null +++ b/packages/hal/mips/jmr3904/current/include/plf_io.h @@ -0,0 +1,54 @@ +#ifndef CYGONCE_PLF_IO_H +#define CYGONCE_PLF_IO_H + +//============================================================================= +// +// plf_io.h +// +// Platform specific IO support +// +//============================================================================= +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): hmt, jskov, nickg +// Contributors: hmt, jskov, nickg +// Date: 1999-08-09 +// Purpose: JMR3904 platform IO support +// Description: +// Usage: #include <cyg/hal/plf_io.h> +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/hal.h> + +//----------------------------------------------------------------------------- + +// Nothing here. + +//----------------------------------------------------------------------------- +// end of plf_io.h +#endif // CYGONCE_PLF_IO_H
--- a/packages/hal/mips/jmr3904/current/src/plf_misc.c +++ b/packages/hal/mips/jmr3904/current/src/plf_misc.c @@ -60,29 +60,18 @@ extern void patch_dbg_syscalls(void * ve void hal_platform_init(void) { - // On the real hardware we also enable the cache. - // doing this here is a temporary measure until we - // have a proper platform specific place to do it. - -#if !defined(CYGHWR_HAL_TX39_JMR3904_ENABLE_TOE) HAL_ICACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_INVALIDATE_ALL(); HAL_DCACHE_ENABLE(); +#if !defined(CYGHWR_HAL_MIPS_TX39_JMR3904_ENABLE_TOE) + HAL_TX39_DEBUG_TOE_DISABLE(); #else - // If TOE is enabled, caches are disabled by default - // until spurious Bus Timeout problem is fixed. - - HAL_ICACHE_INVALIDATE_ALL(); - HAL_ICACHE_DISABLE(); - HAL_DCACHE_INVALIDATE_ALL(); - HAL_DCACHE_DISABLE(); - HAL_TX39_DEBUG_TOE_ENABLE(); #endif
--- a/packages/hal/mips/sim/current/ChangeLog +++ b/packages/hal/mips/sim/current/ChangeLog @@ -1,3 +1,7 @@ +1999-08-19 Nick Garnett <nickg@cygnus.co.uk> + + * include/plf_io.h: Added this file to match other platforms. + 1999-06-21 Nick Garnett <nickg@cygnus.co.uk> * src/plf_misc.c: Added hal_saved_interrupt_state variable to
new file mode 100644 --- /dev/null +++ b/packages/hal/mips/sim/current/include/plf_io.h @@ -0,0 +1,54 @@ +#ifndef CYGONCE_PLF_IO_H +#define CYGONCE_PLF_IO_H + +//============================================================================= +// +// plf_io.h +// +// Platform specific IO support +// +//============================================================================= +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): hmt, jskov, nickg +// Contributors: hmt, jskov, nickg +// Date: 1999-08-09 +// Purpose: Platform IO support +// Description: +// Usage: #include <cyg/hal/plf_io.h> +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include <pkgconf/hal.h> + +//----------------------------------------------------------------------------- + +// Nothing here. + +//----------------------------------------------------------------------------- +// end of plf_io.h +#endif // CYGONCE_PLF_IO_H
--- a/packages/hal/mips/tx39/current/ChangeLog +++ b/packages/hal/mips/tx39/current/ChangeLog @@ -1,3 +1,16 @@ +1999-08-25 Nick Garnett <nickg@cygnus.co.uk> + + * include/variant.inc: Added clock-speed dependent values for the + DRAM DWR0 register. Values as suggested by Toshiba in PR20094. + Added improved work-around for TOE problem suggested by Toshiba + in PR20233. + Some code rearranged to eliminate assembler warning messages. + Some general tidying. + + * include/var_cache.h (HAL_ICACHE_DISABLE): Added jump to aligned + label after disable to avoid potential race with cache. Suggested + by Toshiba in PR20091. + 1999-06-18 Nick Garnett <nickg@cygnus.co.uk> * include/var_intr.h: Added TX39 specific variant of
--- a/packages/hal/mips/tx39/current/include/var_cache.h +++ b/packages/hal/mips/tx39/current/include/var_cache.h @@ -214,6 +214,10 @@ "la $3,0xFFFFFFDF;" \ "and $2,$2,$3;" \ "mtc0 $2,$3;" \ + "j 1f;" \ + "nop;" \ + ".balign 16,0;" \ + "1:;" \ : \ : \ : "$2", "$3" \
--- a/packages/hal/mips/tx39/current/include/variant.inc +++ b/packages/hal/mips/tx39/current/include/variant.inc @@ -1,8 +1,8 @@ -#ifndef CYGONCE_HAL_IMPL_INC -#define CYGONCE_HAL_IMPL_INC +#ifndef CYGONCE_HAL_VARIANT_INC +#define CYGONCE_HAL_VARIANT_INC ##============================================================================= ## -## impl.inc +## variant.inc ## ## TX39 family assembler header file ## @@ -38,7 +38,7 @@ ## Description: This file contains various definitions and macros that are ## useful for writing assembly code for the TX39 CPU family. ## Usage: -## #include <cyg/hal/impl.inc> +## #include <cyg/hal/variant.inc> ## ... ## ## @@ -46,12 +46,12 @@ ## ##============================================================================= +#include <pkgconf/hal.h> + #include <cyg/hal/mips.inc> #include <cyg/hal/platform.inc> -#include <pkgconf/hal.h> - ##----------------------------------------------------------------------------- ## Define CPU variant for architecture HAL. @@ -73,9 +73,11 @@ #if (CYGHWR_HAL_MIPS_CPU_FREQ == 50) #define ROM_CCR0_INIT 0x00000420 #define DRAM_DREFC_INIT 0x00000180 +#define DRAM_DWR0_INIT 0x00111111 #elif (CYGHWR_HAL_MIPS_CPU_FREQ == 66) #define ROM_CCR0_INIT 0x00000520 #define DRAM_DREFC_INIT 0x00000200 +#define DRAM_DWR0_INIT 0x00332222 #else #error Unsupported clock frequency #endif @@ -90,10 +92,25 @@ #else #define DRAM_CONFIG_INIT 0x08024030 #endif - -#ifdef CYG_HAL_MIPS_JMR3904 + +## Enabling timeout exceptions can result in bogus exceptions under the +## following conditions: +## o half speed bus mode (JMR board uses this mode) +## o code resides on 0 wait SRAM +## o I- and D- caches are enabled +## o a very narrow timing condition of cache refill cycle (not +## descibed here) +## The simple solution is to configure 1 cycle wait state SRAM rather +## than zero. + +#ifdef CYGHWR_HAL_MIPS_TX39_JMR3904_ENABLE_TOE +#define SRAM_WAIT_INIT 0x00000100 +#else +#define SRAM_WAIT_INIT 0x00000000 +#endif + .macro hal_memc_init - + # These mappings need to be set up before we # can use the stack and make calls to other # functions @@ -122,7 +139,7 @@ # SRAM config la v0,0xffff9100 - la v1,0x00000000 + la v1,SRAM_WAIT_INIT sw v1,0(v0) # ISA bus setup @@ -135,10 +152,16 @@ la v1,0x00000000 sw v1,0(v0) + hal_memc_init_dram + + .endm + + #if defined(CYG_HAL_STARTUP_ROM) # Only do this in ROM configurations. - + + .macro hal_memc_init_dram # DRAM Configuration la v0, 0xffff8000 la v1, DRAM_CONFIG_INIT @@ -151,19 +174,22 @@ # DWR0 la v0, 0xffff8008 - la v1, 0x00000000 + la v1, DRAM_DWR0_INIT sw v1, 0(v0) # DREFC - Depends on clock requency la v0, 0xffff8800 la v1, DRAM_DREFC_INIT sw v1, 0(v0) + .endm +#else + .macro hal_memc_init_dram + .endm #endif - .endm -#endif - +#define CYGPKG_HAL_MIPS_MEMC_DEFINED + #endif ##----------------------------------------------------------------------------- @@ -235,5 +261,5 @@ hal_intc_translation_table: #endif #------------------------------------------------------------------------------ -#endif // ifndef CYGONCE_HAL_IMPL_INC -# end of impl.inc +#endif // ifndef CYGONCE_HAL_VARIANT_INC +# end of variant.inc
--- a/packages/hal/mn10300/stdeval1/current/ChangeLog +++ b/packages/hal/mn10300/stdeval1/current/ChangeLog @@ -1,3 +1,9 @@ +1999-08-27 Nick Garnett <nickg@cygnus.co.uk> + + * src/hal_diag.c (hal_diag_write_char): Added code to disable + watchdog while emitting a debug message. This is solely to cope + with shortcomings in the test farm. + 1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk> * include/pkgconf/hal_mn10300_am32_stdeval1.h:
--- a/packages/hal/mn10300/stdeval1/current/src/hal_diag.c +++ b/packages/hal/mn10300/stdeval1/current/src/hal_diag.c @@ -425,7 +425,16 @@ void hal_diag_write_char(char c) // later. CYG_INTERRUPT_STATE oldstate; + CYG_BYTE wdcr; HAL_DISABLE_INTERRUPTS(oldstate); + + // Beacuse of problems with NT on the testfarm, we also have + // to disable the watchdog here. This only matters in the + // watchdog tests. And yes, this sends my irony meter off the + // scale too. + + HAL_READ_UINT8( 0x34004002, wdcr ); + HAL_WRITE_UINT8( 0x34004002, wdcr&0x3F ); while(1) { @@ -471,6 +480,7 @@ void hal_diag_write_char(char c) // And re-enable interrupts HAL_RESTORE_INTERRUPTS(oldstate); + HAL_WRITE_UINT8( 0x34004002, wdcr ); }
--- a/packages/hal/powerpc/arch/current/ChangeLog +++ b/packages/hal/powerpc/arch/current/ChangeLog @@ -1,3 +1,15 @@ +1999-09-01 Gary Thomas <gthomas@cygnus.co.uk> + + * src/hal_misc.c: Clean up list of included files. <hal.h> + now provides target and platform specifics. + + * src/hal_intr.c: CYGFUN_HAL_COMMON_KERNEL_SUPPORT should only + be defined if CYGPKG_KERNEL is defined. This needs to be fixed + in a more generic fashion when full CDL becomes available. + + * src/vectors.S: Exception and interrupt handling were enabling + CPU interrupts when it wasn't safe nor warranted. + 1999-08-16 Bob Koninckx <bob.koninckx@mail.mech.kuleuven.ac.be> * src/ppc_stub.c (__clear_single_step): Clear irq_state to prevent
--- a/packages/hal/powerpc/arch/current/src/hal_intr.c +++ b/packages/hal/powerpc/arch/current/src/hal_intr.c @@ -44,6 +44,11 @@ #include <cyg/hal/ppc_regs.h> +// REMINDER: Full CDL required to enforce this +#ifndef CYGPKG_KERNEL +#undef CYGFUN_HAL_COMMON_KERNEL_SUPPORT +#endif + // These are the Cyg_Interrupt::HANDLED/CALL_DSR values. #define Cyg_InterruptHANDLED 1 #define Cyg_InterruptCALL_DSR 2
--- a/packages/hal/powerpc/arch/current/src/hal_misc.c +++ b/packages/hal/powerpc/arch/current/src/hal_misc.c @@ -42,10 +42,7 @@ // //=========================================================================== -#include <pkgconf/system.h> #include <pkgconf/hal.h> -#include CYGBLD_HAL_TARGET_H -#include CYGBLD_HAL_PLATFORM_H #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS #include <cyg/hal/ppc_regs.h> // SPR definitions
--- a/packages/hal/powerpc/arch/current/src/vectors.S +++ b/packages/hal/powerpc/arch/current/src/vectors.S @@ -92,6 +92,8 @@ #define CYG_MSR (CYG_MSR_COMMON & ~(MSR_IR | MSR_DR)) #endif +#define CYG_MSR_NO_INTS (CYG_MSR & ~MSR_ME) + #=========================================================================== # If the following option is enabled, we only save registers up to R12. # The PowerPC ABI defines registers 13..31 as callee saved and thus we do @@ -383,7 +385,7 @@ 2: bl hal_MMU_init # Enable MMU it so we can safely enable caches. - lwi r3,CYG_MSR + lwi r3,CYG_MSR_NO_INTS # interrupts enabled later sync mtmsr r3 sync @@ -444,7 +446,7 @@ 9: stw r5,ppcreg_lr(r1) # stash LR # Enable MMU. - lwi r3,CYG_MSR + lwi r3,CYG_MSR_NO_INTS sync mtmsr r3 sync @@ -588,7 +590,7 @@ 0: stw \dreg,ppcreg_vector(\sta stw r5,ppcreg_lr(r1) # stash LR # Enable MMU. - lwi r3,CYG_MSR + lwi r3,CYG_MSR_NO_INTS sync mtmsr r3 sync @@ -821,7 +823,7 @@ restore_state: mtcr r3 # set ccr - lwi r3,CYG_MSR # do rest with ints disabled + lwi r3,CYG_MSR_NO_INTS # do rest with ints disabled sync mtmsr r3 sync
--- a/packages/hal/powerpc/cogent/current/ChangeLog +++ b/packages/hal/powerpc/cogent/current/ChangeLog @@ -1,3 +1,7 @@ +1999-09-02 Jesper Skov <jskov@cygnus.co.uk> + + * misc/STUBS_config: Added. + 1999-06-11 Hugo Tyson <hmt@cygnus.co.uk> * src/PKGconf.mak: Build the new file.
new file mode 100644 --- /dev/null +++ b/packages/hal/powerpc/cogent/current/misc/STUBS_config @@ -0,0 +1,49 @@ +#! /bin/sh +# Configure PowerPC/cogent eCos to create Cogent GDB stubs +# Ensure that PATH include the directory where the PPC tools reside. +# +# Run from an empty temporary directory with one argument: the path to +# the packages directory (i.e., where pkgconf.tcl lives). +# +# Output will be ./stubrom.bin which is suitable for burning into ROM. +# Remember to be careful with byte-endianess in the ROM programmer. + +tcl $1/pkgconf.tcl \ + --target=powerpc --platform=cogent --startup=stubs \ + --disable CYGPKG_KERNEL --disable CYGPKG_UITRON \ + --disable CYGPKG_LIBC --disable CYGPKG_LIBM \ + --disable CYGPKG_ERROR --disable CYGPKG_IO \ + --disable CYGPKG_IO_SERIAL --disable CYGPKG_DEVICES_WALLCLOCK \ + --disable CYGPKG_DEVICES_WATCHDOG + +patch <<END_OF_PATCH -p0 +--- pkgconf/hal.h~ Thu Jul 8 08:26:44 1999 ++++ pkgconf/hal.h Wed Jul 28 10:51:07 1999 +@@ -110,7 +110,7 @@ + } + + }}CFG_DATA */ +-#define CYGFUN_HAL_COMMON_KERNEL_SUPPORT ++#undef CYGFUN_HAL_COMMON_KERNEL_SUPPORT + + /* {{CFG_DATA + +@@ -369,10 +369,10 @@ + + }}CFG_DATA */ + +-#undef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS ++#define CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS + #undef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT +-#define CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT +-#define CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT ++#undef CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT ++#undef CYGDBG_HAL_DEBUG_GDB_THREAD_SUPPORT + + /* + * NOTE: +END_OF_PATCH + +make +make -C hal/common/current/src/stubrom +powerpc-eabi-objcopy -O binary hal/common/current/src/stubrom/stubrom stubrom.bin
--- a/packages/hal/powerpc/fads/current/ChangeLog +++ b/packages/hal/powerpc/fads/current/ChangeLog @@ -1,3 +1,20 @@ +1999-09-02 Hugo Tyson <hmt@cygnus.co.uk> + + * src/hal_aux.c (CYGARC_MEMDESC_TABLE): Define a non-empty table + for the FADS board so that MM can be enabled. I don't know why + the ROM area is marked non-cachable, but that's as the reporter + requested. + + As requested in PR 20270 by not-a-customer. This is really a + merge of that fix. + + * src/quicc_smc2.c (cyg_smc2_init): Re-order initialization so + that RxTxBD *is* initialized before use. Move setup of rx/tx + params to the end of the function ie. after the data is set up. + + All as requested in PR 20271 by not-a-customer. This is really a + merge of that fix. + 1999-06-11 Hugo Tyson <hmt@cygnus.co.uk> * src/PKGconf.mak: Build the new file.
--- a/packages/hal/powerpc/fads/current/src/hal_aux.c +++ b/packages/hal/powerpc/fads/current/src/hal_aux.c @@ -51,7 +51,16 @@ #include <cyg/hal/hal_cache.h> // Cache macros // The memory map is weakly defined, allowing the application to redefine -// it if necessary. The FADS board requires no regions. -CYGARC_MEMDESC_TABLE CYGBLD_ATTRIB_WEAK = CYGARC_MEMDESC_EMPTY_TABLE; +// it if necessary. The regions defined below are the minimum requirements. +CYGARC_MEMDESC_TABLE CYGBLD_ATTRIB_WEAK = { + // Mapping for the FADS POWERPC development board + CYGARC_MEMDESC_NOCACHE( 0x02800000, 0x00100000 ), // ROM region + CYGARC_MEMDESC_NOCACHE( 0x02200000, 0x00010000 ), // MCP registers/PRAM/DPRAM 64 kByte + CYGARC_MEMDESC_NOCACHE( 0x02100000, 0x00001000 ), // 4 kByte Board Control + CYGARC_MEMDESC_CACHE( 0x00000000, 0x00400000 ), // main memory + + CYGARC_MEMDESC_TABLE_END +}; + // EOF hal_aux.c
--- a/packages/hal/powerpc/fads/current/src/quicc_smc2.c +++ b/packages/hal/powerpc/fads/current/src/quicc_smc2.c @@ -133,6 +133,14 @@ void cyg_smc2_init(unsigned long baudRat IMMR->si_simode |= 0x10000000; /* SCM2: Tx/Rx Clocks are BRG2 */ + /*--------------------*/ + /* Initialize the BDs */ + /*--------------------*/ + + InitBDs(); /* before setting up info depending on RxTxBD below */ + + IMMR->smc_regs[SMC2_REG].smc_smce = 0xFF; /* Clear any pending events */ + /*----------------------------------------*/ /* Set RXBD table start at Dual Port +800 */ /*----------------------------------------*/ @@ -145,14 +153,7 @@ void cyg_smc2_init(unsigned long baudRat IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.tbase = (unsigned short) (unsigned) &RxTxBD->TxBD; - /*---------------------------------------*/ - /* Initialize Rx and Tx Params for SMC2: */ - /* Spin until cpcr flag is cleared */ - /*---------------------------------------*/ - for(IMMR->cp_cr = 0x00d1; IMMR->cp_cr & 0x0001;) ; - - /*--------------------------------------*/ /* Set RFCR,TFCR -- Rx,Tx Function Code */ /* Normal Operation and Motorola byte */ @@ -190,12 +191,8 @@ void cyg_smc2_init(unsigned long baudRat IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.brkcr = 1; - /*--------------------*/ - /* Initialize the BDs */ - /*--------------------*/ - InitBDs(); - + /* InitBDs() used to be here - no harm in doing this again */ IMMR->smc_regs[SMC2_REG].smc_smce = 0xFF; /* Clear any pending events */ /*--------------------------------------------------*/ @@ -217,6 +214,13 @@ void cyg_smc2_init(unsigned long baudRat IMMR->smc_regs[SMC2_REG].smc_smcmr = 0x4823; + /*---------------------------------------*/ + /* Initialize Rx and Tx Params for SMC2: */ + /* Spin until cpcr flag is cleared */ + /*---------------------------------------*/ + + for(IMMR->cp_cr = 0x00d1; IMMR->cp_cr & 0x0001;) ; + }
--- a/packages/hal/powerpc/quicc/current/ChangeLog +++ b/packages/hal/powerpc/quicc/current/ChangeLog @@ -1,3 +1,7 @@ +1999-09-01 Gary Thomas <gthomas@cygnus.co.uk> + + * include/ppc8xx.h: Add some missing definitions (MAR, MBMR). + 1999-06-27 Gary Thomas <gthomas@cygnus.co.uk> * src/quicc_smc1.c: Many changes which allow these routines to
--- a/packages/hal/powerpc/quicc/current/include/ppc8xx.h +++ b/packages/hal/powerpc/quicc/current/include/ppc8xx.h @@ -73,8 +73,10 @@ #define OR6 0x134 /* Option Register 2 */ #define BR7 0x138 /* Base Register 2 */ #define OR7 0x13C /* Option Register 2 */ +#define MAR 0x164 /* Memory Address */ #define MCR 0x168 /* Memory Command */ #define MAMR 0x170 /* Machine A Mode Register */ +#define MBMR 0x174 /* Machine B Mode Register */ #define MPTPR 0x17A /* Memory Periodic Timer Prescaler */ #define MDR 0x17C /* Memory Data */ #define TBSCR 0x200 /* Time Base Status and Control Register */
--- a/packages/hal/powerpc/quicc/current/src/quicc_smc1.c +++ b/packages/hal/powerpc/quicc/current/src/quicc_smc1.c @@ -42,16 +42,12 @@ // //========================================================================== -#include <pkgconf/system.h> #include <pkgconf/hal.h> #include <cyg/infra/cyg_type.h> #include <cyg/hal/hal_cache.h> #ifdef CYG_HAL_POWERPC_MPC860 -#include CYGBLD_HAL_TARGET_H -#include CYGBLD_HAL_PLATFORM_H - // eCos headers decribing PowerQUICC: #include <cyg/hal/quicc/ppc8xx.h> @@ -136,6 +132,7 @@ init_smc1_uart(void) #endif #endif + /* * NMSI mode, BRG1 to SMC1 * (Section 16.12.5.2)
--- a/packages/io/serial/current/ChangeLog +++ b/packages/io/serial/current/ChangeLog @@ -1,3 +1,16 @@ +1999-08-31 Jesper Skov <jskov@cygnus.co.uk> + + * tests/ser_test_protocol.inl: Define dummy crash ID. + +1999-08-30 Jesper Skov <jskov@cygnus.co.uk> + + * tests/ser_test_protocol.inl: Added crash information which + should help track down repeating errors. + +1999-08-20 Jesper Skov <jskov@cygnus.co.uk> + + * tests/README: Added. + 1999-08-18 Jesper Skov <jskov@cygnus.co.uk> * tests/tty1.c:
new file mode 100644 --- /dev/null +++ b/packages/io/serial/current/tests/README @@ -0,0 +1,285 @@ + Serial Testing with ser_filter + +Rationale +~~~~~~~~~ + Since some targets only have one serial connection, a serial testing + harness needs to be able to share the connection with GDB (however, + the test and GDB can also run on separate lines). + + The serial filter (ser_filter) sits between the serial port and GDB + and monitors the exchange of data between GDB and the + target. Normally, no changes are made to the data. + + When a test request packet is sent from the test on the target, it is + intercepted by the filter. The filter and target then enter a loop, + exchanging protocol data between them which GDB never sees. + + In the event of a timeout, or a crash on the target, the filter falls + back into its pass-through mode. If this happens due to a crash it + should be possible to start regular debugging with GDB. The filter + will then stay in the pass-though mode until GDB disconnects. + + +Adding A New Platform +~~~~~~~~~~~~~~~~~~~~~ + The file ser_test_protocol.inl contains information about how to run + the serial tests on supported platforms. When adding a new serial + driver to eCos, ser_test_protocol.inl should be updated accordingly + so the driver can be tested. + + The definitions TEST_SER_DEV and TEST_TTY_DEV are set according to + platform: + + TEST_SER_DEV is the name of the serial device over which the serial + test protocol runs. The definition should be conditional on all + required configuration options. + + TEST_TTY_DEV is the name of the TTY device over which the TTY test + protocol runs. The definition should be conditional on all required + configuration options. Note that this device is layered on top of a + serial device and must be conditional on that device's config + options as well as its own. + + Here's an example for the PowerPC/Cogent where GDB is connected via + serial connector B: + +#if defined(CYGPKG_HAL_POWERPC_COGENT) \ + && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT) \ + && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B) +# define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME +# if defined(CYGPKG_IO_SERIAL_TTY_TTY2) +# define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY2_DEV +# endif +#endif + + + On some targets it may also be necessary to intialize interrupt + vectors which are otherwise used by CygMon or an eCos GDB stub to + monitor characters from the host (looking for Control-C): + +# define SER_OVERRIDE_INT_1 CYGNUM_HAL_INTERRUPT_9 +# define SER_OVERRIDE_INT_2 CYGNUM_HAL_INTERRUPT_10 + + These definitions cause the serial test to restore the eCos handler + on the specified vectors before opening the serial device. + + + The file ser_test_protocol.inl also contains an array of serial + configurations (test_configs). It may be necessary to comment some of + these out for the platform if the driver or hardware cannot handle + all the given serial configurations. + + +The Protocol +~~~~~~~~~~~~ + The protocol commands are prefixed with an @-character which the + serial filter is looking for. The protocol commands include: + + PING + Allows the test on the target to probe for the filter. The filter + responds with OK, while GDB would just ignore the command. This + allows the tests to do nothing if they require the filter and it is + not present. + + CONFIG + Requests a change of serial line configuration. Arguments of the + command specify baud rate, data bits, stop bits, and parity. + + OPT + Requests changes in the filter's options. This allows various + amounts of tracing to be recorded when running tests without + requiring the filter to be restarted. + + BINARY + Requests data to be sent from the filter to the target. The data is + checksummed, allowing errors in the transfer to be detected. + Sub-options of this command control how the data transfer is made: + + NO_ECHO (serial driver receive test) + Just send data from the filter to the target. The test verifies + the checksum and PASS/FAIL depending on the result. + + EOP_ECHO (serial driver half-duplex receive and send test) + As NO_ECHO but the test echoes back the data to the filter. The + filter does a checksum on the received data and sends the result + to the target. The test PASS/FAIL depending on the result of both + checksum verifications. + + DUPLEX_ECHO (serial driver duplex receive and send test) + Smaller packets of data are sent back and forth in a pattern that + ensures that the serial driver will be both sending and receiving + at the same time. Again, checksums are computed and verified + resulting in PASS/FAIL. + + TEXT + This is a test of the text translations in the TTY layer. + Requests a transfer of text data from the target to the filter and + possibly back again. The filter treats this as a binary transfer, + while the target may be doing translations on the data. The target + provides the filter with checksums for what it should expect to + see. + [This test is not implemented yet] + + The above commands may be extended, and new commands added, as + required to test (new) parts of the serial drivers in eCos. + + See ser_test_protocol.inl for further details on the protocols. + + +The Serial Tests +~~~~~~~~~~~~~~~~ + The serial tests are built as any other eCos test. After running the + 'make tests' command, the tests can be found in: + + install/tests/io_serial/ + + serial1 + A simple API test. + + serial2 + A simple serial send test. It writes out two strings, one raw and + one encoded as a GDB O-packet. + + serial3 [requires the serial filter] + This tests the half-duplex send and receive capabilities of the + serial driver. + + serial4 [requires the serial filter] + This test attempts to use a few different serial configurations, + testing the driver's configuration/setup functionality. + + serial5 [requires the serial filter] + This tests the duplex send and receive capabilities of the serial + driver. + + All tests should complete in less than 30 seconds. + + +Serial Filter Usage +~~~~~~~~~~~~~~~~~~~ + Running the ser_filter program with no (or wrong) arguments results + in the below output: + + Usage: ser_filter [-t -c -g -S] TcpIPport SerialPort BaudRate + or: ser_filter -n [-t -c -g -S] SerialPort BaudRate + -t: Enable tracing. + -f: Enable filter output tracing. + -g: Enable GDB tracing. + -S: Output data read from serial line. + -c: Output data on console instead of via GDB. + -n: No GDB. + + The normal way to use it with GDB is to start the filter: + + ser_filter -t 9000 com1 38400 + + In this case, the filter will be listening on port 9000 and connect + to the target via the serial port COM1 at 38400 baud. On a UNIX host, + replace "com1" with a device such as "/dev/ttyS0". + + The '-t' option enables tracing which will cause the filter to + describe its actions on the console. + + Now start GDB with one of the tests as an argument: + + $ mips-tx39-elf-gdb -nw install/tests/io_serial/serial3 + + Then connect to the filter: + + (gdb) target remote localhost:9000 + + This should result in a connection in exactly the same way as if you + had connected directly to the target on the serial line. + + (gdb) load + ... + (gdb) cont + + Which should result in output similar to the below: + + Continuing. + INFO:<BINARY:16:1!> + PASS:<Binary test completed> + INFO:<BINARY:128:1!> + PASS:<Binary test completed> + INFO:<BINARY:256:1!> + PASS:<Binary test completed> + INFO:<BINARY:1024:1!> + PASS:<Binary test completed> + INFO:<BINARY:512:0!> + PASS:<Binary test completed> + ... + PASS:<Binary test completed> + INFO:<BINARY:16384:0!> + PASS:<Binary test completed> + PASS:<serial3 test OK> + EXIT:<done> + + If any of the individual tests fail the testing will terminate with + a FAIL. + + With tracing enabled, you would also see the filter's status output: + + The PING command sent from the target to determine the presence of + the filter: + [400 11:35:16] Dispatching command PING + [400 11:35:16] Responding with status OK + + Each of the binary commands result in output similar to: + [400 11:35:16] Dispatching command BINARY + [400 11:35:16] Binary data (Size:16, Flags:1). + [400 11:35:16] Sending CRC: '170231!', len: 7. + [400 11:35:16] Reading 16 bytes from target. + [400 11:35:16] Done. in_crc 170231, out_crc 170231. + [400 11:35:16] Responding with status OK + [400 11:35:16] Received DONE from target. + + This tracing output is normally sent as O-packets to GDB which will + display the tracing text. By using the -c option, the tracing text + can be redirected to the console from which ser_filter was started. + + + The trace options -f, -g, and -S cause data sent from filter, GDB or + target to be output in hexadecimal form. + + +A Note on Failures +~~~~~~~~~~~~~~~~~~ + A serial connection (especially when driven at a high baud rate) can + garble the transmitted data because of noise from the environment. It + is not the job of the serial driver to ensure data integrity - that + is the job of protocols layering on top of the serial driver. + + In the current implementation the serial tests and the serial filter + are not resilient to such data errors. This means that the test may + crash or hang (possibly without reporting a FAIL). It also means that + you should be aware of random errors - a FAIL is not necessarily + caused by a bug in the serial driver. + + Ideally, the serial testing infrastructure should be able to + distinguish random errors from consistent errors - the former are + most likely due to noise in the transfer medium, while the latter are + more likely to be caused by faulty drivers. The current + implementation of the infrastructure does not have this capability. + + +Debugging +~~~~~~~~~ + If a test fails, the serial filter's output may provide some hints + about what the problem is. If the option '-S' is used when starting + the filter, data received from the target is printed out: + + [400 11:35:16] 0000 50 41 53 53 3a 3c 42 69 'PASS:<Bi' + [400 11:35:16] 0008 6e 61 72 79 20 74 65 73 'nary.tes' + [400 11:35:16] 0010 74 20 63 6f 6d 70 6c 65 't.comple' + [400 11:35:16] 0018 74 65 64 3e 0d 0a 49 4e 'ted>..IN' + [400 11:35:16] 0020 46 4f 3a 3c 42 49 4e 41 'FO:<BINA' + [400 11:35:16] 0028 52 59 3a 31 32 38 3a 31 'RY:128:1' + [400 11:35:16] 0030 21 3e 0d 0a 40 42 49 4e '!>..@BIN' + [400 11:35:16] 0038 41 52 59 3a 31 32 38 3a 'ARY:128:' + [400 11:35:16] 0040 31 21 .. .. .. .. .. .. '1!' + + In the case of an error during a testing command the data received by + the filter will be printed out, as will the data that was + expected. This allows the two data sets to be compared which may give + some idea of what the problem is.
--- a/packages/io/serial/current/tests/ser_test_protocol.inl +++ b/packages/io/serial/current/tests/ser_test_protocol.inl @@ -53,6 +53,7 @@ #include <cyg/io/devtab.h> #include <cyg/io/ttyio.h> #include <cyg/infra/diag.h> +#include <cyg/infra/cyg_ass.h> #include <cyg/hal/hal_intr.h> // for reclaiming interrup vector @@ -65,10 +66,10 @@ #define NA_MSG "No test device specified" - #if defined(CYGPKG_HAL_POWERPC_COGENT) \ && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT) \ && defined(CYGPKG_IO_SERIAL_POWERPC_COGENT_SERIAL_B) +# define TEST_CRASH_ID "ppccog" # define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_COGENT_SERIAL_B_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY2) # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY2_DEV @@ -78,6 +79,7 @@ && defined(CYGPKG_HAL_QUICC) \ && defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC) \ && defined(CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1) +# define TEST_CRASH_ID "ppcmbx" # define TEST_SER_DEV CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY1) # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV @@ -86,6 +88,7 @@ #if defined(CYGPKG_HAL_ARM_PID) \ && defined(CYGPKG_IO_SERIAL_ARM_PID) \ && defined(CYGPKG_IO_SERIAL_ARM_PID_SERIAL0) +# define TEST_CRASH_ID "armpid" # define TEST_SER_DEV CYGDAT_IO_SERIAL_ARM_PID_SERIAL0_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY0) # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY0_DEV @@ -94,6 +97,7 @@ #if defined(CYGPKG_HAL_ARM_AEB) \ && defined(CYGPKG_IO_SERIAL_ARM_AEB) \ && defined(CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1) +# define TEST_CRASH_ID "armaeb" # define TEST_SER_DEV CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY1) # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV @@ -102,6 +106,7 @@ #if defined(CYGPKG_HAL_ARM_CL7211) \ && defined(CYGPKG_IO_SERIAL_ARM_CL7211) \ && defined(CYGPKG_IO_SERIAL_ARM_CL7211_SERIAL1) +# define TEST_CRASH_ID "armcl7" # define TEST_SER_DEV CYGDAT_IO_SERIAL_ARM_CL7211_SERIAL1_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY1) # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV @@ -110,6 +115,7 @@ #if defined(CYGPKG_HAL_MIPS_TX39_JMR3904) \ && defined(CYGPKG_IO_SERIAL_TX39_JMR3904) \ && defined(CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0) +# define TEST_CRASH_ID "tx3jmr" # define TEST_SER_DEV CYGDAT_IO_SERIAL_TX39_JMR3904_SERIAL0_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY1) # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV @@ -118,6 +124,7 @@ #if defined(CYGPKG_HAL_MN10300_AM31_STDEVAL1) \ && defined(CYGPKG_IO_SERIAL_MN10300) \ && defined(CYGPKG_IO_SERIAL_MN10300_SERIAL2) +# define TEST_CRASH_ID "am31st" # define TEST_SER_DEV CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME # if defined(CYGPKG_IO_SERIAL_TTY_TTY2) # define TEST_TTY_DEV CYGDAT_IO_SERIAL_TTY_TTY1_DEV @@ -130,6 +137,7 @@ # define NA_MSG "CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT is unset" # if !defined(CYG_HAL_STARTUP_RAM) \ || defined(CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT) +# define TEST_CRASH_ID "sparcl" # define TEST_SER_DEV CYGDAT_IO_SERIAL_SPARCLITE_SLEB_CON1_NAME // The interrupt vectors are normally in CygMon's control. Steal them back, // but beware that this results in GDB acknowledge characters showing up in @@ -157,6 +165,60 @@ # endif #endif +#ifndef TEST_CRASH_ID +#define TEST_CRASH_ID "......" +#endif + +//---------------------------------------------------------------------------- +// Crash types +// Eventually this will be moved into a separate header file so a script +// can read the definitions and use the output formats/codes to analyze +// test results. For now we just keep it here... + +// FAILCODE:<tttttt:cccc:[optional data, separated by :]!> +// tttttt: 6 letter target code +// cccc: crash code (16bit hex value) + +#define TEST_CRASH(__h, __code, __msg, args...) \ + CYG_MACRO_START \ + int __len = 1; \ + /* Try to flush remaining input */ \ + cyg_thread_delay(50); \ + cyg_io_get_config(__h, CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH, \ + 0, &__len); \ + diag_printf("FAILCODE:<" TEST_CRASH_ID ":%04x:" __code, ## args); \ + diag_printf("!>\n"); \ + CYG_FAIL(__msg); \ + hang(); \ + CYG_MACRO_END + +// Target IO +#define TEST_CRASH_IO 0x0000 +#define TEST_CRASH_IO_READ "%d", 0x0001 +#define TEST_CRASH_IO_WRITE "%d", 0x0002 +#define TEST_CRASH_IO_DRAIN "%d", 0x0003 +#define TEST_CRASH_IO_GET_CFG "%d", 0x0004 +#define TEST_CRASH_IO_SET_CFG "%d", 0x0005 + +// Target +#define TEST_CRASH_CRC 0x0010 +#define TEST_CRASH_CRC_CHAR "%02x", 0x0011 +#define TEST_CRASH_CRC_BAD "%08x:%08x", 0x0012 +#define TEST_CRASH_CRC_HOST "", 0x0013 + +// Protocol errors +#define TEST_CRASH_PROT 0x1000 +#define TEST_CRASH_PROT_BIN_MODE "%d", 0x1080 +#define TEST_CRASH_PROT_TEXT "%d", 0x1100 + +#define TEST_CRASH_HOST_xx 0xf000 +#define TEST_CRASH_HOST_TIMEOUT "%d:%d:%d:%d", 0xf000 + // command#, read invocation#, expected, actual +#define TEST_CRASH_HOST_CRC_BAD "%d:%08x:%08x:%d:%02x:%02x", 0xf010 + // command#, expected CRC, actual, index, expected char, actual +#define TEST_CRASH_HOST_DUPLEX_BAD "%d:%d:%02x:%02x", 0xf020 + // command#, index, expected char, actual + //---------------------------------------------------------------------------- // The data in buffer and the cmd buffer #define IN_BUFFER_SIZE 1024 @@ -343,20 +405,26 @@ do_abort(void *handle) #include "timeout.inl" // Read with timeout (__t = timeout in ticks, int* __r = result) -#define Tcyg_io_read_timeout(__h, __d, __l, __t, __r) \ - CYG_MACRO_START \ - int __res; \ - r_stamp = timeout((__t), do_abort, (__h)); \ - __res = cyg_io_read((__h), (__d), (__l)); \ - CYG_TEST_CHECK((ENOERR == __res || -EINTR == __res),"cyg_io_read failed");\ - *(__r) = __res; \ - untimeout(r_stamp); \ +#define Tcyg_io_read_timeout(__h, __d, __l, __t, __r) \ + CYG_MACRO_START \ + int __res; \ + r_stamp = timeout((__t), do_abort, (__h)); \ + __res = cyg_io_read((__h), (__d), (__l)); \ + if (ENOERR != __res && -EINTR != __res) { \ + TEST_CRASH(__h, TEST_CRASH_IO_READ, \ + "cyg_io_read/timeout failed", __res); \ + } \ + *(__r) = __res; \ + untimeout(r_stamp); \ CYG_MACRO_END -#define Tcyg_io_read(__h, __d, __l) \ - CYG_MACRO_START \ - int __res = cyg_io_read((__h), (__d), (__l)); \ - CYG_TEST_CHECK(ENOERR == __res, "cyg_io_read failed"); \ +#define Tcyg_io_read(__h, __d, __l) \ + CYG_MACRO_START \ + int __res = cyg_io_read((__h), (__d), (__l)); \ + if (ENOERR != __res) { \ + TEST_CRASH(__h, TEST_CRASH_IO_READ, \ + "cyg_io_read failed", __res); \ + } \ CYG_MACRO_END #define Tcyg_io_write(__h, __d, __l) \ @@ -364,12 +432,17 @@ do_abort(void *handle) int __res; \ cyg_uint32 __len = 1; \ __res = cyg_io_write((__h), (__d), (__l)); \ - if (ENOERR != __res) diag_printf("[%d]\n", __res); \ - CYG_TEST_CHECK(ENOERR == __res, "cyg_io_write failed"); \ + if (ENOERR != __res) { \ + TEST_CRASH(__h, TEST_CRASH_IO_WRITE, \ + "cyg_io_write failed", __res); \ + } \ __res = cyg_io_get_config((__h), \ CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN, \ 0, &__len); \ - CYG_TEST_CHECK(ENOERR == __res, "DRAIN failed"); \ + if (ENOERR != __res) { \ + TEST_CRASH(__h, TEST_CRASH_IO_DRAIN, \ + "DRAIN failed", __res); \ + } \ CYG_MACRO_END @@ -489,9 +562,9 @@ change_config(cyg_io_handle_t handle, cy res = cyg_io_get_config(handle, CYG_IO_GET_CONFIG_SERIAL_INFO, &new_cfg, &len); - if (res != ENOERR) { - diag_printf("Can't get serial config - DEVIO error: %d\n", res); - hang(); + if (res != ENOERR) { + TEST_CRASH(handle, TEST_CRASH_IO_GET_CFG, + "Can't get serial config", res); } new_cfg.baud = cfg->baud_rate; @@ -519,9 +592,10 @@ change_config(cyg_io_handle_t handle, cy res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &old_cfg, &len); cyg_thread_delay(10); // Some chips don't like changes to happen to fast... - if (ENOERR != res) { - diag_printf("change_config: set_config failed/1 (%d)\n", res); - hang(); + + if (res != ENOERR) { + TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG, + "Can't set serial config", res); } // Send command to host and read host's reply. @@ -554,9 +628,9 @@ change_config(cyg_io_handle_t handle, cy res = cyg_io_set_config(handle, CYG_IO_SET_CONFIG_SERIAL_INFO, &new_cfg, &len); cyg_thread_delay(10); // Some chips don't like changes to happen to fast... - if (ENOERR != res) { - diag_printf("change_config: set_config failed/2 (%d)\n", res); - hang(); + if (res != ENOERR) { + TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG, + "Can't set serial config/2", res); } { @@ -621,8 +695,8 @@ change_config(cyg_io_handle_t handle, cy &old_cfg, &len); cyg_thread_delay(10); // Some chips don't like changes to happen to fast... if (res != ENOERR) { - diag_printf("change_config: set_config failed/3 (%d)\n", res); - hang(); + TEST_CRASH(handle, TEST_CRASH_IO_SET_CFG, + "Can't set serial config/3", res); } using_old_config = 1; } @@ -646,14 +720,10 @@ read_host_crc(cyg_io_handle_t handle) if ('!' == ch) break; -#ifdef __DEVELOPER__ if (!((ch >= '0' && ch <= '9'))){ - diag_printf("CHAR: %02x\n", ch); + TEST_CRASH(handle, TEST_CRASH_CRC_CHAR, + "Illegal CRC format from host", ch); } -#endif - - CYG_TEST_CHECK((ch >= '0' && ch <= '9'), - "Illegal CRC format from host"); crc = crc*10 + (ch - '0'); } @@ -847,20 +917,24 @@ test_binary(cyg_io_handle_t handle, int } break; default: - CYG_TEST_CHECK(0, "unknown mode"); + TEST_CRASH(handle, TEST_CRASH_PROT_BIN_MODE, + "Unknown mode", mode); + break; } // Verify that the CRC matches the one from the host. FIX_CRC(xcrc, icrc); -#ifdef __DEVELOPER__ - if (host_crc != icrc) - diag_printf("%d != %d\n", icrc, host_crc); -#endif - CYG_TEST_CHECK(host_crc == icrc, "CRC failed!"); + if (host_crc != icrc) { + TEST_CRASH(handle, TEST_CRASH_CRC_BAD, + "Input CRC failed", icrc, host_crc); + } // Verify that the host is happy with the data we echoed. - CYG_TEST_CHECK('O' == host_status, "Host failed checksum on echoed data"); + if ('O' != host_status) { + TEST_CRASH(handle, TEST_CRASH_CRC_HOST, + "Output CRC failed"); + } CYG_TEST_PASS("Binary test completed"); return TEST_RETURN_OK; @@ -892,7 +966,7 @@ test_text(cyg_io_handle_t handle, cyg_mo //--------------------------------------------------------------------------- // Send PING to host, verifying the filter's presence. // Format out: -// "@PING!" +// "@PING:<crash id>!" // Format in: // "OK" // or @@ -903,7 +977,7 @@ test_text(cyg_io_handle_t handle, cyg_mo void test_ping(cyg_io_handle_t handle) { - char msg[] = "@PING:!"; + char msg[] = "@PING:" TEST_CRASH_ID "!"; char msg2[] = "\n"; int msglen = strlen(msg); int res;
--- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,3 +1,33 @@ +1999-08-25 Jonathan Larmour <jlarmour@cygnus.co.uk> + + * include/pkgconf/kernel.h: Add missing close brace in + CYGIMP_KERNEL_COUNTERS_CLOCK_LATENCY CDL. + +1999-08-24 Nick Garnett <nickg@cygnus.co.uk> + + * tests/kcache1.c (entry0): Depending on architecture, set + cyg_test_is_simulator for last two tests. Otherwise they take far + too long and time out. + +1999-08-23 Hugo Tyson <hmt@cygnus.co.uk> + + * tests/intr0.cxx (vsr0): + * tests/kintr0.c (vsr0): + Add a comment to the effect that vsr0() is NOT a valid VSR on any + known platform; VSRs must be writ in assembler. Customer + requested this, the examples are rather confusing otherwise. + +1999-08-23 Nick Garnett <nickg@cygnus.co.uk> + + * include/pkgconf/kernel.h: + * src/common/clock.cxx: + * tests/tm_basic.cxx: + Added CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY to enable recording + of DSR latency figures. Added code controlled by this option to + clock and tm_basic. Also made interrupt latency measurement + primarily dependent on CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY since + whether HAL_CLOCK_LATENCY is defined is not sufficient. + 1999-08-16 Jonathan Larmour <jlarmour@cygnus.co.uk> * src/sload/sload.c: Rename AM32 to AM31
--- a/packages/kernel/current/include/pkgconf/kernel.h +++ b/packages/kernel/current/include/pkgconf/kernel.h @@ -535,7 +535,19 @@ Measure the interrupt latency as seen by the real-time clock timer interrupt. This requires hardware support, defined by the HAL_CLOCK_LATENCY() macro." - doc ref/ecos-ref/counters-clocks-and-alarms.html + doc ref/ecos-ref/counters-clocks-and-alarms.html + } + + cdl_option CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY { + display "Measure real-time [clock] DSR latency" + parent CYGPKG_KERNEL_COUNTERS + requires CYGVAR_KERNEL_COUNTERS_CLOCK + requires CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY + description " + Measure the DSR latency as seen by the real-time clock + timer interrupt. This requires hardware support, defined by + the HAL_CLOCK_LATENCY() macro." + doc ref/ecos-ref/counters-clocks-and-alarms.html } }}CFG_DATA */ @@ -550,6 +562,7 @@ #define CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE 8 #undef CYGIMP_KERNEL_COUNTERS_SORT_LIST #undef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY +#undef CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY /* --------------------------------------------------------------------- * Thread-related options
--- a/packages/kernel/current/src/common/clock.cxx +++ b/packages/kernel/current/src/common/clock.cxx @@ -660,20 +660,27 @@ Cyg_RealTimeClock::Cyg_RealTimeClock() Cyg_Clock::real_time_clock = this; } -#ifdef HAL_CLOCK_LATENCY +#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY) cyg_tick_count total_clock_latency, total_clock_interrupts; cyg_int32 min_clock_latency = 0x7FFFFFFF; cyg_int32 max_clock_latency = 0; bool measure_clock_latency = false; #endif +#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) +cyg_tick_count total_clock_dsr_latency, total_clock_dsr_calls; +cyg_int32 min_clock_dsr_latency = 0x7FFFFFFF; +cyg_int32 max_clock_dsr_latency = 0; +cyg_int32 clock_dsr_start = 0; +#endif + // ------------------------------------------------------------------------- cyg_uint32 Cyg_RealTimeClock::isr(cyg_vector vector, CYG_ADDRWORD data) { // CYG_REPORT_FUNCTION(); -#ifdef HAL_CLOCK_LATENCY +#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY) if (measure_clock_latency) { cyg_int32 delta; HAL_CLOCK_LATENCY(&delta); @@ -693,7 +700,10 @@ cyg_uint32 Cyg_RealTimeClock::isr(cyg_ve HAL_CLOCK_RESET( CYGNUM_HAL_INTERRUPT_RTC, CYGNUM_KERNEL_COUNTERS_RTC_PERIOD ); Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_RTC); - + +#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) + HAL_CLOCK_READ(&clock_dsr_start); +#endif return Cyg_Interrupt::CALL_DSR|Cyg_Interrupt::HANDLED; } @@ -703,6 +713,22 @@ void Cyg_RealTimeClock::dsr(cyg_vector v { // CYG_REPORT_FUNCTION(); +#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) + if (measure_clock_latency) { + cyg_int32 delta; + HAL_CLOCK_READ(&delta); + delta -= clock_dsr_start; + // Note: Ignore a latency of <= 0 when finding min_clock_latency. + if (delta > 0 ) { + // Valid delta measured + total_clock_dsr_latency += delta; + total_clock_dsr_calls++; + if (min_clock_dsr_latency > delta) min_clock_dsr_latency = delta; + if (max_clock_dsr_latency < delta) max_clock_dsr_latency = delta; + } + } +#endif + Cyg_RealTimeClock *rtc = (Cyg_RealTimeClock *)data; CYG_INSTRUMENT_CLOCK( TICK_START,
--- a/packages/kernel/current/tests/intr0.cxx +++ b/packages/kernel/current/tests/intr0.cxx @@ -90,6 +90,19 @@ static bool flash( void ) return true; } +/* IMPORTANT: The calling convention for VSRs is target dependent. It is + * unlikely that a plain C or C++ routine would function correctly on any + * particular platform, even if it could correctly access the system + * resources necessary to handle the event that caused it to be called. + * VSRs usually must be written in assembly language. + * + * This is just a test program. The routine vsr0() below is defined simply + * to define an address that will be in executable memory. If an event + * causes this VSR to be called, all bets are off. If it is accidentally + * installed in the vector for the realtime clock, the system will likely + * freeze. + */ + static cyg_VSR vsr0; static void vsr0()
--- a/packages/kernel/current/tests/kcache1.c +++ b/packages/kernel/current/tests/kcache1.c @@ -297,6 +297,18 @@ static void entry0( cyg_addrword_t data CYG_TEST_INFO("Dcache on Icache on (again)"); time1(); +#if defined(CYGPKG_HAL_MIPS) + // In some architectures, the time taken for the next two tests is + // very long, partly because HAL_XCACHE_INVALIDATE_ALL() is implemented + // with a loop over the cache. Hence these tests take longer than the + // testing infrastructure is prepared to wait. The simplest way to get + // these tests to run quickly is to make them think they are running + // under a simulator. + + cyg_test_is_simulator = 1; + +#endif + #ifdef HAL_ICACHE_INVALIDATE_ALL HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL();
--- a/packages/kernel/current/tests/kintr0.c +++ b/packages/kernel/current/tests/kintr0.c @@ -97,6 +97,19 @@ static bool flash( void ) return true; } +/* IMPORTANT: The calling convention for VSRs is target dependent. It is + * unlikely that a plain C or C++ routine would function correctly on any + * particular platform, even if it could correctly access the system + * resources necessary to handle the event that caused it to be called. + * VSRs usually must be written in assembly language. + * + * This is just a test program. The routine vsr0() below is defined simply + * to define an address that will be in executable memory. If an event + * causes this VSR to be called, all bets are off. If it is accidentally + * installed in the vector for the realtime clock, the system will likely + * freeze. + */ + static cyg_VSR_t vsr0; static void vsr0()
--- a/packages/kernel/current/tests/tm_basic.cxx +++ b/packages/kernel/current/tests/tm_basic.cxx @@ -140,13 +140,19 @@ static fun_times alarm_ft[NALARMS]; static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION; static long ns_per_system_clock; -#ifdef HAL_CLOCK_LATENCY +#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 + externC void diag_printf(const char *, ...); void run_sched_tests(void); @@ -198,7 +204,7 @@ show_ticks_in_us(cyg_uint32 ticks) // fair measurements of the kernel primitives, which are not distorted // by the printing mechanisms. -#ifdef HAL_CLOCK_LATENCY +#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY) void disable_clock_latency_measurement(void) { @@ -222,7 +228,14 @@ reset_clock_latency_measurement(void) 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() @@ -1433,7 +1446,7 @@ run_all_tests(CYG_ADDRESS id) #ifdef CYG_SCHEDULER_LOCK_TIMINGS cyg_uint32 lock_ave, lock_max; #endif -#ifdef HAL_CLOCK_LATENCY +#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY) cyg_int32 clock_ave; #endif @@ -1511,7 +1524,7 @@ run_all_tests(CYG_ADDRESS id) diag_printf("\n"); #endif -#ifdef HAL_CLOCK_LATENCY +#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; @@ -1520,6 +1533,17 @@ run_all_tests(CYG_ADDRESS id) 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
--- a/packages/language/c/libc/current/ChangeLog +++ b/packages/language/c/libc/current/ChangeLog @@ -1,3 +1,15 @@ +1999-09-02 Hugo Tyson <hmt@cygnus.co.uk> + + * include/assert.h: Make the sense of NDEBUG correct; it is "set" + when NOT debugging. Fix for CR 101983-CR-1 + See Stroustrup, "The C++ Programming Language." + +1999-08-18 Jonathan Larmour <jlarmour@cygnus.co.uk> + + * src/stdio/common/fopen.cxx (_fopen): Set buffer size 0 when not + buffering + Fix for case 101868 + 1999-08-06 Jonathan Larmour <jlarmour@cygnus.co.uk> * tests/stdio/sprintf2.c (test): Don't rely on 2.345 being exactly
--- a/packages/language/c/libc/current/include/assert.h +++ b/packages/language/c/libc/current/include/assert.h @@ -56,21 +56,21 @@ // MACROS -// The user should define NDEBUG to turn on these user assertions. Also the -// common infrastructure assertions should be turned on too. +// The user should define NDEBUG to turn off these user assertions. Also the +// common infrastructure assertions should be turned off too. -#ifndef NDEBUG +#ifdef NDEBUG # define assert( _bool_ ) ((void)0) -#else // if NDEBUG is defined +#else // if NDEBUG is NOT defined # define assert( _bool_ ) \ CYG_MACRO_START \ CYG_ASSERT( _bool_, "User assertion failed: \"" # _bool_ "\"" ); \ CYG_MACRO_END -#endif // if NDEBUG is defined +#endif // if NDEBUG is NOT defined
--- a/packages/language/c/libc/current/src/stdio/common/fopen.cxx +++ b/packages/language/c/libc/current/src/stdio/common/fopen.cxx @@ -163,7 +163,7 @@ externC FILE * // potentially interactive devices, so as per ANSI 7.9.3 it must not // be buffered curr_stream = new Cyg_StdioStream( dev, open_mode, append, binary, - _IONBF ); + _IONBF, 0 ); if (curr_stream == NULL) { errno = ENOMEM;
