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

VxWorks

开发平台:

C/C++

  1. /* ppc555Intr.c - PowerPC 555 interrupt driver */
  2. /* Copyright 1984-1998 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01b,12apr99,zl   lock interrupts before restoring mask
  8. 01a,16mar99,zl   written based on ppc860Intr.c.
  9. */
  10. /*
  11. DESCRIPTION
  12. The PowerPC 555 CPU series is divided in several units: PowerPC core, System
  13. Interface Unit (SIU), and on-chip periferal units. The PowerPC core accepts 
  14. only one external interrupt exception (vector 0x500). The SIU provides an 
  15. interrupt controller which provides 32 levels but only 16 are used. The 
  16. Interrupt controller is connected to the PowerPC core external interrupt. This 
  17. library provides the routines to manage this interrupt controller.
  18. ppc555IntrInit() connects the default demultiplexer, ppc555IntrDemux, to the 
  19. external interrupt vector and initializes a table containing a function pointer
  20. and an associated parameter for each interrupt source. ppc555IntrInit() is 
  21. called by sysHwInit() from sysLib.c.
  22. The default demultimplexer, ppc555IntrDeMux() detects which peripheral or 
  23. controller has raised an interrupt and calls the associated routine with its 
  24. parameter. 
  25. Note: at this time only one interrupt source can be connected to a given level.
  26. This gives only 16 different sources, of which 8 are external. To relieve this
  27. restriction, interrupt handlers sharing the same level should be stored in a 
  28. linked list and should be called one by one. It would be the ISRs responsability
  29. to determine if it is really an interrupt condition. If not then simply return.
  30. INCLUDE FILES: drv/intrCtl/ppc555Intr.h, drv/multi/ppc555Siu.h
  31. */
  32. /* includes */
  33. #include "intLib.h"
  34. #include "iv.h"
  35. #include "drv/intrCtl/ppc555Intr.h"
  36. #include "drv/multi/ppc555Siu.h"
  37. #ifdef  INCLUDE_WINDVIEW
  38. #include "private/funcBindP.h"
  39. #include "private/eventP.h"
  40. #endif /* INCLUDE_WINDVIEW */
  41. IMPORT UINT32 vxImemBaseGet();
  42. /* local */
  43. LOCAL INTR_HANDLER intrVecTable[NUM_VEC_MAX]; /*  Intr vector table */
  44. /* forward declarations */
  45. LOCAL void ppc555IntrDemux (void);
  46. LOCAL STATUS ppc555IntConnect (VOIDFUNCPTR *, VOIDFUNCPTR, int);
  47. LOCAL int ppc555IntEnable (int);
  48. LOCAL int ppc555IntDisable (int);
  49. /*******************************************************************************
  50. *
  51. * ppc555IntrInit - initialize the interrupt manager for the PowerPC 500 series
  52. *
  53. * This routine connects the default demultiplexers, ppc555IntHandler() to 
  54. * the external interrupt vector and associates all interrupt sources with 
  55. * the default interrupt handler.  This routine is called by sysHwInit() 
  56. * in sysLib.c.
  57. *
  58. * RETURN : OK
  59. */
  60. STATUS ppc555IntrInit 
  61.     (
  62.     )
  63.     {
  64.     VOIDFUNCPTR defaultVec;      /* default vector */
  65.     int vector;
  66.     /* Get the default vector connected to the External Interrupt (0x500) */
  67.     defaultVec = (VOIDFUNCPTR) excVecGet ((FUNCPTR *) _EXC_OFF_INTR);
  68.     /* Connect the interrupt demultiplexer to External Interrupt (0x500) */
  69.     excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_INTR, ppc555IntrDemux);
  70.     /* Install the driver routines in the architecture hooks */
  71.     if (_func_intConnectRtn == NULL)
  72.         _func_intConnectRtn = ppc555IntConnect;
  73.     if (_func_intEnableRtn == NULL)
  74.         _func_intEnableRtn = ppc555IntEnable;
  75.     if (_func_intDisableRtn == NULL)
  76.         _func_intDisableRtn = ppc555IntDisable;
  77.     /* Set all vectors to default handler */
  78.     for (vector = 0; vector < NUM_VEC_MAX; vector++)
  79. intConnect (INUM_TO_IVEC(vector), defaultVec, 0);
  80.     return (OK);
  81.  
  82.    }
  83. /*******************************************************************************
  84. *
  85. * ppc555IntConnect - connect a routine to an interrupt 
  86. *
  87. * This routine connects any C or assembly routine to one of the multiple 
  88. * sources of interrupts.
  89. *
  90. * The connected routine can be any normal C code, except that it must not 
  91. * invoke certain operating system functions that may block or perform I/O
  92. * operations.
  93. *
  94. * <vector> types are defined in h/drv/intrClt/ppc555Intr.h.
  95. *
  96. * RETURNS: OK, or ERROR if <vector> is unknown.
  97. *
  98. * SEE ALSO: ppc555Intr.h
  99. */
  100. LOCAL STATUS ppc555IntConnect
  101.     (
  102.     VOIDFUNCPTR * vector, /* interrupt vector to attach to */
  103.     VOIDFUNCPTR routine, /* routine to be called */
  104.     int  parameter /* parameter to be passed to routine */
  105.     )
  106.     {
  107.     /* test the vector */
  108.     if (IVEC_TO_INUM(vector) >= NUM_VEC_MAX)
  109. return (ERROR);
  110.     intrVecTable[IVEC_TO_INUM(vector)].vec = routine;
  111.     intrVecTable[IVEC_TO_INUM(vector)].arg = parameter;
  112.     return (OK);
  113.     }
  114. /*******************************************************************************
  115. *
  116. * ppc555IntHandler - SIU interrupt demultiplexer 
  117. *
  118. * This routine must be bound to external interrupt exception (vector 0x500). 
  119. * It is used to call the appropriate handler with its argument when an
  120. * interrupt occurs. 
  121. *
  122. * NOTE: when this function is called the interrupts are still locked. It's
  123. * this function responsability to unlock the interrupt.
  124. *
  125. * RETURNS: N/A
  126. */
  127. void ppc555IntrDemux (void)
  128.     {
  129.     UINT8  intVec; /* interrupt vector */
  130.     UINT32 imemBase; /* internal memory Base Address */
  131.     UINT32 intMask; /* current interrupt mask */
  132.     imemBase = vxImemBaseGet(); /* Internal memory base address */
  133.     /* read the interrupt vector register */
  134.     intVec = (* SIVEC(imemBase)) >> 26;
  135. #ifdef  INCLUDE_WINDVIEW
  136.     WV_EVT_INT_ENT(intVec)
  137. #endif /* INCLUDE_WINDVIEW */
  138.     /* save the current interrupt mask */ 
  139.     intMask = * SIMASK(imemBase);
  140.     /* lock all levels inferior to the interrupt detected */
  141.     * SIMASK(imemBase) &= (0xffffffff << (32 - intVec));
  142.     /* unlock the interrupt */
  143.     intUnlock (_PPC_MSR_EE);
  144.     /* call the Interrupt Handler */
  145.     intrVecTable[intVec].vec (intrVecTable[intVec].arg);
  146.     /* lock interrupts */
  147.     intLock ();
  148.     /* restore the interrupt mask */
  149.     * SIMASK(imemBase) = intMask;
  150.     return;
  151.     }
  152. /*******************************************************************************
  153. *
  154. * ppc555IntEnable - enable one of the Level or IRQ interrupts into the SIU
  155. *
  156. * This routine will unmask the bit in the SIMASK register corresponding to
  157. * the requested interrupt level.  The interrupt level must be in the range
  158. * of 0 - 31.
  159. * RETURNS: 0, always.
  160. */
  161. LOCAL int ppc555IntEnable
  162.     (
  163.     int intNum /* interrupt level to enable (0 - 31) */
  164.     )
  165.     {
  166.     UINT32 imemBase;
  167.     imemBase = vxImemBaseGet();
  168.     if ((intNum >= 0) && (intNum < 32))
  169. * SIMASK(imemBase) |= (1 << (31 - intNum));
  170.     return 0;
  171.     }
  172. /*******************************************************************************
  173. *
  174. * ppc555IntDisable - Disable one of the Level or IRQ interrupts into the SIU
  175. *
  176. * This routine will mask the bit in the SIMASK register corresponding to
  177. * the requested interrupt level.  The interrupt level must be in the range
  178. * of 0 - 31.
  179. * RETURNS: 0, always.
  180. */
  181. LOCAL int ppc555IntDisable
  182.     (
  183.     int intNum          /* interrupt level to disable (0 - 31) */
  184.     )
  185.     {
  186.     UINT32 imemBase;
  187.     
  188.     imemBase = vxImemBaseGet();
  189.     if ((intNum >= 0) && (intNum < 32))
  190.         * SIMASK(imemBase) &= ~(1 << (31 - intNum));
  191.     return 0;
  192.     }