async_pci.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:10k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /* "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)" */
  9. /*
  10.  *  ======== async_pci.c ========
  11.  * 
  12.  *  PCI Driver Async Test for for Valley Tech vt1423 board
  13.  *  The test is to transfer data from dsp memory to pci memory 
  14.  *  (pci write) or from pci memory to dsp memory (pci read)
  15.  *  Data values placed in the memory are based on channel number, such as 
  16.  *  0x01010101 transfered for channel one, 0x05050505 for channel 5.
  17.  *  Use 21555 Bridge Scratchpad registers (32 bytes)  
  18.  *  
  19.  *  User defines the following parameters:
  20.  *  
  21.  *  -- VT1423_PCI_PRIORITY: if defined, tasks will have different priorities
  22.  *  -- CHAN_NUM: Number of channels to be opened
  23.  *  -- PCI_REQ_NUM: Number of IOPs for each channel
  24.  *  -- TRANSFER_COUNT: bytes to be transfered
  25.  *  -- PCI_ADDR_START: PCI start address 
  26.  *  -- LOG_DATA: if defined, will print the memory read/write data
  27.  *  -- SLEEP_TIME: task sleep time
  28.  */
  29. #include <std.h>
  30. #include <log.h>
  31. #include <sys.h>
  32. #include <tsk.h>
  33. #include <gio.h>
  34. #include <iom.h>
  35. #include <c64xx_pci.h>   
  36. #include <csl_pci.h>
  37. #include <async.h>
  38. extern far LOG_Obj trace;
  39. /* debug info */
  40. /* #define LOG_DATA */
  41. /* User defined constants */
  42. #define VT1423_PCI_PRIORITY
  43. #define CHAN_NUM                8
  44. #define PCI_REQ_NUM             10      
  45. #define TRANSFER_COUNT_RAW      (32/CHAN_NUM)
  46. #define TRANSFER_COUNT          (TRANSFER_COUNT_RAW - TRANSFER_COUNT_RAW % 4)  
  47. #define PCI_ADDR_START          0xc00000a8      
  48. #define SLEEP_TIME              2       
  49. #define TIMEOUT         2000
  50. typedef struct CallbackObj {
  51.     Int chanNum; /* trace the channel number */
  52.     Int reqNum; /* index for trace submitted request */
  53.     char        value; /* value to write to memory, then read it back */  
  54.     Bool packetFree; /* if the packet is free to use */ 
  55. } CallbackObj;
  56. static Void chan_callback(Ptr arg, Int status, Ptr reqp, Uns size);
  57. static Void chan_tsk(Int chanNum, Int sleep);
  58. #ifdef LOG_DATA
  59. static Void logData(Int chanNum, Ptr reqp, Int status);
  60. #endif
  61. static Void setMem(int count, Ptr *memAddr, char value);
  62. static Void verifyData(Int chanNum, Ptr reqp, char value);
  63. static Ptr gio[CHAN_NUM];
  64. /*
  65.  *  ======== main ========
  66.  */
  67. Void main()
  68. {   
  69.     C64XX_PCI_Attrs pciAttrs[CHAN_NUM];
  70.     TSK_Attrs tskAttrs[CHAN_NUM];
  71.     GIO_Attrs gioAttrs[CHAN_NUM];
  72.     Int i;
  73.     
  74.     for (i = 0; i < CHAN_NUM; i++) {
  75.         /* C64XX_PCI_Attrs init */
  76.         /* even numbered Channel used as low priority queue channel */
  77.         if (i % 2 == 0) {  
  78.             pciAttrs[i].queuePriority = C64XX_PCI_QUEUE_PRIORITY_LOW; 
  79.         } else {
  80.             pciAttrs[i].queuePriority = C64XX_PCI_QUEUE_PRIORITY_HIGH;
  81.         }    
  82.         
  83.         /* GIO_Attrs init */
  84.         gioAttrs[i].nPackets = PCI_REQ_NUM;
  85.         gioAttrs[i].timeout = TIMEOUT; 
  86.     }
  87.     /* create IOM objs */
  88.     for (i = 0; i < CHAN_NUM; i++) {
  89.         gio[i] = ASYNC_create("/udevPci", IOM_INOUT, NULL, 
  90.                 &pciAttrs[i], &gioAttrs[i]);
  91.         if (gio[i] == NULL) {
  92.             LOG_printf(&trace, "ERROR!!! GIO_create NULL!");
  93.         }
  94.     }
  95.     
  96.     /* create tasks */
  97.     for (i = 0; i < CHAN_NUM; i++) {
  98.         tskAttrs[i] = TSK_ATTRS;
  99. #ifdef VT1423_PCI_PRIORITY
  100.         tskAttrs[i].priority = 3 + i; 
  101. #endif
  102.         if (TSK_create((Fxn)chan_tsk, &tskAttrs[i], i, SLEEP_TIME) == NULL) {
  103.             LOG_printf(&trace, "ERROR!!! TSK_create NULL!");
  104.         }
  105.     }     
  106.     
  107.     LOG_printf(&trace, "Exit mainn");  
  108.     /* fall into DSP/BIOS idle loop */
  109.     return;
  110. }
  111. /*
  112.  *  ======== chan_callback ========
  113.  *  Handle callback
  114.  */
  115. static Void chan_callback(Ptr arg, Int status, Ptr reqp, Uns size){
  116.     CallbackObj *pCallback = (CallbackObj *)arg;
  117.     C64XX_PCI_Request *req = (C64XX_PCI_Request *)reqp;
  118.     Int chanNum = pCallback->chanNum;
  119. #ifdef LOG_DATA
  120.     logData(chanNum, req, status);
  121. #endif
  122.     /*
  123.      * if this callback is for ASYNC_read, then check 
  124.      * if read value = written value 
  125.      */
  126.     if (C64XX_PCI_GETXFERMODE(req->options) == PCI_READ_PREF || 
  127.         C64XX_PCI_GETXFERMODE(req->options) == PCI_READ_NOPREF) {
  128.                 verifyData(chanNum, req, pCallback->value);  
  129.     }
  130.     pCallback->packetFree = TRUE;
  131. }
  132. /*
  133.  *  ======== chan_tsk ========
  134.  */
  135. static Void chan_tsk(Int chanNum, Int sleep)
  136. {
  137.     Uns                 size;
  138.     Int                 status;
  139.     C64XX_PCI_Request   req[PCI_REQ_NUM];
  140.     C64XX_PCI_Request   *curReq;
  141.     GIO_AppCallback     gioCallback[PCI_REQ_NUM]; 
  142.     CallbackObj         callback[PCI_REQ_NUM];
  143.     Ptr                 dspAddr;
  144.     char                value; 
  145.     Int                 submitReqIndex;
  146.     Int                 j;
  147.     value = (char)chanNum;
  148.  
  149.     /* allocate dsp memory for each channel */
  150.     /* dsp address need to be PCI word address, so memory alignment defined 4 */
  151.     dspAddr = MEM_alloc(0, TRANSFER_COUNT, 4);
  152.     if (dspAddr == NULL) {
  153.         LOG_printf(&trace, "dspAddr alloc NULL");
  154.         SYS_abort("dspAddr NULL");
  155.     }
  156.     
  157.     /* C64XX_PCI_Request init. First set write req, then set read request */
  158.     for (j = 0; j < PCI_REQ_NUM; j = j + 2) {
  159.         /* pci write : dsp->pci */        
  160.         req[j].srcAddr = (char *)dspAddr;
  161.         req[j].dstAddr = (char *)PCI_ADDR_START + TRANSFER_COUNT * chanNum;
  162.         req[j].byteCnt = TRANSFER_COUNT;    
  163.         req[j].options = 0;
  164.         req[j].options = 
  165.                 C64XX_PCI_SETXFERMODE(req[j].options, PCI_WRITE);
  166.            
  167.         /* pci read : pci->dsp */
  168.         req[j + 1].srcAddr = (char *)PCI_ADDR_START + TRANSFER_COUNT * chanNum;
  169.         req[j + 1].dstAddr = (char *)dspAddr;       
  170.         req[j + 1].byteCnt = TRANSFER_COUNT;     
  171.         req[j + 1].options = 0;
  172.         req[j + 1].options = 
  173.                 C64XX_PCI_SETXFERMODE(req[j + 1].options, PCI_READ_NOPREF);
  174.     }
  175.     for (j = 0; j < PCI_REQ_NUM; j++) {
  176.         callback[j].chanNum = chanNum;
  177.         callback[j].reqNum = j;
  178.         callback[j].value = value;
  179.         callback[j].packetFree = TRUE;
  180.         gioCallback[j].fxn = (GIO_TappCallback)chan_callback;
  181.     }
  182.     submitReqIndex = 0;
  183.     for (;;) {
  184.         if (!callback[submitReqIndex].packetFree) {
  185.             LOG_printf(&trace, "ERR!!! chan[%d] request[%d] not free", 
  186.                    chanNum, submitReqIndex);
  187.                 goto SLEEP;
  188.         }
  189.         else {
  190.             callback[submitReqIndex].packetFree = FALSE;
  191.         }
  192.         gioCallback[submitReqIndex].arg = (Ptr)(&callback[submitReqIndex]);
  193.         curReq = (C64XX_PCI_Request*)(&req[submitReqIndex]);
  194.  
  195.         if (C64XX_PCI_GETXFERMODE(curReq->options) == PCI_WRITE ) {
  196.             /*  
  197.              * set dsp memory value as chanNum chanNum ...
  198.              * (for example: 0x0101.. for Chan1) 
  199.              */ 
  200.             setMem(TRANSFER_COUNT, curReq->srcAddr, value);
  201.             /* pci write : dsp->pci. Write the value to pci memory */
  202.             status = ASYNC_write(gio[chanNum], curReq, &size, 
  203.                     &gioCallback[submitReqIndex]);
  204.             if (status < 0) {
  205.                 LOG_printf(&trace, "ERR - in ASYNC_write status 
  206.                         c[%d] = %d", chanNum, status);
  207.             }
  208.         } else {
  209.             /* first set dsp mem value to default 0x99 */
  210.             setMem(TRANSFER_COUNT, curReq->dstAddr, 0x99);
  211.         
  212.             /* pci read : pci->dsp. Readback pci memory to dsp memory */
  213.             status = ASYNC_read(gio[chanNum], curReq, &size, 
  214.                     &gioCallback[submitReqIndex]);
  215.         }
  216.         if (status < 0) {
  217.             LOG_printf(&trace, "ERR - in ASYNC_read status c[%d] = %d", 
  218.                     chanNum, status);
  219.         }
  220.         submitReqIndex++;
  221.         if (submitReqIndex == PCI_REQ_NUM) {
  222.             submitReqIndex = 0;
  223.         } 
  224. SLEEP:  TSK_sleep(sleep);
  225.     }  
  226. }
  227. /*
  228.  *  ======== logData ========
  229.  *  print out the read/write memory
  230.  *  Note: only display the first 4 bytes (Uns)
  231.  */
  232. #ifdef LOG_DATA
  233. static Void logData(Int chanNum, Ptr reqp, Int status)
  234. {
  235.     C64XX_PCI_Request *req;
  236.     Uns  *addr; 
  237.     
  238.     req = (C64XX_PCI_Request*)reqp;
  239.     
  240.     /* print out info */
  241.     if (req != NULL) {
  242.         LOG_printf(&trace, "chan[%d], status=%x", chanNum, status);
  243.         
  244.         if (C64XX_PCI_GETXFERMODE(req->options) == PCI_WRITE ) {
  245.             addr = (Uns *)req->srcAddr;
  246.             LOG_printf(&trace, "    sbmt-w: written=%xn", *addr);
  247.         } 
  248.         else {
  249.             addr = (Uns *)req->dstAddr;
  250.             LOG_printf(&trace, "    sbmt-r: read=%xn", *addr);  
  251.         }
  252.     } 
  253.     else {
  254.         LOG_printf(&trace, "request NULL");    
  255.     } 
  256. }
  257. #endif
  258. /*
  259.  *  ======== setMem ========
  260.  *  Set memory value
  261.  */
  262. static Void setMem(int count, Ptr *memAddr, char value)
  263. {
  264.     char *tempMem = (char *)memAddr;
  265.     int i;
  266.     
  267.     for (i = 0; i < count; i++) {
  268.         *tempMem = value;
  269.         tempMem++;
  270.     }   
  271. }
  272. /*
  273.  *  ======== verifyData ========
  274.  *  Verify read back data 
  275.  */
  276. static Void verifyData(Int chanNum, Ptr reqp, char value)
  277. {
  278.     C64XX_PCI_Request *req;
  279.     char  *addr; 
  280.     Int i;
  281.     
  282.     req = (C64XX_PCI_Request*)reqp;
  283.     
  284.     if (req != NULL) {
  285.        addr = (char *)req->dstAddr;
  286.        for (i = 0; i < req->byteCnt; i++) {
  287.            if (*addr != value) {
  288.                LOG_printf(&trace, "ERROR!!! in verify chan[%d], addr = %x", 
  289.                        chanNum, addr); 
  290.            }
  291.            addr++;
  292.        } 
  293.     } 
  294. }