async_pci.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:10k
- /*
- * Copyright 2003 by Texas Instruments Incorporated.
- * All rights reserved. Property of Texas Instruments Incorporated.
- * Restricted rights to use, duplicate or disclose this code are
- * granted through contract.
- *
- */
- /* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */
- /*
- * ======== async_pci.c ========
- *
- * PCI Driver Async Test for for Valley Tech vt1423 board
- * The test is to transfer data from dsp memory to pci memory
- * (pci write) or from pci memory to dsp memory (pci read)
- * Data values placed in the memory are based on channel number, such as
- * 0x01010101 transfered for channel one, 0x05050505 for channel 5.
- * Use 21555 Bridge Scratchpad registers (32 bytes)
- *
- * User defines the following parameters:
- *
- * -- VT1423_PCI_PRIORITY: if defined, tasks will have different priorities
- * -- CHAN_NUM: Number of channels to be opened
- * -- PCI_REQ_NUM: Number of IOPs for each channel
- * -- TRANSFER_COUNT: bytes to be transfered
- * -- PCI_ADDR_START: PCI start address
- * -- LOG_DATA: if defined, will print the memory read/write data
- * -- SLEEP_TIME: task sleep time
- */
- #include <std.h>
- #include <log.h>
- #include <sys.h>
- #include <tsk.h>
- #include <gio.h>
- #include <iom.h>
- #include <c64xx_pci.h>
- #include <csl_pci.h>
- #include <async.h>
- extern far LOG_Obj trace;
- /* debug info */
- /* #define LOG_DATA */
- /* User defined constants */
- #define VT1423_PCI_PRIORITY
- #define CHAN_NUM 8
- #define PCI_REQ_NUM 10
- #define TRANSFER_COUNT_RAW (32/CHAN_NUM)
- #define TRANSFER_COUNT (TRANSFER_COUNT_RAW - TRANSFER_COUNT_RAW % 4)
- #define PCI_ADDR_START 0xc00000a8
- #define SLEEP_TIME 2
- #define TIMEOUT 2000
- typedef struct CallbackObj {
- Int chanNum; /* trace the channel number */
- Int reqNum; /* index for trace submitted request */
- char value; /* value to write to memory, then read it back */
- Bool packetFree; /* if the packet is free to use */
- } CallbackObj;
- static Void chan_callback(Ptr arg, Int status, Ptr reqp, Uns size);
- static Void chan_tsk(Int chanNum, Int sleep);
- #ifdef LOG_DATA
- static Void logData(Int chanNum, Ptr reqp, Int status);
- #endif
- static Void setMem(int count, Ptr *memAddr, char value);
- static Void verifyData(Int chanNum, Ptr reqp, char value);
- static Ptr gio[CHAN_NUM];
- /*
- * ======== main ========
- */
- Void main()
- {
- C64XX_PCI_Attrs pciAttrs[CHAN_NUM];
- TSK_Attrs tskAttrs[CHAN_NUM];
- GIO_Attrs gioAttrs[CHAN_NUM];
- Int i;
-
- for (i = 0; i < CHAN_NUM; i++) {
- /* C64XX_PCI_Attrs init */
- /* even numbered Channel used as low priority queue channel */
- if (i % 2 == 0) {
- pciAttrs[i].queuePriority = C64XX_PCI_QUEUE_PRIORITY_LOW;
- } else {
- pciAttrs[i].queuePriority = C64XX_PCI_QUEUE_PRIORITY_HIGH;
- }
-
- /* GIO_Attrs init */
- gioAttrs[i].nPackets = PCI_REQ_NUM;
- gioAttrs[i].timeout = TIMEOUT;
- }
- /* create IOM objs */
- for (i = 0; i < CHAN_NUM; i++) {
- gio[i] = ASYNC_create("/udevPci", IOM_INOUT, NULL,
- &pciAttrs[i], &gioAttrs[i]);
- if (gio[i] == NULL) {
- LOG_printf(&trace, "ERROR!!! GIO_create NULL!");
- }
- }
-
- /* create tasks */
- for (i = 0; i < CHAN_NUM; i++) {
- tskAttrs[i] = TSK_ATTRS;
- #ifdef VT1423_PCI_PRIORITY
- tskAttrs[i].priority = 3 + i;
- #endif
- if (TSK_create((Fxn)chan_tsk, &tskAttrs[i], i, SLEEP_TIME) == NULL) {
- LOG_printf(&trace, "ERROR!!! TSK_create NULL!");
- }
- }
-
- LOG_printf(&trace, "Exit mainn");
- /* fall into DSP/BIOS idle loop */
- return;
- }
- /*
- * ======== chan_callback ========
- * Handle callback
- */
- static Void chan_callback(Ptr arg, Int status, Ptr reqp, Uns size){
- CallbackObj *pCallback = (CallbackObj *)arg;
- C64XX_PCI_Request *req = (C64XX_PCI_Request *)reqp;
- Int chanNum = pCallback->chanNum;
- #ifdef LOG_DATA
- logData(chanNum, req, status);
- #endif
- /*
- * if this callback is for ASYNC_read, then check
- * if read value = written value
- */
- if (C64XX_PCI_GETXFERMODE(req->options) == PCI_READ_PREF ||
- C64XX_PCI_GETXFERMODE(req->options) == PCI_READ_NOPREF) {
- verifyData(chanNum, req, pCallback->value);
- }
- pCallback->packetFree = TRUE;
- }
- /*
- * ======== chan_tsk ========
- */
- static Void chan_tsk(Int chanNum, Int sleep)
- {
- Uns size;
- Int status;
- C64XX_PCI_Request req[PCI_REQ_NUM];
- C64XX_PCI_Request *curReq;
- GIO_AppCallback gioCallback[PCI_REQ_NUM];
- CallbackObj callback[PCI_REQ_NUM];
- Ptr dspAddr;
- char value;
- Int submitReqIndex;
- Int j;
- value = (char)chanNum;
-
- /* allocate dsp memory for each channel */
- /* dsp address need to be PCI word address, so memory alignment defined 4 */
- dspAddr = MEM_alloc(0, TRANSFER_COUNT, 4);
- if (dspAddr == NULL) {
- LOG_printf(&trace, "dspAddr alloc NULL");
- SYS_abort("dspAddr NULL");
- }
-
- /* C64XX_PCI_Request init. First set write req, then set read request */
- for (j = 0; j < PCI_REQ_NUM; j = j + 2) {
- /* pci write : dsp->pci */
- req[j].srcAddr = (char *)dspAddr;
- req[j].dstAddr = (char *)PCI_ADDR_START + TRANSFER_COUNT * chanNum;
- req[j].byteCnt = TRANSFER_COUNT;
- req[j].options = 0;
- req[j].options =
- C64XX_PCI_SETXFERMODE(req[j].options, PCI_WRITE);
-
- /* pci read : pci->dsp */
- req[j + 1].srcAddr = (char *)PCI_ADDR_START + TRANSFER_COUNT * chanNum;
- req[j + 1].dstAddr = (char *)dspAddr;
- req[j + 1].byteCnt = TRANSFER_COUNT;
- req[j + 1].options = 0;
- req[j + 1].options =
- C64XX_PCI_SETXFERMODE(req[j + 1].options, PCI_READ_NOPREF);
- }
- for (j = 0; j < PCI_REQ_NUM; j++) {
- callback[j].chanNum = chanNum;
- callback[j].reqNum = j;
- callback[j].value = value;
- callback[j].packetFree = TRUE;
- gioCallback[j].fxn = (GIO_TappCallback)chan_callback;
- }
- submitReqIndex = 0;
- for (;;) {
- if (!callback[submitReqIndex].packetFree) {
- LOG_printf(&trace, "ERR!!! chan[%d] request[%d] not free",
- chanNum, submitReqIndex);
- goto SLEEP;
- }
- else {
- callback[submitReqIndex].packetFree = FALSE;
- }
- gioCallback[submitReqIndex].arg = (Ptr)(&callback[submitReqIndex]);
- curReq = (C64XX_PCI_Request*)(&req[submitReqIndex]);
-
- if (C64XX_PCI_GETXFERMODE(curReq->options) == PCI_WRITE ) {
- /*
- * set dsp memory value as chanNum chanNum ...
- * (for example: 0x0101.. for Chan1)
- */
- setMem(TRANSFER_COUNT, curReq->srcAddr, value);
- /* pci write : dsp->pci. Write the value to pci memory */
- status = ASYNC_write(gio[chanNum], curReq, &size,
- &gioCallback[submitReqIndex]);
- if (status < 0) {
- LOG_printf(&trace, "ERR - in ASYNC_write status
- c[%d] = %d", chanNum, status);
- }
- } else {
- /* first set dsp mem value to default 0x99 */
- setMem(TRANSFER_COUNT, curReq->dstAddr, 0x99);
-
- /* pci read : pci->dsp. Readback pci memory to dsp memory */
- status = ASYNC_read(gio[chanNum], curReq, &size,
- &gioCallback[submitReqIndex]);
- }
- if (status < 0) {
- LOG_printf(&trace, "ERR - in ASYNC_read status c[%d] = %d",
- chanNum, status);
- }
- submitReqIndex++;
- if (submitReqIndex == PCI_REQ_NUM) {
- submitReqIndex = 0;
- }
- SLEEP: TSK_sleep(sleep);
- }
- }
- /*
- * ======== logData ========
- * print out the read/write memory
- * Note: only display the first 4 bytes (Uns)
- */
- #ifdef LOG_DATA
- static Void logData(Int chanNum, Ptr reqp, Int status)
- {
- C64XX_PCI_Request *req;
- Uns *addr;
-
- req = (C64XX_PCI_Request*)reqp;
-
- /* print out info */
- if (req != NULL) {
- LOG_printf(&trace, "chan[%d], status=%x", chanNum, status);
-
- if (C64XX_PCI_GETXFERMODE(req->options) == PCI_WRITE ) {
- addr = (Uns *)req->srcAddr;
- LOG_printf(&trace, " sbmt-w: written=%xn", *addr);
- }
- else {
- addr = (Uns *)req->dstAddr;
- LOG_printf(&trace, " sbmt-r: read=%xn", *addr);
- }
- }
- else {
- LOG_printf(&trace, "request NULL");
- }
- }
- #endif
- /*
- * ======== setMem ========
- * Set memory value
- */
- static Void setMem(int count, Ptr *memAddr, char value)
- {
- char *tempMem = (char *)memAddr;
- int i;
-
- for (i = 0; i < count; i++) {
- *tempMem = value;
- tempMem++;
- }
- }
- /*
- * ======== verifyData ========
- * Verify read back data
- */
- static Void verifyData(Int chanNum, Ptr reqp, char value)
- {
- C64XX_PCI_Request *req;
- char *addr;
- Int i;
-
- req = (C64XX_PCI_Request*)reqp;
-
- if (req != NULL) {
- addr = (char *)req->dstAddr;
- for (i = 0; i < req->byteCnt; i++) {
- if (*addr != value) {
- LOG_printf(&trace, "ERROR!!! in verify chan[%d], addr = %x",
- chanNum, addr);
- }
- addr++;
- }
- }
- }