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

VxWorks

开发平台:

C/C++

  1. /* sun4Vme.c - Sun VMEbus library */
  2. /* Copyright 1984-1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01e,04jan97,p_m  changed sysBusTasClear back to sysBusClearTas for backward
  8.                  compatibility
  9. 01d,11jun96,wlf  doc: cleanup; changed sysBusClearTas() to sysBusTasClear().
  10. 01c,15oct92,jwt  cleaned up ANSI compiler warnings.
  11. 01b,25sep92,ccc  fixed warning.
  12. 01a,17aug92,ccc  created by copying routines from sun1e sysLib.c.
  13. */
  14. /*
  15. DESCRIPTION
  16. This library contains routines which relate to the VMEbus functions of the
  17. Sun VMEbus gate array.
  18. The functions addressed here include:
  19.     Bus interrupt functions:
  20. - enable/disable VMEbus interrupt levels
  21. - generate bus interrupts
  22.     Mailbox/locations monitor functions:
  23. - enable mailbox/location monitor interrupts
  24. */
  25. /* locals */
  26. LOCAL FUNCPTR sysMailboxRoutine  = NULL;
  27. LOCAL int sysMailboxArg          = NULL;
  28. LOCAL BOOL sysMailboxConnected   = FALSE;
  29. /********************************************************************************
  30. * sysIntDisable - disable a bus interrupt level
  31. *
  32. * This routine disables a specified VMEbus interrupt level.
  33. *
  34. * RETURNS: OK, or ERROR if <intLevel> is not in the range 1 - 7.
  35. *
  36. * SEE ALSO: sysIntEnable()
  37. */
  38.  
  39. STATUS sysIntDisable
  40.     (
  41.     int intLevel       /* interrupt level to disable (1-7) */
  42.     )
  43.     {
  44.     if (intLevel < 1 || intLevel > 7)
  45. return (ERROR);
  46.     *SUN_BUS_IR &= ~(0x01 << intLevel);
  47.     return (OK);
  48.     }
  49. /********************************************************************************
  50. * sysIntEnable - enable a bus interrupt level
  51. *
  52. * This routine enables a specified VMEbus interrupt level.
  53. *
  54. * RETURNS: OK, or ERROR if <intLevel> is not in the range 1 - 7.
  55. *
  56. * SEE ALSO: sysIntDisable()
  57. */
  58.  
  59. STATUS sysIntEnable
  60.     (
  61.     int intLevel       /* interrupt level to enable (1-7) */
  62.     )
  63.     {
  64.     if (intLevel < 1 || intLevel > 7)
  65. return (ERROR);
  66.     *SUN_BUS_IR |= (0x01 << intLevel);
  67.     return (OK);
  68.     }
  69.  
  70. /********************************************************************************
  71. * sysBusIntAck - acknowledge a bus interrupt
  72. *
  73. * This routine acknowledges a specified VMEbus interrupt level.
  74. *
  75. * RETURNS: The vector put on the bus by the interrupting device.
  76. *
  77. * SEE ALSO: sysBusIntGen()
  78. */
  79.  
  80. int sysBusIntAck
  81.     (
  82.     int intLevel       /* interrupt level to acknowledge */
  83.     )
  84.     {
  85.     return ((int) (SUN_ACK [intLevel << 1]));
  86.     }
  87. /*******************************************************************************
  88. *
  89. * sysBusIntGen - generate a bus interrupt
  90. *
  91. * This routine generates a VMEbus interrupt for a specified level with a
  92. * specified vector.
  93. *
  94. * NOTE: This routine has no effect, since the CPU board cannot generate a 
  95. * VMEbus interrupt.
  96. *
  97. * RETURNS: ERROR, always.
  98. *
  99. * SEE ALSO: sysBusIntAck()
  100. */
  101.  
  102. STATUS sysBusIntGen
  103.     (
  104.     int  level,        /* VMEbus interrupt level to generate (1-7) */
  105.     int  vector        /* interrupt vector to generate (0-255)     */
  106.     )
  107.     {
  108.     return (ERROR);
  109.     }
  110. /**************************************************************************
  111. *
  112. * sysBusTas - test and set a location across the bus
  113. *
  114. * This routine performs an atomic SPARC test-and-set (TAS) instruction 
  115. * across a backplane.
  116. *
  117. * Read-modify-write cycles to DRAM can be made non-atomic by a VMEbus
  118. * access.  In that case, this routine locks out VMEbus access during the
  119. * call to vxTas().  For VMEbus accesses, vxTas() is called directly.
  120. *
  121. * NOTE: This routine is equivalent to vxTas(), since there is no VMEbus.
  122. *
  123. * RETURNS: TRUE if the value had not been set but is now,
  124. * or FALSE if the value was set already.
  125. *
  126. * SEE ALSO: vxTas()
  127. */
  128.  
  129. BOOL sysBusTas
  130.     (
  131.     char *      addr                    /* address to be tested and set */
  132.     )
  133.     {
  134.     int  oldLevel;                      /* Lock interrupts for DRAM TAS */
  135.     BOOL status;                        /* vxTas() return value */
  136.  
  137.     if (((void *) addr >= (void *) LOCAL_MEM_LOCAL_ADRS) &&
  138.         ((void *) addr < (void *) (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE)))
  139.         {
  140.         oldLevel = intLock ();          /* Lock interrupts */
  141.         *SUN_BUS_LOCK = BUS_LOCK_REQUEST;
  142.         while ((*SUN_BUS_LOCK & BUS_LOCK_GRANT) != BUS_LOCK_GRANT);
  143.  
  144.         status = vxTas (addr);          /* Local RMW cycle */
  145.  
  146.         *SUN_BUS_LOCK = BUS_LOCK_RELEASE;
  147.  
  148.         intUnlock (oldLevel);           /* Restore interrupt level */
  149.         }
  150.     else
  151.         {
  152.         status = vxTas (addr);          /* VMEbus RMW cycle */
  153.         }
  154.  
  155.     return (status);
  156.     }
  157.  
  158. /**************************************************************************
  159. *
  160. * sysBusClearTas - clear a location set by sysBusTas()
  161. *
  162. * This routine clears the specified location if it has been set by a
  163. * call to sysBusTas(). 
  164. *
  165. * RETURNS: N/A
  166. *
  167. * SEE ALSO: sysBusTas()
  168. */
  169. void sysBusClearTas
  170.     (
  171.     char *      addr                    /* address to be cleared */
  172.     )
  173.     {
  174.     *addr = 0;                          /* clear byte set by LDSTUB */
  175.     }
  176. /*******************************************************************************
  177. *
  178. * sysMailboxInt - handle a mailbox interrupt
  179. *
  180. * This routine handles the mailbox interrupt.  It is attached to the mailbox
  181. * interrupt vector by the routine sysMailboxConnect().  The appropriate
  182. * routine is called and the interrupts are acknowledged.
  183. *
  184. * RETURNS: N/A
  185. *
  186. * SEE ALSO: sysMailboxConnect()
  187. */
  188. LOCAL void sysMailboxInt (void)
  189.     {
  190.     char mboxReg = *SUN_MBOX;
  191.     if (((mboxReg & MBOX_INT_PENDING) == MBOX_INT_PENDING) &&
  192.         (sysMailboxRoutine != NULL))
  193.         (*(FUNCPTR) sysMailboxRoutine) (sysMailboxArg);
  194.     }
  195. /********************************************************************************
  196. * sysMailboxConnect - connect a routine to the mailbox interrupt
  197. *
  198. * This routine specifies the interrupt service routine to be called at each 
  199. * mailbox interrupt.
  200. *
  201. * RETURNS: OK, or ERROR if the routine cannot be connected to the interrupt.
  202. *
  203. * SEE ALSO: intConnect(), sysMailboxEnable()
  204. */
  205.  
  206. STATUS sysMailboxConnect
  207.     (
  208.     FUNCPTR routine,   /* routine called at each mailbox interrupt */
  209.     int arg            /* argument with which to call routine      */
  210.     )
  211.     {
  212.     if (!sysMailboxConnected)
  213.         if (intConnect ((VOIDFUNCPTR *) INUM_TO_IVEC (INT_VEC_MBOX),
  214.                     (VOIDFUNCPTR) sysMailboxInt, 0) == ERROR)
  215.             {
  216.             return (ERROR);
  217.             }
  218.     sysMailboxConnected = TRUE;
  219.     sysMailboxRoutine   = routine;
  220.     sysMailboxArg       = arg;
  221.  
  222.     return (OK);
  223.     }
  224. /*******************************************************************************
  225. *
  226. * sysMailboxEnable - enable the mailbox interrupt
  227. *
  228. * This routine enables the mailbox interrupt.
  229. *
  230. * NOTE: All bits, except bits 1 - 3, 14, and 15, must be zero for the
  231. * mailbox address.
  232. *
  233. * RETURNS: OK, always.
  234. *
  235. * SEE ALSO: sysMailboxConnect()
  236. */
  237. STATUS sysMailboxEnable
  238.     (
  239.     INT8 *mailboxAdrs   /* address of mailbox (ignored) */
  240.     )
  241.     {
  242.     static char dummy = 0;      /* force compiler to access location */
  243.     int ix;
  244.     dummy = *SUN_MBOX;          /* clear interrupt */
  245.     /* Enable interrupt at the location */
  246.     ix = (int) mailboxAdrs;
  247.     *SUN_MBOX = 0x40 | ((ix >> 11) & 0x18) | ((ix >> 1) & 0x07);
  248.     return (OK);
  249.     }