#define OSISR_C
/******************************************************************************
 *
 *       (C) Copyright 2006, Freescale Semiconductor, Inc. All Rights Reserved.
 *
 *       THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
 *       BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
 *       Freescale Semiconductor, Inc.
 *
 * Filename:     $Source: \RAppIDToolbox/RAppID_verM/rappid/src/Metrowerks_specific_files/OSEKTurbo/osisr.c,v $
 * Author:       $Author: r66544 $
 * Revision:     $Revision: 1.2 $
 *
 * Functions:    
 *
 * History:      Use the CVS command rlog to display revision history
 *               information.
 *
 * Description:    OSEK OS ISR management    
 *
 * Notes:        
 *
 ******************************************************************************/

#if !defined(OSPROPH)
#include "osprop.h"                     /* OS Properties */
#else                                   /* !defined(OSPROPH) */
#include OSPROPH                        /* OS Properties */
#endif                                  /* !defined(OSPROPH) */

#include <osapi.h>

/*    Global OS variables    */

#if defined(OSISRNORMAL) || defined(OSHOOKSTARTUP) /* There are user interrupts category 2, 3 or systimer */
#if !defined(OSISRLEVELREG)
OSISRLEVELTYPE OsIsrLevel;              /* ISR nesting level: */
/*     0, if no ISR cat 2 and 3 are active    */
/*  N otherwise (N number of nested interrupts)*/
#endif                                  /* !defined(OSISRLEVELREG)*/
#endif                                  /* defined(OSISRNORMAL) || defined(OSHOOKSTARTUP) */

OSDWORD OsOldMsr;                       /* Saved MSR for EnableAll/DisableAllInterrupts */
OSINTMASKTYPE OsOldInterruptMask;       /* Saved interrupt mask for SuspendOS/ResumeOSInterrupts services */
/* and for Hooks */
OSINTMASKTYPE OsOldIntMaskAll;          /* SuspendAll/ResumeAllInterrupts services */
OSBYTE OsSuspendLevelAll;               /* level of the nested Suspend/ResumeAll pairs */

#if defined(OSISRENHANCED) || defined(OSWITHINTERRUPTLEVEL)
OSINTMASKTYPE OsIsrOff;                 /* mask which disable all ISR2 */
#endif                                  /* defined(OSISRENHANCED) || defined(OSWITHINTERRUPTLEVEL)*/

#if (!defined(OSNOOSINTERRUPTS) && defined(OSISRENTRYEXIT)) \
  || defined (OSHOOKERROR) || defined (OSHOOKPRETASK) || defined (OSHOOKPOSTTASK) || defined(OSCOMHOOKERROR)
OSBYTE OsSuspendLevel;                  /* level of the nested Suspend/Resume pairs */

#endif

#if defined(OSISRENTRYEXIT) && defined (OSEXTSTATUS) && defined(OSHOOKERROR)
OSDWORD OsIntCheck;                     /* check correct order of the nested Suspend/Resume pairs */
#endif                                  /* defined(OSISRENTRYEXIT) && defined (OSEXTSTATUS) && defined(OSHOOKERROR) */

#if defined(OSISRNORMAL)

#if defined(OSECC) && defined(OSISRSTACKSIZE)
OSDWORD OsISRStack[OSISRSTACKSIZE];
#endif                                  /* defined(OSECC) && defined(OSISRSTACKSIZE)*/

#endif                                  /* defined(OSISRNORMAL) */

/* For OSMPC55XX the interrupt vector table is placed in the BAM region (see lcf file) */
#pragma push
#pragma section code_type ".vects" data_mode=far_abs code_mode=far_abs
__declspec(section ".vects") extern OSFITVEC;
__declspec(section ".vects") extern OSDECVEC;
__declspec(section ".vects") extern OSEXTVEC;
__declspec(section ".vects") extern void OSINITIVORS(void);
#pragma pop

/*    Private OS Services    */
/***************************************************************************
 * Function : OSInitializeISR
 *
 * Description: Initializes ISRs
 *
 * Returns: none
 *
 * Notes: 
 *
 **************************************************************************/
void OSInitializeISR( void )
{
  OSDWORD tmp, i;
#if defined(OSISRNORMAL)
  /* Init ISR manager */
  OsIsrLevel = OSISRLEVEL0;             /* no ISR/critical section running                      */
#endif                                  /* defined(OSISRNORMAL) */
#if defined(OSWITHINTERRUPTLEVEL)
  OSISRALLON();
#endif                                  /* defined(OSWITHINTERRUPTLEVEL) */

#if defined(OSISRENTRYEXIT) || \
    defined (OSHOOKERROR) || defined (OSHOOKPRETASK) || defined (OSHOOKPOSTTASK)
  OsSuspendLevel = 0;                   /* level of the nested Suspend/Resume pairs */
#endif                                  /* defined(OSISRENTRYEXIT) || \
                                           defined (OSHOOKERROR) || defined (OSHOOKPRETASK) || defined (OSHOOKPOSTTASK) */

#if !defined(OSNOISR)
  OsSetIVPR((OSDWORD)OSIVPR);           /* Set Interrupt vector prefix */
  OSInitIVORS();
#endif

#if defined(OSTIMDEC) || defined(OSDECISR)
  OsSetDECVec((OSDWORD)&OSDECVEC);
#endif                                  /* defined(OSTIMDEC) */
#if defined(OSTIMFIT) || defined(OSTIM2FIT) || defined(OSFITISR)
  OsSetFITVec((OSDWORD)&OSFITVEC);
#endif                                  /* defined(OSTIMFIT) || defined(OSTIM2FIT) */

#if defined(OSISRDISPATCH)
#if OSNISR > 0
  for( i = 0; i < OSNISR; i++ )
  {
    OSSET_INT_PSRX(OsIsrCfg[i].index, OsIsrCfg[i].prio); /* Set priority for Software setable interrupt for FIT */
  }

  OsSetEXTVec((OSDWORD)&OSEXTVEC);
#endif                                  /* OSNISR > 0 */
#if defined(OSISRENHANCED)
  OSINTC_BCR |= OSINTC_BCR_HVEN;        /* Hardware vector mode */
#else                                   /* defined(OSISRENHANCED) */
  OSINTC_BCR &= ~OSINTC_BCR_HVEN;       /* Software vector mode */
#endif                                  /* defined(OSISRENHANCED) */
#if defined(OSVTABCOMPRESSED)           /* If the vector table is compressed */
  OSINTC_BCR |= OSINTC_BCR_VTES;        /* Vector Table Entry Size = 8 */
#else                                   /* defined(OSVTABCOMPRESSED) */
  OSINTC_BCR &= ~OSINTC_BCR_VTES;       /* Vector Table Entry Size = 4 */
#endif                                  /* defined(OSVTABCOMPRESSED) */
  OSINTC_CPR = 0;                       /* Current interrupt priority set 0 */
#endif                                  /* defined(OSISRDISPATCH) */
}

#if defined(OSISRNORMAL)

#if defined(OSBCC)
#if !defined(OSEXTSTATUS) && !defined(OSNOFASTTERMINATE) && !defined(OSBCC2)
/***************************************************************************
 * Function : OSLeaveISR
 *
 * Description: Leave ISR and switch tasks' context, if needed
 *
 * Returns: none
 *
 * Notes: 
 *
 **************************************************************************/
void OSLeaveISR( void )
{
#if defined(OSRESOURCE)
  OSTSKCBPTR osOldRunning;              /* currently running task    */
#else                                   /* defined(OSRESOURCE */
  OSTASKTYPE osOldRunning;              /* currently running task    */
#endif                                  /* defined(OSRESOURCE) */

  OSTASKTYPE osChainTask;               /* task to be chain    (if any)    */

#if defined(OSFLOATINGPOINT)
  OSFPSCRATCHCTX osFPScratchCtx;        /* Area for storing scrach registers */
#endif                                  /* defined(OSFLOATINGPOINT) */

#if defined(OSINRES)
  OSRUNPRIODEF;                         /* temporary variable for walk around the Diab BUG */
#endif                                  /* defined(OSINRES) */

#if defined(OSEXTSTATUS) && defined(OSHOOKERROR) /* check Suspend/Resume pairing */
  if( (OsSuspendLevelAll != 0) || (OsSuspendLevel != 0) )
  {
    OSErrorHook_noPar( E_OS_SYS_ORDER );
  }
#endif                                  /* defined (OSEXTSTATUS) && defined(OSHOOKERROR) */

  /* Check condition of dispatching, if dispatching is not needed then return, else dispatch  */
#if defined(OSMIXPREEMPT)
  if( OSTASKID(OsRunning) != OSNULLTASK ) /* if interrupted task is not idle loop */
  {
    if( (OSRUNNINGSTATUS & (OSTCBNONPREEMPT
#if defined(OSRES_SCHEDULER)
       | OSTCBSCHEDULER
#endif                                  /* defined(OSRES_SCHEDULER) */
       ) ) != 0 )
    {
      return;                           /* if non-preemptive task was interrupted, then no launch    */
    }
  }
#elif defined(OSFULLPREEMPT)
  if( OSTASKID(OsRunning) != OSNULLTASK ) /* if interrupted task is not idle loop */
  {
#if defined(OSRES_SCHEDULER)
    if( (OSRUNNINGSTATUS & OSTCBSCHEDULER ) != 0 )
    {
      return;                           /* if running task take scheduler then no launch    */
    }
#endif                                  /* defined(OSRES_SCHEDULER) */
  }
#else                                   /* OSNOPREEMPT */
  if( OSTASKID(OsRunning) != OSNULLTASK )
  {
    return;                             /* for non-preemptive system nothing launch,    */
  }
  /*  if interrupt occured while any task was running    */
#endif                                  /* defined(OSMIXPREEMPT) */

  osOldRunning = OsRunning;             /* save running task (if any)    */

#if defined(OSHOOKPOSTTASK)
  if( OSTASKID(OsRunning) != OSNULLTASK )
  {
    OSPostTaskHook();                   /* user hook or empty macros */
  }
#endif                                  /* defined(OSHOOKPOSTTASK) */

#if defined(OSFLOATINGPOINT)
  if( ( OsRunning = OSGETMAXPRIOTASK) != osOldRunning )
  {
    OSFPTURNON();
    /* Save scratch registers */
    OSSaveScratchFPCtx(&osFPScratchCtx);
    do                                  /* cycle to launch all preempting tasks    */
#else                                   /* defined(OSFLOATINGPOINT) */
    {                                   /* Dummy block for alignment */
      while( ( OsRunning = OSGETMAXPRIOTASK) != osOldRunning ) /* cycle to launch all preempting tasks    */
#endif                                  /* defined(OSFLOATINGPOINT) */
      /* Body of loop */
      {
        OSRUNPRIOASS;
        OSSETRUNPRIO();                 /* set internal resource priotity, if any       */

        OSCallPreTaskHook();
#if defined(OSISRENHANCED)
        OSSISRCLEARBIT();               /* Clear appropriate bit in the SISR register */
#endif                                  /* defined(OSISRENHANCED) */
        OSEI();
        osChainTask = OSCALLTASK();     /* execute the task, and get the ID of chained task */
        OSDI();
        OSCheckMainStack();             /* check main stack overflow */

#if defined(OSINRES)
        if( (OSTASKSTATUS( OSTASKRUNPRIO( OsRunning )) & OSTCBNOSUSPENDED) == 0
         )
        {                               /* if there is no ready task of this prio.  */
          OSTask2Suspend( OSTASKRUNPRIO( OsRunning )); /* then clear bit in OsScheduler         */
        }
        OSRESETRUNPRIO();
#endif                                  /* defined(OSINRES) */
#if defined(OSRESOURCE) || defined(OSINRES)
        OSRUNNINGSTATUS &= (~OSTCBNOSUSPENDED); /* clear "nonsuspended" flag */
#endif                                  /* defined(OSRESOURCE) || defined(OSINRES) */

        OSREMOVETASK(OsRunning);

        if( osChainTask != OSNULLTASK ) /* if some task needs to be chained    */
        {
          OSTask2Ready( osChainTask ); /* then readies chained task    */
        }

        OSPostTaskHook();               /* user hook or empty macros */
      }

#if defined(OSFLOATINGPOINT)
      while( (OsRunning = OSGETMAXPRIOTASK) != osOldRunning ); /* if dispatching is needed    */
      OSLoadScratchFPCtx(&osFPScratchCtx); /* Restore scratch registers     */
    }                                   /* End of if( OsRunning = ... */
#else                                   /* defined(OSFLOATINGPOINT) */
  }                                     /* End of dummy block */
#endif                                  /* defined(OSFLOATINGPOINT) */

  OSRUNPRIOASS;
  OSSETBITRUNPRIO();                    /* Restore runprio bit */

  OSPreTaskHook();                      /* call user hook           */

  return;
}
#else                                   /* !defined(OSEXTSTATUS) && !defined(OSNOFASTTERMINATE) && !defined(OSBCC2) */
/***************************************************************************
 * Function : OSLeaveISR
 *
 * Description: Leave ISR and switch tasks' context, if needed
 *
 * Returns: none
 *
 * Notes: 
 *
 **************************************************************************/
void OSLeaveISR( void )
{
  OSTSKCBPTR osOldRunning;              /* currently running task    */

#if defined(OSFLOATINGPOINT)
  OSFPSCRATCHCTX osFPScratchCtx;        /* Area for storing scrach registers */
#endif                                  /* defined(OSFLOATINGPOINT) */

#if defined(OSEXTSTATUS) && defined(OSHOOKERROR) /* check Suspend/Resume pairing */
  if( (OsSuspendLevelAll != 0) || (OsSuspendLevel != 0) )
  {
    OSErrorHook_noPar( E_OS_SYS_ORDER );
  }
#endif                                  /* defined (OSEXTSTATUS) && defined(OSHOOKERROR) */

  /* Check condition of dispatching, if dispatching is not needed then return, else dispatch  */
#if defined(OSMIXPREEMPT)
  if( OSTASKID(OsRunning) != OSNULLTASK ) /* if interrupted task is not idle loop */
  {
    if( (OSRUNNINGSTATUS & (OSTCBNONPREEMPT
#if defined(OSRES_SCHEDULER)
       | OSTCBSCHEDULER
#endif                                  /* defined(OSRES_SCHEDULER) */
       ) ) != 0 )
    {
      return;                           /* if non-preemptive task was interrupted, then no launch    */
    }
  }
#elif defined(OSFULLPREEMPT)
  if( OSTASKID(OsRunning) != OSNULLTASK ) /* if interrupted task is not idle loop */
  {
#if defined(OSRES_SCHEDULER)
    if( (OSRUNNINGSTATUS & OSTCBSCHEDULER ) != 0 )
    {
      return;                           /* if running task take scheduler then no launch    */
    }
#endif                                  /* defined(OSRES_SCHEDULER) */
  }
#else                                   /* OSNOPREEMPT */
  if( OSTASKID(OsRunning) != OSNULLTASK )
  {
    return;                             /* for non-preemptive system nothing launch,    */
  }
  /*  if interrupt occured while any task was running    */
#endif                                  /* defined(OSMIXPREEMPT) */

  osOldRunning = OsRunning;             /* save running task (if any)    */

#if defined(OSHOOKPOSTTASK)
  if( OSTASKID(OsRunning) != OSNULLTASK )
  {
    OSPostTaskHook();                   /* user hook or empty macros */
  }
#endif                                  /* defined(OSHOOKPOSTTASK) */

#if defined(OSFLOATINGPOINT)
  OSFPTURNON();
  OSSaveScratchFPCtx(&osFPScratchCtx); /* Save scratch registers     */
#endif                                  /* defined(OSFLOATINGPOINT) */
  OsRunning = OSGETMAXPRIOTASK;
  if( OSSetJmp( *(osOldRunning->context) ) )
  {
    OSSETBITRUNPRIO();                  /* Restore runprio bit */
    OSDHI();
    OSPreTaskHook();
#if defined(OSFLOATINGPOINT)
    /* Restore scratch registers     */
    OSLoadScratchFPCtx(&osFPScratchCtx);
#endif                                  /* defined(OSFLOATINGPOINT) */
    return;
  }
  if( (OSRUNNINGSTATUS & OSTCBFIRST) != 0 ) /* if task not running yet */
  {
    OSRUNNINGSTATUS &= (OSBYTE)(~OSTCBFIRST); /* task already running */

    OSSAVESETSPRG2(*(osOldRunning->context));

    OSSETRUNPRIO();                     /* set internal resource priotity, if any       */

    OSCallPreTaskHook();
#if defined(OSISRENHANCED)
    OSSISRCLEARBIT();                   /* Clear appropriate bit in the SISR register */
#endif                                  /* defined(OSISRENHANCED) */
    OSEI();
    OSCALLTASK();                       /* start task (via conventional call or jump) */
    /* never return at this point */
  }
  OSLOADSPRG2(*(OsRunning->context));
#if defined(OSISRENHANCED)
  OSSISRCLEARBIT();                     /* Clear appropriate bit in the SISR register */
#endif                                  /* defined(OSISRENHANCED) */
  OSLongJmp( *(OsRunning->context), 1 ); /* jump directly to the context of preempted task   */
  /* never return at this point */
  return;
}

#endif                                  /* !defined(OSEXTSTATUS) && !defined(OSNOFASTTERMINATE) && !defined(OSBCC2) */
#endif                                  /* defined(OSBCC) */

#if defined(OSECC)
/***************************************************************************
 * Function : OSLeaveISR
 *
 * Description: Leave ISR and switch tasks' context, if needed
 *
 * Returns: none
 *
 * Notes: 
 *
 **************************************************************************/
void OSLeaveISR( void )
{
  OSTSKCBPTR osOldRunning;              /* currently running task    */
#if defined(OSFLOATINGPOINT)
  OSFPSCRATCHCTX osFPScratchCtx;        /* Area for storing scrach registers */
#endif                                  /* defined(OSFLOATINGPOINT) */

#if defined(OSEXTSTATUS) && defined(OSHOOKERROR) /* check Suspend/Resume pairing */
  if( (OsSuspendLevelAll != 0) || (OsSuspendLevel != 0) )
  {
    OSErrorHook_noPar( E_OS_SYS_ORDER );
  }
#endif                                  /* defined (OSEXTSTATUS) && defined(OSHOOKERROR) */

#if defined(OSMIXPREEMPT)
#if defined(OSRES_SCHEDULER)
  if( (OsRunning->status & (OSTCBNONPREEMPT | OSTCBSCHEDULER) ) != 0 )
#else                                   /* defined(OSRES_SCHEDULER) */
  if( (OsRunning->status & OSTCBNONPREEMPT) != 0 )
#endif                                  /* defined(OSRES_SCHEDULER) */
  {
    return;                             /* if non-preemptive task was interrupted, */
    /* or running task take scheduler then no launch */
  }
#elif defined(OSFULLPREEMPT)
#if defined(OSRES_SCHEDULER)
  if( (OsRunning->status & OSTCBSCHEDULER ) != 0 )
  {
    return;                             /* if running task take scheduler then no launch */
  }
#endif                                  /* defined(OSRES_SCHEDULER) */
#else                                   /* OSNOPREEMPT */
  if( OsRunning->taskId != OSNULLTASK )
  {
    return;                             /* for non-preemptive system nothing launch,    */
  }
  /* if interrupt occured while any task was running */
#endif                                  /* defined(OSMIXPREEMPT) */

  osOldRunning = OsRunning;             /* save running task (if any)    */

#if defined(OSHOOKPOSTTASK)
  if( osOldRunning->taskId != OSNULLTASK )
  {
    OSPostTaskHook();                   /* call user hook               */
  }
#endif                                  /* defined(OSHOOKPOSTTASK) */

  OsRunning = OSGETMAXPRIOTASK;
#if defined(OSFLOATINGPOINT)
  OSFPTURNON();
  /* Save scratch registers */
  OSSaveScratchFPCtx(&osFPScratchCtx);
#endif                                  /* defined(OSFLOATINGPOINT) */
  if( OSSetJmp( *(osOldRunning->context)) ) /* save context of preempted task    */
  {
    /* return point from dispatched tasks */
    OSSETBITRUNPRIO();                  /* Restore runprio bit */
    OSDHI();
    OSPreTaskHook();
#if defined(OSFLOATINGPOINT)
    /* Restore scratch registers     */
    OSLoadScratchFPCtx(&osFPScratchCtx);
#endif                                  /* defined(OSFLOATINGPOINT) */
    return;
  }

#if OSNXTSKS > 0
  if( (osOldRunning->status & OSTCBEXTENDED) == 0 )
#endif                                  /* OSNXTSKS > 0  */
  {
    OSSAVESETSPRG2(*(osOldRunning->context));
  }

  if( (OsRunning->status & OSTCBFIRST) != 0 ) /* if task not running yet */
  {
    /* start-up the task    */
    OsRunning->status &= (OSBYTE)(~OSTCBFIRST); /* task already running */

#if OSNXTSKS > 0
    if( (OsRunning->status & OSTCBEXTENDED) != 0 )
    {
      OSLOADSP(OsRunning->tos);
    }
    else
    {
      if( (osOldRunning->status & OSTCBEXTENDED) != 0 ) /* if preempted task is BASIC */
      {
        OSLOADBASICSP();
      }
    }
#endif                                  /* OSNXTSKS > 0    */

    OSSETRUNPRIO();                     /* set internal resource priotity, if any       */

    OSCallPreTaskHook();
#if defined(OSISRENHANCED)
    OSSISRCLEARBIT();                   /* Clear appropriate bit in the SISR register */
#endif                                  /* defined(OSISRENHANCED) */
    OSEI();
    OSCALLTASK();                       /* start task (via conventional call or jump) */
    /*            return;                                */
    /* 'return' just to fool optimizer    */
    /* never return at this point */
  }
#if OSNXTSKS > 0
  if( (OsRunning->status & OSTCBEXTENDED) == 0 )
#endif                                  /* OSNXTSKS > 0  */
  {
    OSLOADSPRG2(*(OsRunning->context));
  }
#if defined(OSISRENHANCED)
  OSSISRCLEARBIT();                     /* Clear appropriate bit in the SISR register */
#endif                                  /* defined(OSISRENHANCED) */
  OSLongJmp( *(OsRunning->context), 1 ); /* jump directly to the context of preempted task */
  /* never return at this point */
  return;
  OSWARNSUPPRESS                        /* For extra CW warning suppress */
}
#endif                                  /* defined(OSECC) */

#endif                                  /* defined(OSISRNORMAL) */

#if defined(OSISRDISPATCH)
/***************************************************************************
 * Function : OSInterruptDispatcher
 *
 * Description:  This is External Interrupt Dispatcher.
 *               It executes following actions:
 *               in case with OSWITHINTERRUPTLEVEL:
 *                   - save interrupt mask
 *                   - set interrupt mask according to current ISR level and OsIsrOff
 *                   - enable external interrupts
 *               in any cases:
 *               - give the control to the Interrupt Handler
 *                 according to the bits in the SIVEC register
 *
 * Returns: none
 *
 * Notes:        1. The "ba OSInterruptDispatcher" command shall be placed onto
 *                  0x500 address (External Exceptions) in the Vector table.
 **************************************************************************/
OSINTERRUPT void (OSInterruptDispatcher) (void)
{
#if OSNISR > 0
  volatile OSDWORD iackr;
  iackr = OSINTC_IACKR;
  /* FIX FOR BROKEN SOURCE CODE in OSEKTURBO */
  ((OSTASKENTRY)(OsIsr[((iackr)& 0x000007FF) >> 2]))();
  /*  ((OSTASKENTRY)(OsIsr[iackr >> 2]))();*/
#endif                                  /* OSNISR > 0 */

  OSWARNSUPPRESS                        /* For extra CW warning suppress */
}

#endif                                  /* defined(OSISRDISPATCH) */

#if defined(OSWITHINTERRUPTLEVEL)
#if defined(OSDECISR)
__declspec(interrupt) void OSDECisr()
{
  OsSetTSR(OSTSR_DIS);
  OSINTC_SSCIR4_7 = OSDECSOFTINVOKE;
}
#endif                                  /* defined(OSDECISR) */
#if defined(OSFITISR)
__declspec(interrupt) void OSFITisr()
{
  OsSetTSR(OSTSR_FIS);
  OSINTC_SSCIR4_7 = OSFITSOFTINVOKE;
}
#endif                                  /* defined(OSFITISR) */
#endif                                  /* defined(OSWITHINTERRUPTLEVEL) */

/*    Public OS Services    */

#if defined(OSISRNORMAL)
/***************************************************************************
 * Function:    ResumeOSInterrupts
 *
 * Description: Restore interrupt state saved by SuspendOSInterrupts service
 *
 * Returns: E_OK
 *
 * Notes:   
 *
 **************************************************************************/
void ResumeOSInterrupts( void )
{
  OSOrtiSetServiceWatch( OSServiceId_ResumeOSInterrupts );
#if defined (OSEXTSTATUS) && defined(OSHOOKERROR)
  if( OsSuspendLevel == 0 )
  {
    OSErrorHook( E_OS_SYS_ORDER, OSServiceId_ResumeOSInterrupts, 0 );
    OSOrtiServiceWatchOnExit( OSServiceId_ResumeOSInterrupts );
    return;
  }

  if( ((OsSuspendLevel + OsSuspendLevelAll) <= 32 ) &&
   ( OsIntCheck & ( 0x1 << ( OsSuspendLevel + OsSuspendLevelAll - 1 ) ) ) != 0 )
  {
    OSErrorHook( E_OS_SYS_ORDER, OSServiceId_ResumeOSInterrupts, 0 );
    OSOrtiServiceWatchOnExit( OSServiceId_ResumeOSInterrupts );
    return;
  }
#endif                                  /* defined (OSEXTSTATUS) && defined(OSHOOKERROR) */
  OsSuspendLevel--;                     /* decrease counter of nested Suspend/Resume pairs */

  /* if outmost level of Suspend/Resume pair, then return interrupt state */
  /* else - nothing to do */
  if( OsSuspendLevel == 0 )
  {
    OsResumeInterrupts();               /* resume OS interrupts macro */
  }

  OSOrtiServiceWatchOnExit( OSServiceId_ResumeOSInterrupts );
}

/***************************************************************************
 * Function:    SuspendOSInterrupts
 *
 * Description: Save interrupt state and disable all OS interrupts
 *
 * Returns: E_OK
 *
 * Notes:   
 *
 **************************************************************************/
void SuspendOSInterrupts( void )
{
  OSOrtiSetServiceWatch( OSServiceId_SuspendOSinterrupts );
  /* if first call of Suspend Interrupts, then disable them */
  /* else - nothing to do */
  if( OsSuspendLevel == 0 )
  {
    OsSuspendInterrupts();              /* suspend OS interrupts macro */
  }

#if defined (OSEXTSTATUS) && defined(OSHOOKERROR)
  if((OsSuspendLevel + OsSuspendLevelAll) < 32 )
  {
    OsIntCheck &= ~( 0x1 << (OsSuspendLevel + OsSuspendLevelAll) );
  }
#endif                                  /* defined (OSEXTSTATUS) && defined(OSHOOKERROR) */
  OsSuspendLevel++;                     /* increase counter of nested Suspend/Resume pairs */
  OSOrtiServiceWatchOnExit( OSServiceId_SuspendOSinterrupts );
}
#endif                                  /* defined(OSISRNORMAL) */

/***************************************************************************
 * Function:    ResumeAllInterrupts
 *
 * Description: Restore interrupt state saved by DisableAllInterrupts service
 *
 * Returns: 
 *
 * Notes:   1.  This function is MD.
 *
 **************************************************************************/
void ResumeAllInterrupts( void )
{
  OSOrtiSetServiceWatch( OSServiceId_ResumeAllInterrupts );
#if defined (OSEXTSTATUS) && defined(OSHOOKERROR)
  if( OsSuspendLevelAll == 0 )
  {
    OSErrorHook( E_OS_SYS_ORDER, OSServiceId_ResumeAllInterrupts, 0 );
    OSOrtiServiceWatchOnExit( OSServiceId_ResumeAllInterrupts );
    return;
  }
#if defined (OSISRNORMAL)
  if( ((OsSuspendLevel + OsSuspendLevelAll) <= 32 ) &&
   ( OsIntCheck & ( 0x1 << ( OsSuspendLevel + OsSuspendLevelAll - 1 ) ) ) == 0 )
  {
    OSErrorHook( E_OS_SYS_ORDER, OSServiceId_ResumeAllInterrupts, 0 );
    OSOrtiServiceWatchOnExit( OSServiceId_ResumeAllInterrupts );
    return;
  }
#endif                                  /* defined (OSISRNORMAL) */
#endif                                  /* defined (OSEXTSTATUS) && defined(OSHOOKERROR) */
  OsSuspendLevelAll--;                  /* decrease counter of nested Suspend/Resume pairs */

  if( OsSuspendLevelAll == 0 )
  {                                     /* if at outmost level of Suspend/Resume pair, restore interrupt level  */
    OSRESTOREMSR( OsOldIntMaskAll );
  }                                     /* else - nothing to do         */
  OSOrtiServiceWatchOnExit( OSServiceId_ResumeAllInterrupts );
}

/***************************************************************************
 * Function:    SuspendAllInterrupts
 *
 * Description: Save interrupt state and disable all OS interrupts
 *
 * Returns: 
 *
 * Notes:   1.  This function is MD.
 *
 **************************************************************************/
void SuspendAllInterrupts( void )
{

  OSOrtiSetServiceWatch( OSServiceId_SuspendAllinterrupts );
  if( OsSuspendLevelAll == 0 )
  {                                     /* if it is the first call to SuspendAllInterrupts, then disable them */
    OSSAVEMSR(OsOldIntMaskAll);
    OSDCHI();                           /* disable all ext.interrupts */
  }

#if defined (OSEXTSTATUS) && defined(OSHOOKERROR) && defined (OSISRNORMAL)
  if( ((OsSuspendLevel + OsSuspendLevelAll) < 32 ) )
  {
    OsIntCheck |= 0x1 << (OsSuspendLevel + OsSuspendLevelAll);
  }
#endif                                  /* defined (OSEXTSTATUS) && defined(OSHOOKERROR) && defined (OSISRNORMAL)  */
  OsSuspendLevelAll++;                  /* increase counter of nested Suspend/Resume pairs */
  OSOrtiServiceWatchOnExit( OSServiceId_SuspendAllinterrupts );
  OSWARNSUPPRESS                        /* For extra CW warning suppress */
}

