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

VxWorks

开发平台:

C/C++

  1. /* wdbBdmPktDrv.c - Bdm packet driver for lightweight UDP/IP */
  2. /* Copyright 1998-2001 Wind River Systems, Inc. */
  3. /*
  4. This is an unsupported release of the Background Debug Mode (BDM) Back
  5. End. It is provided AS IS with no warranties of any kind.
  6. */
  7. #include "copyright_wrs.h"
  8. /*
  9. modification history
  10. --------------------
  11. 01b,15sep01,dat  Use of WRS_ASM macro
  12. 01a,16jun98,vrd  written, inspired from wdbNetromPktDrv.c version 01h.
  13. */
  14. /*
  15. DESCRIPTION
  16. OVERVIEW
  17. This is a driver for WDB system which uses the BDM line and protocol to
  18. communicate with the HOST.
  19. USAGE
  20. The driver is typically only called only from usrWdb.c. The only directly
  21. callable routine in this module is wdbBdmPktDevInit().  Your configAll.h
  22. file will have to be modified so that WDB_COMM_TYPE is defined as
  23. WDB_COMM_BDM.
  24. DATA BUFFERING
  25. The drivers only need to handle one input packet at a time because
  26. the WDB protocol only supports one outstanding host-request at a time.
  27. If multiple input packets arrive, the driver can simply drop them.
  28. The driver then loans the input buffer to the WDB agent, and the agent
  29. invokes a driver callback when it is done with the buffer.
  30. For output, the agent will pass the driver a chain of mbufs, which
  31. the driver must send as a packet. When it is done with the mbufs,
  32. it calls wdbMbufChainFree() to free them.
  33. The header file wdbMbuflib.h provides the calls for allocating, freeing,
  34. and initializing mbufs for use with the lightweight UDP/IP interpreter.
  35. It ultimatly makes calls to the routines wdbMbufAlloc() and wdbMbufFree(),
  36. which are provided in source code in usrWdb.c.
  37. */
  38. /* includes */
  39. #include "vxWorks.h"
  40. #include "string.h"
  41. #include "errno.h"
  42. #include "intLib.h"
  43. #include "wdb/wdbLib.h"
  44. #include "wdb/wdbCommIfLib.h"
  45. #include "wdb/wdbMbufLib.h"
  46. #include "drv/wdb/wdbBdmPktDrv.h"
  47. /* defines */
  48. #define MIN min
  49. /* typedefs */
  50. typedef struct
  51.     {
  52.     UINT8 recvSem;
  53.     UINT8 padding;
  54.     UINT16 recvCount;
  55.     UINT8 recvBuffer [WDB_BDM_PKT_MTU];
  56.     UINT8 sendSem;
  57.     UINT8 padding2;
  58.     UINT16 sendCount;
  59.     UINT8 sendBuffer [WDB_BDM_PKT_MTU];
  60.     } BDM_COMM_BUFF;
  61. /* locals */
  62. LOCAL BDM_COMM_BUFF bdmCommBuff;
  63. LOCAL BDM_COMM_BUFF * pBdmCommBuff = &bdmCommBuff;
  64. LOCAL int pollDelay = 2; /* polling delay */
  65. /* forward declarations */
  66. LOCAL STATUS wdbBdmPoll (void *pDev);
  67. LOCAL STATUS wdbBdmTx (void *pDev, struct mbuf * pMbuf);
  68. LOCAL STATUS wdbBdmModeSet (void *pDev, uint_t newMode);
  69. LOCAL void wdbBdmFree (void *pDev);
  70. LOCAL void wdbBdmPollTask (void * pDev);
  71. LOCAL void wdbBdmTargetStop (void);
  72. LOCAL STATUS wdbBdmInitHardware (void);
  73. /******************************************************************************
  74. *
  75. * wdbBdmTargetStop - stop the CPU
  76. *
  77. * This routine contains CPU specific code to put the CPU in BDM mode.
  78. *
  79. * RETURNS: N/A
  80. *
  81. * NOMANUAL
  82. */
  83. LOCAL void wdbBdmTargetStop (void)
  84.     {
  85. #if  (CPU == CPU32)
  86.     WRS_ASM ("nop");
  87.     WRS_ASM (".word 0x4afa");
  88. #endif /* (CPU == CPU32) */
  89. #if  (CPU == PPC860)
  90.     WRS_ASM ("sc"); /* sc instruction */
  91. #if FALSE
  92.     WRS_ASM ("tw 31,0,0"); /* trap instruction */
  93. #endif /* FALSE */
  94. #endif /* (CPU == PPC860) */
  95.     }
  96. /******************************************************************************
  97. *
  98. * wdbBdmInitHardware - initialize the BDM communiction buffer
  99. *
  100. * This routine computes the input and the output buffer address.
  101. *
  102. * RETURNS: N/A
  103. *
  104. * NOMANUAL
  105. */
  106. LOCAL STATUS wdbBdmInitHardware (void)
  107.     {
  108.     /* reset memory */
  109.     
  110.     bdmCommBuff.recvSem = 0;
  111.     bdmCommBuff.recvCount = 0;
  112.     bdmCommBuff.sendSem = 0;
  113.     bdmCommBuff.sendCount = 0;
  114.     /*
  115.      * Here you must put the IOBuff address in the first register (the first
  116.      * one for the Macraigor's ReadRegister routine and then put the CPU in
  117.      * background. The backend will restart the CPU.
  118.      */
  119. #if  (CPU == CPU32)
  120.     WRS_ASM ("move.l _pBdmCommBuff,D3");
  121.     WRS_ASM ("nop");
  122.     WRS_ASM (".word 0x4afa");
  123. #elif  (CPU == PPC860)
  124.     WRS_ASM ("addi 3, 0, bdmCommBuff@ha"); /* move IOBuff@ha to R3 */
  125.     WRS_ASM ("rlwinm 3, 3, 16, 0, 15"); /* move IOBuff@ha to R3@ha */
  126.     WRS_ASM ("addi 3, 3, bdmCommBuff@l"); /* move IOBuff@l to R3 */
  127.     WRS_ASM ("sc"); /* sc instruction */
  128. #if  FALSE
  129.     WRS_ASM ("tw 31, 0, 0"); /* trap instruction */
  130. #endif /* FALSE */
  131. #endif  /* CPU == CPU32 */
  132.     return(OK);
  133.     }
  134. /******************************************************************************
  135. *
  136. * wdbBdmPktDevInit - initialize a bdm packet device.
  137. *
  138. * RETRUNS: N/A
  139. *
  140. * NOMANUAL
  141. */
  142. STATUS wdbBdmPktDevInit
  143.     (
  144.     WDB_BDM_PKT_DEV *pPktDev, /* bdm device structure to init */
  145.     void (*stackRcv)() /* receive packet callback (udpRcv) */
  146.     )
  147.     {
  148.     /* initialize the wdbDrvIf field with driver info */
  149.     pPktDev->wdbDrvIf.mode = WDB_COMM_MODE_POLL | WDB_COMM_MODE_INT;
  150.     pPktDev->wdbDrvIf.mtu = WDB_BDM_PKT_MTU;
  151.     pPktDev->wdbDrvIf.stackRcv = stackRcv; /* udpRcv */
  152.     pPktDev->wdbDrvIf.devId = (WDB_BDM_PKT_DEV *)pPktDev;
  153.     pPktDev->wdbDrvIf.pollRtn = wdbBdmPoll;
  154.     pPktDev->wdbDrvIf.pktTxRtn = wdbBdmTx;
  155.     pPktDev->wdbDrvIf.modeSetRtn = wdbBdmModeSet;
  156.     /*
  157.      * Put your hardware initialization code here. It should initialize
  158.      * the device structure's register addresses and initialize
  159.      * the hardware.
  160.      */
  161.     if (wdbBdmInitHardware() != OK)
  162. return(ERROR);
  163.     /* put the device in a quiescent state */
  164.     wdbBdmModeSet (pPktDev, WDB_COMM_MODE_INT);
  165.     /* start the polling task if the OS is initialized */
  166.     if(taskIdCurrent)
  167. {
  168. taskSpawn ("tBdmPoll", 200, 0, 5000, (int (*)()) wdbBdmPollTask,
  169.    (int) pPktDev, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  170. }
  171.     return(OK);
  172.     }
  173. /******************************************************************************
  174. *
  175. * wdbBdmTx - transmit a packet.
  176. *
  177. * The packet is realy a chain of mbufs. We may have to just queue up
  178. * this packet is we are already transmitting.
  179. *
  180. * RETURNS: OK or ERROR
  181. *
  182. * NOMANUAL
  183. */
  184. LOCAL STATUS wdbBdmTx
  185.     (
  186.     void * pDev,
  187.     struct mbuf * pMbuf
  188.     )
  189.     {
  190.     UINT32 packetSize = 0;
  191.     /* copy transmit data to buffer */
  192.     wdbMbufDataGet (pMbuf, bdmCommBuff.sendBuffer,
  193.                     WDB_BDM_PKT_MTU, &packetSize);
  194.     /* send packet */
  195.     bdmCommBuff.sendCount = (UINT16) htons (packetSize);
  196.     bdmCommBuff.sendSem = 0xFF;
  197.     wdbBdmTargetStop ();
  198.     /* free mbuf chain */
  199.     wdbMbufChainFree (pMbuf);
  200.     return (OK);
  201.     }
  202. /******************************************************************************
  203. *
  204. * wdbBdmFree - free the input buffer
  205. *
  206. * This is the callback used to let us know the agent is done with the
  207. * input buffer we loaded it.
  208. *
  209. * RETURNS: N/A
  210. *
  211. * NOMANUAL
  212. */
  213. LOCAL void wdbBdmFree
  214.     (
  215.     void * pDev /* unused */
  216.     )
  217.     {
  218.     bdmCommBuff.recvCount = 0;
  219.     bdmCommBuff.recvSem = 0;
  220.     }
  221. /******************************************************************************
  222. *
  223. * wdbBdmModeSet - switch driver modes
  224. *
  225. * RETURNS: OK for a supported mode, else ERROR
  226. *
  227. * NOMANUAL
  228. */
  229. LOCAL STATUS wdbBdmModeSet
  230.     (
  231.     void * pDev,
  232.     uint_t newMode
  233.     )
  234.     {
  235.     WDB_BDM_PKT_DEV * pPktDev = pDev;
  236.     if (newMode == WDB_COMM_MODE_INT)
  237. pPktDev->mode = WDB_COMM_MODE_INT;
  238.     else if (newMode == WDB_COMM_MODE_POLL)
  239. pPktDev->mode = WDB_COMM_MODE_POLL;
  240.     else
  241. return (ERROR);
  242.     return (OK);
  243.     }
  244. /******************************************************************************
  245. *
  246. * wdbBdmPoll - poll for a packet
  247. *
  248. * This routine polls for a packet. If a packet has arrived it invokes
  249. * the agents callback.
  250. *
  251. * RETURNS: OK if a packet has arrived, else ERROR.
  252. *
  253. * NOMANUAL
  254. */ 
  255. LOCAL STATUS wdbBdmPoll
  256.     (
  257.     void * pDev
  258.     )
  259.     {
  260.     WDB_BDM_PKT_DEV * pPktDev = pDev;
  261.     struct mbuf * pMbuf;
  262.     UINT16 packetSize = 0;
  263.     if (bdmCommBuff.recvSem)
  264. {
  265. /*
  266.  * Fill the input buffer with the packet. Use an mbuf cluster to pass
  267.  * the packet on to the agent.
  268.  */
  269. packetSize = ntohs (bdmCommBuff.recvCount);
  270. pMbuf = wdbMbufAlloc();
  271. if ((pMbuf == NULL) || (packetSize == 0))
  272.     {
  273.     bdmCommBuff.recvSem = 0;
  274.     return (ERROR);
  275.     }
  276. wdbMbufClusterInit (pMbuf, bdmCommBuff.recvBuffer, (UINT32) packetSize,
  277.     (int (*) ())wdbBdmFree, (int) pPktDev);
  278. (*pPktDev->wdbDrvIf.stackRcv) (pMbuf);  /* invoke callback */
  279. return (OK);
  280. }
  281.     return (ERROR);
  282.     }
  283. /******************************************************************************
  284. *
  285. * wdbBdmPollTask - poll for a packet
  286. *
  287. * This routine polls for a packet. If a packet has arrived it invokes
  288. * the agents callback.
  289. *
  290. * RETURNS: OK if a packet has arrived, else ERROR.
  291. *
  292. * NOMANUAL
  293. */ 
  294. LOCAL void wdbBdmPollTask
  295.     (
  296.     void * pDev
  297.     )
  298.     {
  299.     for (;;)
  300. {
  301. taskDelay (pollDelay);
  302. wdbBdmPoll (pDev);
  303. }
  304.     }