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

📄 dm642_pci.c

📁 dsp dm642 flash烧录入
💻 C
📖 第 1 页 / 共 2 页
字号:
        PCI_intDisable(PCI_EVT_HOSTSW);

        IRQ_disable(IRQ_EVT_DSPINT);
    }
    HWI_restore(imask);

    return (IOM_COMPLETED);
}

/*
 *  ======== mdSubmitChan ========
 *  return submit status
 */
static Int mdSubmitChan(Ptr chanp, IOM_Packet *pPacket)
{
    ChanHandle          chan = (ChanHandle)chanp;
    IOM_Packet*         packet = pPacket;
    Uns                 imask;
    C64XX_PCI_Request  *req;
    C64XX_PCI_Request  *curReq;

    req = (C64XX_PCI_Request *)packet->addr;
    req->reserved = chan;

    /* IOM_READ or IOM_WRITE command handle in the same way */
    if (packet->cmd == IOM_READ || packet->cmd == IOM_WRITE) {

        imask = HWI_disable();
        QUE_enqueue(chan->queue, packet);

        if (device.curPacket == NULL) {
#ifndef TEST_RESET
            processQueue();
#endif
        }
        HWI_restore(imask);
        return (IOM_PENDING);
    }

    if (packet->cmd == IOM_FLUSH || packet->cmd == IOM_ABORT) {

        imask = HWI_disable();
        chan->flushAbortIop = packet;

        /* check the channel of pending packet */
        if (device.curPacket != NULL) {
                curReq = (C64XX_PCI_Request *)device.curPacket->addr;

            /* The pending packet is this channel. Let isr handles it */
            if ((ChanHandle)curReq->reserved == chan) {
                HWI_restore(imask);
                return (IOM_PENDING);
            }
        }

        /* the pending packet is not FLUSH/ABORT channel */
        removePackets(chan, packet->cmd);

        /* FLUSH/ABORT done */
        if (chan->writeCount == 0) {
            chan->flushAbortIop = NULL;
            HWI_restore(imask);
            return (IOM_COMPLETED);
        }

        HWI_restore(imask);
        return (IOM_PENDING);
    }
    return (IOM_EBADIO);
}

/*
 *  ======== mdUnBindDev ========
 *  return status
 */

static Int mdUnBindDev(Ptr devp)
{
    /* empty for now */
    return (IOM_COMPLETED);
}

/*
 *  ======== C64XX_PCI_init ========
 */
Void C64XX_PCI_init(Void)
{
    /* empty for now */
}

extern far SEM_Obj PciDmaDataAvail;

/*
 *  ======== isr ========
 *  interrupt service routine is runtime pluged in
 */
static Void isr(Void)
{
    ChanHandle          chan;
    IOM_Packet          *oldPacket;
    C64XX_PCI_Request   *oldReq;
    Int                 status = IOM_EBADIO;

    if (PCI_FGET(PCIIS, MASTEROK)) {
        /* pci master transfer complete */
        PCI_FSET(PCIIS, MASTEROK, 1);
        status = IOM_COMPLETED;

    }
    else if (PCI_FGET(PCIIS, PCIMASTER)) {
        /* pci master abort */
        PCI_FSET(PCIIS, PCIMASTER, 1);

    }
    else if (PCI_FGET(PCIIS, PCITARGET)) {
        /* pci target abort */
        PCI_FSET(PCIIS, PCITARGET, 1);

    }
    //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    // VTI change
    //    TO BE USED ONLY AS AN EXAMPLE/REFERENCE
    //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    /*
     * VTI NOTE: Modifications done to this file are for example and referenece purposes ONLY.
     *           Such modifications have NOT been fully tested.  VTI makes NO guarantee as to their
     *           correctness and validity.
     */
    else if (PCI_FGET(PCIIS, HOSTSW)) {
        /* pci host software generated int */
        PCI_RSET(PCIIS, (PCI_PCIIS_HOSTSW_CLR << _PCI_PCIIS_HOSTSW_SHIFT));
        //PCI_FSET(PCIIS, HOSTSW, 1);
        SEM_ipost(&PciDmaDataAvail);
        return;
    }
    else {
        /* not registered interrupt, clear intr here */
        PCI_RSET(PCIIS, 0x00000FFF);
        /* error handling TBD */
        return;
    }

    if (device.curPacket != NULL) {
        oldPacket = device.curPacket;
        oldReq = (C64XX_PCI_Request *)oldPacket->addr;
        chan = (ChanHandle)oldReq->reserved;

        device.curPacket = NULL;

        if (chan->flushAbortIop == NULL) {
            /* normal. process next request in the queues */
            processQueue();

            /* callback */
            CALLBACK(chan,oldPacket,status);
            return;
        }

        /* flush or abort cmd */
        /* first do callback */
        CALLBACK(chan,oldPacket,status);

        if (chan->writeCount) {
           chan->writeCount--;
        }
        else {
           removePackets(chan, chan->flushAbortIop->cmd);
        }

        /* process next request in the queues */
        processQueue();

        /* if all write IOPs are done, call the callback for the FLUSH IOP */
        if (chan->writeCount == 0) {
           CALLBACK(chan,chan->flushAbortIop,IOM_COMPLETED);
           chan->flushAbortIop = NULL;
        }
        return;
    }

    /* process next request in the queues */
    processQueue();
}

/*
 *  ======== pciErrorIsr ========
 *  interrupt service routine is runtime pluged in for asynchronous error TBD
 */
#ifdef PCI_ERROR_ISR_IMPL
static Void pciErrorIsr(Void)
{
    /* How to check PCI status register to identify the error source --
    parity/system: TBD (on C6416, not accessable) use 'event' here to
    represent the status register related content */

    Bool report = FALSE;
    Uns error = 0;
    C64XX_PCI_Request *req;
    IOM_Packet *packet;

    if (device.errCallback == NULL) {
        return;
    }
    if ((event == C64XX_PCI_EVT_PARITY_ERR) &&
            (device.evtMask & C64XX_PCI_EVT_PARITY_ERR)) {
        error = error | C64XX_PCI_EVT_PARITY_ERR;
        report = TRUE;
    }
    else if ((event == C64XX_PCI_EVT_SYSTEM_ERR) &&
            (device.evtMask & C64XX_PCI_EVT_SYSTEM_ERR)) {
        error = error | C64XX_PCI_EVT_SYSTEM_ERR;
        report = TRUE;
    }

    if (!report) {
        return;
    }

    if (device.curPacket != NULL) {
        packet = device.curPacket;
        req = (C64XX_PCI_Request *)packet->addr;
        device.errInfo->inprogressDstAddr = req->dstAddr;
        device.errInfo->inprogressSrcAddr = req->srcAddr;
        device.errInfo->statusReg = PCI_STATUS_REGISTER;
    }
    else {
        device.errInfo->inprogressDstAddr = NULL;
        device.errInfo->inprogressSrcAddr = NULL;
        device.errInfo->statusReg = PCI_STATUS_REGISTER;
    }

    (device.errCallback)(error, (Ptr)device.errorInfo);

}
#endif


/*
 *  ======== doTransfer ========
 */
static Void doTransfer(C64XX_PCI_Request *request)
{
    C64XX_PCI_Request   *req = request;
    PCI_ConfigXfr       config;
    Uns                 xfrMode;

    xfrMode = C64XX_PCI_GETXFERMODE(request->options);

    if (xfrMode == PCI_WRITE) {
        config.dspma = (Uns)req->srcAddr;
        config.pcima = (Uns)req->dstAddr;
        config.pcimc = GET_BYTE_COUNT(req->byteCnt);

    }
    else if (xfrMode ==  PCI_READ_PREF || xfrMode ==  PCI_READ_NOPREF) {
        config.dspma = (Uns)req->dstAddr;
        config.pcima = (Uns)req->srcAddr;
        config.pcimc = GET_BYTE_COUNT(req->byteCnt);
    }

    PCI_xfrConfig(&config);
    PCI_xfrStart(xfrMode);
}


/*
 *  ======== processQueue ========
 */
static Void processQueue()
{
    QUE_Handle          que;
    C64XX_PCI_Request   *req;

    que = &device.highPrioQue;
    /* process next packet in queue */
    if (QUE_empty(que)) {
        que = &device.lowPrioQue;
        if (QUE_empty(que)) {
            return;
        }
    }
    device.curPacket = QUE_dequeue(que);
    req = (C64XX_PCI_Request *)device.curPacket->addr;
    doTransfer(req);
}

/*
 *  ======== removePackets ========
 */
static Void removePackets(Ptr chanp, Int cmd)
{
    ChanHandle          chan = (ChanHandle)chanp;
    QUE_Elem            *next;
    QUE_Elem            *current;
    C64XX_PCI_Request  *curReq;
    Int                 status;

    if (cmd != IOM_FLUSH && cmd != IOM_ABORT) {
        return;
    }

    current = QUE_head(chan->queue);
    curReq = (C64XX_PCI_Request *)((IOM_Packet *)current)->addr;

    while (chan->queue != current) {
        next = QUE_next(current);

        /* check the channel of the each IOM_Packet in the queue */
        /* find the match. The packet and remove channels are identical */
        if ((ChanHandle)curReq->reserved == chan) {
            /* for write flush wait for complete */
            if ( cmd == IOM_FLUSH &&
                    ((IOM_Packet *)current)->cmd == IOM_WRITE ) {
                chan->writeCount++;
            } else {
                /* for read flush or abort, do flush */
                if (cmd == IOM_FLUSH) {
                    status = IOM_FLUSHED;
                }
                else {
                    status = IOM_ABORTED;
                }
                QUE_remove(current);
                CALLBACK(chan, (IOM_Packet *)current, status);
            }
        }

        current = next;
        curReq = (C64XX_PCI_Request*)((IOM_Packet *)current)->addr;
    } /* end while */
}

/*
 *  ======== resetChannel ========
 */
static Void resetChannel(Ptr chanp)
{
    ChanHandle          chan = (ChanHandle)chanp;
    C64XX_PCI_Request  *curReq;
    Uns                 imask;

    imask = HWI_disable();
    /* assume reset async ? */
    if (device.curPacket != NULL) {
        curReq = (C64XX_PCI_Request *)((IOM_Packet *)device.curPacket)->addr;
        if ((ChanHandle)curReq->reserved == chan) {
            CALLBACK((ChanHandle)curReq->reserved,
                    (IOM_Packet *)device.curPacket, IOM_ABORTED);
            device.curPacket = NULL;
        }
    }

    removePackets(chanp, IOM_ABORT);
    HWI_restore(imask);
}

/*
 *  ======== resetDevice ========
 */
static Void resetDevice()
{
    QUE_Elem            *next;
    QUE_Elem            *current;
    QUE_Handle          queue;
    C64XX_PCI_Request  *curReq;
    Int                 i;
    Uns                 imask;

    imask = HWI_disable();
    /* assume reset async ? */
    if (device.curPacket != NULL) {
        curReq = (C64XX_PCI_Request *)((IOM_Packet *)device.curPacket)->addr;
         CALLBACK((ChanHandle)curReq->reserved,
                    (IOM_Packet *)device.curPacket, IOM_ABORTED);
        device.curPacket = NULL;
    }

    for (i = 0; i < 2; i++) {
        if (i == 0 ) {
            queue = &device.highPrioQue;
        }
        else {
            queue = &device.lowPrioQue;
        }
        /* remove all the elements in the high/low priority queue */
        current = QUE_head(queue);
        curReq = (C64XX_PCI_Request *)((IOM_Packet *)current)->addr;

        while (queue != current) {
            next = QUE_next(current);

            QUE_remove(current);
            CALLBACK((ChanHandle)curReq->reserved,
                    (IOM_Packet *)current, IOM_ABORTED);

            current = next;
            curReq = (C64XX_PCI_Request*)((IOM_Packet *)current)->addr;
        } /* end while */
    } /* end for */

    HWI_restore(imask);
}

⌨️ 快捷键说明

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