⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 async_pci.c

📁 DSP/BIOS Driver Developer Kit 1.11 The DSP/BIOS Driver Developer Kit (DDK) provides a selection of
💻 C
字号:
/*
 *  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 main\n");  
    /* 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=%x\n", *addr);
        } 
        else {
            addr = (Uns *)req->dstAddr;
            LOG_printf(&trace, "    sbmt-r: read=%x\n", *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++;
       } 
    } 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -