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

VxWorks

开发平台:

C/C++

  1. /* templateVme.c - template VMEbus library */
  2. /* Copyright 1984-1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. TODO - Remove the template modification history and begin a new history
  8. starting with version 01a and growing the history upward with
  9. each revision.
  10. 01b,02apr97,dat  chg'd sysBusToLocalAdrs, and sysLocalToBusAdrs
  11. 01a,10mar97,dat  written, from nullVme.c, ver 01g
  12. */
  13. /*
  14. TODO - This is an example driver.  The documentation and code must be
  15. replaced with appropriate information.
  16. DESCRIPTION
  17. Describe the complete device, including features not controlled by this
  18. driver.
  19. Describe the device's VME capabilities, including those not supported or
  20. used by this driver.  Describe the capabilities this driver does support
  21. and any restrictions or limitations imposed.
  22. The functions usually addressed here include:
  23.     Mapping of master and slave windows on the bus.
  24.     Test and set functions on the bus.
  25.     Bus interrupt functions:
  26. - enable/disable VMEbus interrupt levels
  27. - generate bus interrupts
  28.     Mailbox/locations monitor functions:
  29. - enable mailbox/location monitor interrupts
  30. In this example, the following macros control the mapping of VMEbus addresses
  31. to local addresses.  Master accesses are accesses where the local processor
  32. is the bus master.  The one-time setup of the control registers that implements
  33. master windows is normally done in sysHwInit(), in file sysLib.c.
  34.     VME_A16_MSTR_BUS Master window base (bus addr)
  35.     VME_A16_MSTR_SIZE Master window size
  36.     VME_A16_MSTR_LOCAL Local address of window
  37.     VME_A24_MSTR_BUS Master window base (bus addr)
  38.     VME_A24_MSTR_SIZE Master window size
  39.     VME_A24_MSTR_LOCAL Local address of window
  40.     VME_A32_MSTR_BUS Master window base (bus addr)
  41.     VME_A32_MSTR_SIZE Master window size
  42.     VME_A32_MSTR_LOCAL Local address of window
  43. Slave accesses are initiated by some other CPU and the board acts as
  44. the VMEbus slave device.  When a CPU exports it's memory to the bus, it
  45. is creating a slave window on the bus.  In this example driver, the
  46. following macros describe the slave windows on the VMEbus.  The setup
  47. of the slave window control registers is usually a one-time operation
  48. done as part of sysProcNumSet, and only for processor number 0.
  49.     VME_A16_SLV_LOCAL Local address mapped to window on bus.
  50.     VME_A16_SLV_WINDOW Bus address of window
  51.     VME_A16_SLV_SIZE Slave window size
  52.     VME_A24_SLV_LOCAL Local address mapped to window on bus.
  53.     VME_A24_SLV_WINDOW Bus address of window
  54.     VME_A24_SLV_SIZE Slave window size
  55.     VME_A32_SLV_LOCAL Local address mapped to window on bus.
  56.     VME_A32_SLV_WINDOW Bus address of window
  57.     VME_A32_SLV_SIZE Slave window size
  58. This sample driver uses the macros mentioned above to implement the functions
  59. sysBusToLocalAdrs() and sysLocalToBusAdrs().  These are commonly declared
  60. directly in the sysLib.c file rather than a driver file.  Declaring them 
  61. in the driver is preferred.
  62. The macros described above are usually defined in either config.h or
  63. <target>.h.  Those macros that are user changeable should be in config.h, while
  64. those that are fixed and unchangeable should be in <target>.h.  The user
  65. should be able to set any xxxx_SIZE macro to 0 and cause the associated window,
  66. master or slave, to be disabled.
  67. INCLUDES:
  68. vme.h, vxLib.h, sysLib.h
  69. */
  70. /* This driver contributes nothing, if INCLUDE_VME is not defined. */
  71. #ifdef INCLUDE_VME
  72. /* includes */
  73. #include "vme.h"
  74. #include "vxLib.h"
  75. #include "sysLib.h"
  76. /* locals */
  77. LOCAL FUNCPTR sysMailboxRoutine  = NULL;
  78. LOCAL int sysMailboxArg          = NULL;
  79. /*******************************************************************************
  80. *
  81. * sysIntDisable - disable a bus interrupt level
  82. *
  83. * This routine disables a specified VMEbus interrupt level.  SysHwInit()
  84. * should have disabled all interrupts by default.  It should not be
  85. * necessary to disable individual interrupts following startup.
  86. *
  87. * RETURNS: OK, or ERROR if <intLevel> is not in the range 1 - 7.
  88. *
  89. * SEE ALSO: sysIntEnable()
  90. */
  91. STATUS sysIntDisable
  92.     (
  93.     int intLevel        /* interrupt level to disable (1-7) */
  94.     )
  95.     {
  96.     if (intLevel < 1 || intLevel > 7)
  97.         return (ERROR);
  98.     /* TODO - Disable the requested interrupt level */
  99.     return (OK);
  100.     }
  101. /*******************************************************************************
  102. *
  103. * sysIntEnable - enable a bus interrupt level
  104. *
  105. * This routine enables a specified VMEbus interrupt level.  At startup,
  106. * sysHwInit() should have disabled all interrupts.  Specific interrupts
  107. * must be enabled if interrupts are expected.
  108. *
  109. * RETURNS: OK, or ERROR if <intLevel> is not in the range 1 - 7.
  110. *
  111. * SEE ALSO: sysIntDisable()
  112. */
  113. STATUS sysIntEnable
  114.     (
  115.     int intLevel        /* interrupt level to enable (1-7) */
  116.     )
  117.     {
  118.     if (intLevel < 1 || intLevel > 7)
  119.         return (ERROR);
  120.     /* TODO - Enable the requested interrupt level */
  121.     return (OK);
  122.     }
  123. /******************************************************************************
  124. *
  125. * sysBusIntAck - acknowledge a bus interrupt
  126. *
  127. * This routine acknowledges a specified VMEbus interrupt level.
  128. *
  129. * RETURNS: NULL.
  130. */
  131. int sysBusIntAck
  132.     (
  133.     int intLevel        /* interrupt level to acknowledge */
  134.     )
  135.     {
  136.     /* TODO - perform any special acknowledge cycles */
  137.     return (NULL);
  138.     }
  139. /******************************************************************************
  140. *
  141. * sysBusIntGen - generate a bus interrupt
  142. *
  143. * This routine generates a VMEbus interrupt for a specified level with a
  144. * specified vector.
  145. *
  146. * WARNING:
  147. * The local CPU is sending an interrupt to a remote CPU.  If the local
  148. * CPU has enabled the same VMEbus interrupt level that it is sending, then
  149. * the local CPU will interrupt itself and this sequence will probably fail.
  150. *
  151. * RETURNS: OK or ERROR if unable to generate requested interrupt.
  152. */
  153. STATUS sysBusIntGen
  154.     (
  155.     int level,          /* bus interrupt level to generate          */
  156.     int vector          /* interrupt vector to return (0-255)       */
  157.     )
  158.     {
  159.     /*
  160.      * TODO - cause interrupt to occur on the VMEbus, present vector
  161.      * during IACK cycle.
  162.      */
  163.     return (ERROR);
  164.     }
  165. /*******************************************************************************
  166. *
  167. * sysMailboxInt - handle mailbox interrupt
  168. *
  169. * Mailbox interrupts usually must be acknowledged.
  170. *
  171. * RETURNS: N/A.
  172. */
  173. LOCAL void sysMailboxInt (void)
  174.     {
  175.     /* TODO - Acknowledge and reset mailbox interrupt as needed */
  176.     if (sysMailboxRoutine != NULL)
  177.         sysMailboxRoutine (sysMailboxArg);
  178.     }
  179. /******************************************************************************
  180. *
  181. * sysMailboxConnect - connect a routine to the mailbox interrupt
  182. *
  183. * This routine specifies the interrupt service routine to be called at each
  184. * mailbox interrupt.
  185. *
  186. * RETURNS: OK or ERROR, if mailboxes are not supported.
  187. *
  188. * SEE ALSO: sysMailboxEnable()
  189. */
  190. STATUS sysMailboxConnect
  191.     (
  192.     FUNCPTR routine,    /* routine called at each mailbox interrupt */
  193.     int     arg         /* argument with which to call routine      */
  194.     )
  195.     {
  196.     sysMailboxRoutine   = NULL;
  197.     sysMailboxArg       = arg;
  198.     sysMailboxRoutine   = routine;
  199.     return (OK);
  200.     }
  201. /******************************************************************************
  202. *
  203. * sysMailboxEnable - enable the mailbox interrupt
  204. *
  205. * This routine enables the mailbox interrupt.
  206. *
  207. * RETURNS: OK or ERROR if mailboxes are not supported.
  208. *
  209. * SEE ALSO: sysMailboxConnect()
  210. */
  211. STATUS sysMailboxEnable
  212.     (
  213.     INT8 *mailboxAdrs           /* mailbox address */
  214.     )
  215.     {
  216.     static BOOL connected = FALSE;
  217.     if (!connected)
  218. {
  219. /* TODO - connect the mailbox interrupt */
  220. connected = TRUE;
  221. }
  222.     /* TODO - enable mailbox interrupts */
  223.     return (ERROR);
  224.     }
  225. /********************************************************************************
  226. * sysBusTas - test and set a location across the bus
  227. *
  228. * This routine performs a test-and-set (TAS) instruction across the backplane.
  229. *
  230. * RETURNS: TRUE if the value had not been set but is now,
  231. * or FALSE if the value was set already.
  232. *
  233. * SEE ALSO: vxTas()
  234. */
  235.  
  236. BOOL sysBusTas
  237.     (
  238.     INT8 *addr          /* address to be tested and set */
  239.     )
  240.     {
  241.     /* TODO - Modify as necessary to guarantee atomic read/write operation */
  242.     return (vxTas(addr));       /* RMW cycle */
  243.     }
  244. /********************************************************************************
  245. * sysBusTasClear - clear a test and set location on the bus
  246. *
  247. * This routine clears a bus test and set location.  Usually this routine is
  248. * not even required.  It is required if the sysBusTas() routine uses any
  249. * special semaphore techniques.
  250. *
  251. * If used, the BSP activates this routine by placing its address into the
  252. * global variable 'smUtilTasClearRtn'. e.g.
  253. *
  254. smUtilTasClearRtn = sysBusTasClear;
  255. *
  256. * RETURNS: N/A.
  257. */
  258.  
  259. void sysBusTasClear
  260.     (
  261.     INT8 *addr          /* address to be cleared */
  262.     )
  263.     {
  264.     /* TODO - Modify as necessary to guarantee atomic read/write operation */
  265.     *addr = 0;
  266.     }
  267. /*******************************************************************************
  268. *
  269. * sysLocalToBusAdrs - convert a local address to a bus address
  270. *
  271. * This routine gets the VMEbus address that accesses a specified local
  272. * memory address.
  273. *
  274. * RETURNS: OK, or ERROR if the address space is unknown or not mapped. 
  275. *
  276. * SEE ALSO: sysBusToLocalAdrs()
  277. */
  278.  
  279. STATUS sysLocalToBusAdrs
  280.     (
  281.     int adrsSpace,        /* bus address space in which pBusAdrs resides */
  282.     char * pLocalAdrs,    /* local address to convert                   */ 
  283.     char ** ppBusAdrs     /* where to return bus address                */ 
  284.     )
  285.     {
  286.     /* return error if local memory is not mapped to VMEbus */
  287.     if (sysProcNumGet () != 0)
  288. return ERROR;
  289.     switch (adrsSpace)
  290.         {
  291.         case VME_AM_EXT_SUP_PGM:
  292.         case VME_AM_EXT_SUP_DATA:
  293.         case VME_AM_EXT_USR_PGM:
  294.         case VME_AM_EXT_USR_DATA:
  295.     if ((VME_A32_SLV_SIZE != 0) &&
  296. ((ULONG)localAdrs >= VME_A32_SLV_LOCAL) &&
  297. ((ULONG)localAdrs < (VME_A32_SLV_LOCAL + VME_A32_SLV_SIZE)))
  298. {
  299.                 *pBusAdrs = localAdrs + (VME_A32_SLV_BUS - VME_A32_SLV_LOCAL);
  300.                 return (OK);
  301.                 }
  302.     return (ERROR);
  303.         case VME_AM_STD_SUP_PGM:
  304.         case VME_AM_STD_SUP_DATA:
  305.         case VME_AM_STD_USR_PGM:
  306.         case VME_AM_STD_USR_DATA:
  307.     if ((VME_A24_SLV_SIZE != 0) &&
  308. ((ULONG)localAdrs >= VME_A24_SLV_LOCAL) &&
  309. ((ULONG)localAdrs < (VME_A24_SLV_LOCAL + VME_A24_SLV_SIZE)))
  310. {
  311.                 *pBusAdrs = localAdrs + (VME_A24_SLV_BUS - VME_A24_SLV_LOCAL);
  312.                 return (OK);
  313.                 }
  314.     return (ERROR);
  315.         case VME_AM_SUP_SHORT_IO:
  316.         case VME_AM_USR_SHORT_IO:
  317.     if ((VME_A16_SLV_SIZE != 0) &&
  318. ((ULONG)localAdrs >= VME_A16_SLV_LOCAL) &&
  319. ((ULONG)localAdrs < (VME_A16_SLV_LOCAL + VME_A16_SLV_SIZE)))
  320. {
  321.                 *pBusAdrs = localAdrs + (VME_A16_SLV_BUS - VME_A16_SLV_LOCAL);
  322.                 return (OK);
  323.                 }
  324.     return (ERROR);
  325.  
  326.         default:
  327.             return (ERROR);
  328.         }
  329.     }
  330. /*******************************************************************************
  331. *
  332. * sysBusToLocalAdrs - convert a bus address to a local address
  333. *
  334. * This routine gets the local address that accesses a specified VMEbus
  335. * memory address.
  336. *
  337. * RETURNS: OK, or ERROR if the address space is unknown or the mapping is not
  338. * possible.
  339. *
  340. * SEE ALSO: sysLocalToBusAdrs()
  341. */
  342. STATUS sysBusToLocalAdrs
  343.     (
  344.     int adrsSpace,      /* bus address space in which pBusAdrs resides */
  345.     char *pBusAdrs,      /* bus address to convert                     */
  346.     char **ppLocalAdrs   /* where to return local address              */
  347.     )
  348.     {
  349.     switch (adrsSpace)
  350. {
  351. case VME_AM_EXT_SUP_PGM:
  352. case VME_AM_EXT_USR_PGM:
  353. case VME_AM_EXT_SUP_DATA:
  354. case VME_AM_EXT_USR_DATA:
  355.     if ((VME_A32_MSTR_SIZE == 0) ||
  356. ((ULONG) busAdrs < VME_A32_MSTR_BUS) ||
  357. ((ULONG) busAdrs >= (VME_A32_MSTR_BUS + VME_A32_MSTR_SIZE)))
  358. {
  359.      return (ERROR);
  360. }
  361.     *pLocalAdrs = (char *)busAdrs +
  362.     (VME_A32_MSTR_LOCAL - VME_A32_MSTR_BUS);
  363.     return (OK);
  364. case VME_AM_STD_SUP_PGM:
  365. case VME_AM_STD_USR_PGM:
  366. case VME_AM_STD_SUP_DATA:
  367. case VME_AM_STD_USR_DATA:
  368.     if ((VME_A24_MSTR_SIZE == 0) ||
  369. ((ULONG) busAdrs < VME_A24_MSTR_BUS) ||
  370. ((ULONG) busAdrs >= (VME_A24_MSTR_BUS + VME_A24_MSTR_SIZE)))
  371. {
  372. return (ERROR);
  373. }
  374.     *pLocalAdrs = (char *) busAdrs +
  375.     (VME_A24_MSTR_LOCAL - VME_A24_MSTR_BUS);
  376.     return (OK);
  377.         case VME_AM_SUP_SHORT_IO:
  378.         case VME_AM_USR_SHORT_IO:
  379.     if ((VME_A16_MSTR_SIZE == 0) ||
  380. ((ULONG) busAdrs < VME_A16_MSTR_BUS) ||
  381. ((ULONG) busAdrs >= (VME_A16_MSTR_BUS + VME_A16_MSTR_SIZE)))
  382. {
  383. return (ERROR);
  384. }
  385.             *pLocalAdrs = (char *) busAdrs + 
  386.     (VME_A16_MSTR_LOCAL - VME_A16_MSTR_BUS);
  387.             return (OK);
  388. default:
  389.     return (ERROR);
  390. }
  391.     }
  392. #endif /*INCLUDE_VME*/