ppc403Intr.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* ppc403Intr.c - IBM 403 EVB-specific interrupt handling library */
  2. /* Copyright 1984-1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /* modification history
  5. -----------------------
  6. 01q,24jan02,pch  Fix Diab warnings
  7. 01p,24aug98,cjtc windview 2.0 event logging is now single step. Timestamp no
  8.                  longer stored by intEnt. Avoids out-of-sequence timestamps in
  9.                  event log (SPR 21868)
  10. 01o,16apr98,pr   moved triggering support from arch/ppc
  11. 01n,08apr98,pr   modified support for WindView 20
  12. 01m,07aug97,tam  fixed critical exception handling (SPR #8964).
  13. 01l,10jun97,wlf  doc: more cleanup.
  14. 01k,31mar97,tam  clear DMA interrupts properly in sysPpc403IntHandler(SPR 8285)
  15. 01j,19mar97,tam  mask CE bit as well (SPR 8192). Removed while loop in 
  16.  sysPpc403IntEnable() & sysPpc403IntDisable().
  17. 01i,09dec96,tpr  changed _func_intEnableRtn() & _func_intDisableRtn() return
  18.  type from void to int.
  19.  Added sysPpc403IntEnable() & sysPpc403IntDisable() return
  20.  code.
  21. 01h,15nov96,wlf  doc: cleanup.
  22. 01g,11jul96,pr   included eventP.h
  23. 01f,11jul96,pr   added windview instrumentation
  24. 01e,11jul96,tam  modified sysPpc403IntHandler to enable nested interrupt.
  25. 01d,18mar96,tam  added sysPpc403IntEnable/Disable and cleanup. 
  26. 01c,28feb96,tam  renamed and moved src/arch/ppc/intPpp403Lib.c to 
  27.  src/drv/intrCtl/ppc403Intr.c.
  28. 01b,09feb95,yao  enabled nested interrupt.
  29. 01a,28nov94,yao  created.
  30. */
  31. /*
  32. This library provides various interface routines to manipulate and connect 
  33. to external hardware interrupts for the PPC403GA Embedded Controller.  
  34. */
  35. #include "vxWorks.h"
  36. #include "logLib.h"
  37. #include "stdio.h"
  38. #include "private/eventP.h"
  39. /* defines */
  40. #define INT_LEVEL_MAX 31
  41. #define INT_LEVEL_MIN 0
  42. /* externals */
  43. IMPORT STATUS (*_func_intConnectRtn) (VOIDFUNCPTR *, VOIDFUNCPTR, int);
  44. IMPORT int (*_func_intEnableRtn) (int);
  45. IMPORT int (*_func_intDisableRtn) (int);
  46. /* globals */
  47. void            sysPpc403IntHandler (void);
  48. /* locals */
  49. LOCAL VOIDFUNCPTR  sysIntBlTbl [32] = {(VOIDFUNCPTR) NULL};
  50. LOCAL int      sysIntArg [32]   = {0};
  51. /* forward LOCAL functions declarations */
  52. LOCAL STATUS    sysPpc403IntConnect (VOIDFUNCPTR * vector, VOIDFUNCPTR routine,
  53.                                      int parameter);
  54. LOCAL int      sysPpc403IntEnable (int intLevel);
  55. LOCAL int      sysPpc403IntDisable (int intLevel);
  56. /*******************************************************************************
  57. *
  58. * sysPpc403IntrInit - initialize the PPC403GA interrupt facility 
  59. *
  60. * This routine initializes the interrupt facility for the PPC403GA Embedded
  61. * Controller.
  62. *
  63. * RETURNS: OK, always.
  64. */
  65. STATUS sysPpc403IntrInit (void)
  66.     {
  67.     /* set the BSP driver specific Interrupt Handler and intConnect routines */
  68.     _func_intConnectRtn = sysPpc403IntConnect;
  69.     _func_intEnableRtn = sysPpc403IntEnable;
  70.     _func_intDisableRtn = sysPpc403IntDisable;
  71.     return (OK);
  72.     }
  73. /*******************************************************************************
  74. *
  75. * sysPpc403IntConnect - connect a C routine to a hardware interrupt
  76. *
  77. * This routine connects a specified C routine to a specified
  78. * interrupt vector.  It is called by intConnect(). 
  79. *
  80. * The PPC403GA Embedded Controller does not provide vectors for external
  81. * interrupts.  Instead, vectors are assigned according to the bits in the
  82. * External Interrupt Enable Register (EXIER).
  83. * In case of DMA interrupts, the DMA Status register is always passed to 
  84. * the ISR as the argument <parameter>.
  85. *
  86. * RETURNS: OK, or ERROR if <vector> is out of range.
  87. * SEE ALSO: intConnect(), sysPpc403IntHandler()
  88. */
  89. LOCAL STATUS sysPpc403IntConnect 
  90.     (
  91.     VOIDFUNCPTR * vector, /* interrupt vector to attach to     */
  92.     VOIDFUNCPTR   routine, /* routine to be called              */
  93.     int           parameter /* parameter to be passed to routine */
  94.     )
  95.     {
  96.     if (((int)vector > INT_LEVEL_MAX) || ((int)vector < INT_LEVEL_MIN))
  97. return (ERROR);
  98.     else
  99. {
  100.         sysIntBlTbl[(int)vector] = routine;
  101.         sysIntArg[(int)vector]   = parameter;
  102.         return (OK);
  103. }
  104.     }
  105. /*******************************************************************************
  106. *
  107. * sysPpc403IntHandler - PPC403GA external interrupt handler
  108. *
  109. * This is the external interrupt handler for the PPC403GA
  110. * Embedded Controller.
  111. * In case of DMA interrupts, the DMA Status register is always passed to 
  112. * the ISR, that was connected to the DMA interrupt via intConnect(), as an 
  113. * argument.
  114. *
  115. * RETURNS: N/A
  116. */
  117. void sysPpc403IntHandler (void)
  118.     {
  119.     int vector;
  120.     INT32 exisr;
  121.     INT32 exier;
  122.     UINT32 dmaSrVal = 0; /* DMA Status reg. value */
  123.     /* get interrupts status and interrupt control register */
  124.     exisr = vxExisrGet ();
  125.     exier = vxExierGet ();
  126.     exisr = exisr & exier;
  127.     /* get interrupt number */
  128.     vector = vxFirstBit (exisr);
  129. #ifdef INCLUDE_WINDVIEW
  130.     WV_EVT_INT_ENT(vector)
  131. #endif
  132.     if (vector <= INT_LEVEL_MAX)
  133. {
  134. /* is this a DMA interrupt ? */
  135. if ((vector > 7) && (vector < 12))
  136.     {
  137.     /* 
  138.      * got a DMA interrupt: clear DMASR[CSX,TSX,RIX,CTX] bits for
  139.      * DMA channel X before interrupts are re-enabled.
  140.      * Pass the DMA status register to the ISR that proccesses the 
  141.      * DMA interrupt for channel X.
  142.      * This does prevent passing another argument than DMASR to the 
  143.      * ISR via intConnect, only for the DMA interrupts. However it 
  144.      * enables the ISR to detect the cause of the interrupt according
  145.      * to DMASR.
  146.      */
  147.     dmaSrVal = vxDmasrGet();
  148.     vxDmasrSet (dmaSrVal & ((0x88880040 >> (vector -8)) & 0xfff80070));
  149.     sysIntArg[vector] = (UINT32) dmaSrVal; 
  150.     }
  151. /* clear the interrupt status bit */
  152. vxExisrClear (1 << (INT_LEVEL_MAX - vector));
  153. /*
  154.  * Mask this and lower priority interrupt levels:
  155.  * the critical interrupt has the highest priority while the 
  156.  * external interrupt 4 has the lowest priority (cf EXIER reg.).
  157.  */
  158. vxExierSet ((0xFFFFFFFF << (INT_LEVEL_MAX+1 - vector)) & vxExierGet());
  159. /*
  160.  * enable interrupt nesting: an external interrupt cannot be nested
  161.  * with a critical interrupt (CINT or watchdog int.) due to the
  162.  * implementation of the support for critical interrupt. However
  163.  * critical interrupts may be nested with each other.
  164.  */
  165. if (vector == 0)
  166.     intUnlock (_PPC_MSR_CE);
  167. else
  168.     intUnlock (_PPC_MSR_EE | _PPC_MSR_CE);
  169.      if (sysIntBlTbl [vector] != (VOIDFUNCPTR) NULL)
  170.     (*sysIntBlTbl [vector]) (sysIntArg[vector]);
  171.      else
  172.     logMsg ("uninitialized interrupt vector %dn", vector, 0,0,0,0,0);
  173. /* re-enable interrupt mask */
  174. vxExierSet (exier);
  175. }
  176.     }
  177. /*******************************************************************************
  178. *
  179. * sysPpc403IntDisable - disable an external interrupt level
  180. *
  181. * This routine disables a specified external interrupt for the PPC403GA
  182. * Embedded Controller.
  183. *
  184. * RETURNS: OK, or ERROR if <intLevel> is not in the range 0 - 31.
  185. *
  186. * SEE ALSO: sysPpc403IntEnable()
  187. */
  188. LOCAL int sysPpc403IntDisable
  189.     (
  190.     int intLevel        /* interrupt level to disable */
  191.     )
  192.     {
  193.     UINT32 intMask;
  194.     if (intLevel > INT_LEVEL_MAX || intLevel < INT_LEVEL_MIN)
  195.         return (ERROR);
  196.     intMask = 1 << (INT_LEVEL_MAX - intLevel);
  197.     /* disable the interrupt level */
  198.     vxExierDisable (intMask);
  199.     vxExisrClear (intMask);          /* clear pending interrupts */
  200.     return (OK);
  201.     }
  202. /*******************************************************************************
  203. *
  204. * sysPpc403IntEnable - enable an external interrupt level
  205. *
  206. * This routine enables a specified external interrupt for the PPC403GA
  207. * Embedded Controller.
  208. *
  209. * RETURNS: OK, or ERROR if <intLevel> is not in the range 0 - 31.
  210. *
  211. * SEE ALSO: sysPpc403IntDisable()
  212. */
  213. LOCAL int sysPpc403IntEnable
  214.     (
  215.     int intLevel        /* interrupt level to enable */
  216.     )
  217.     {
  218.     UINT32 intMask;
  219.     if (intLevel > INT_LEVEL_MAX || intLevel < INT_LEVEL_MIN)
  220.         return (ERROR);
  221.     intMask = 1 << (INT_LEVEL_MAX - intLevel);
  222.     vxExisrClear (intMask);    /* clear pending interrupts */
  223.     /* enable the interrupt level */
  224.     vxExierEnable (intMask);
  225.     return (OK);
  226.     }