📄 async_pci.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 + -