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

📄 ep931xide.cpp

📁 EP9315开发板的Wince6.0的BSP包文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if(m_hThreadWaitEvent)
    {
        CloseHandle(m_hThreadWaitEvent);
        m_hThreadWaitEvent = 0;
    }

    //
    // Close the IDE and the DMA events handles.
    //
    if(m_hDmaIntEvent)
    {
        InterruptDisable(SYSINTR_DMA_M2M0);
        CloseHandle(m_hDmaIntEvent);
        m_hDmaIntEvent = 0;
    }

    if(m_hIdeIntEvent)
    {
        InterruptDisable(SYSINTR_IDE);
        CloseHandle(m_hIdeIntEvent);
        m_hIdeIntEvent = 0;
    }

    //
    // Close the handles for the Ist Events.
    //
    if(m_hIstEvent[DMA_EVENT])
    {
        CloseHandle(m_hIstEvent[DMA_EVENT]);
        m_hIstEvent[DMA_EVENT] = 0;
    }

    if(m_hIstEvent[IDE_EVENT])
    {
        CloseHandle(m_hIstEvent[IDE_EVENT]);
        m_hIstEvent[IDE_EVENT] = 0;
    }


    DeleteCriticalSection( &m_CriticalSection);
}

//****************************************************************************
// CEP931xPort::SetupDMAInit
//****************************************************************************
// Sets up the dma controller and prepares the DMA buffers from INIT.
// 
//
BOOL CEP931xPort::SetupDMAInit ()
{
    
    return TRUE;
}

//****************************************************************************
// CEP931xPort::SetupDMA
//****************************************************************************
// Sets up the dma controller and prepares the DMA buffers.
// 
//
BOOL CEP931xPort::SetupDMA
( 
    PSG_BUF pSgBuf, 
    DWORD   dwSgCount, 
    BOOL    fRead,
    ULONG   ulCurrentMode
) 
{
    BOOL    fLockRet;
    ULONG   ulDmaCount;
    ULONG   ulIDESource, ulIDEDest;
    ULONG   ulBuffer;
    LPBYTE  pBuffer;
    BOOL    fPagesLocked;
    DWORD   PFNs[16];
    ULONG   ulPage, ulNumPages;
    ULONG   ulPageSize = UserKInfo[KINX_PAGESIZE];  
    DWORD   dwAlignMask = 3; 
                           
    volatile ULONG ulDumbCntrlRead;
    
    DEBUGMSG
    ( 
        ZONE_DMA, 
        (
            TEXT("ATAPI:SetupDMA Request = %s SgCount=%ld\r\n"), 
            fRead ? TEXT("Read") : TEXT("Write"), 
            dwSgCount
        )
    );

    //
    // Stop any DMA that is occuring.
    //
    m_pulDmaBase[M2M_CTRL>>2] = 0;

    //* * * Read back the control register to allow hardware state
    //* * * machines to transition.
    ulDumbCntrlRead = m_pulDmaBase[M2M_CTRL>>2];

    //
    // Lets save off the DMA information.
    //
    m_pDMASgBuf         = pSgBuf;
    m_dwDMASgCount      = dwSgCount;
    m_fDMARead          = fRead;
    m_fAligned          = TRUE; 
    m_ulCurrentMode     = ulCurrentMode;

    //
    // Check if either the buffer or the buffer length is unaligned.  If the buffers are not 
    //
    if(dwSgCount ==1 && !((ULONG)pSgBuf[0].sb_buf & dwAlignMask) && !(pSgBuf[0].sb_len & dwAlignMask))
    {
        //
        // Map the pointer to the process so that we have a valid pointer in our process.
        //
	      m_pucDmaBuffer = pSgBuf[0].sb_buf;//(LPBYTE)MapCallerPtr(pSgBuf[0].sb_buf,  pSgBuf[0].sb_len);
//        m_pucDmaBuffer = (LPBYTE)MapPtrToProcess(pSgBuf[0].sb_buf, GetCallerProcess());

        //
        // Lock the pages for reading or writing.
        //
        fPagesLocked = LockPages
        ( 
            m_pucDmaBuffer, 
            pSgBuf[0].sb_len, 
            PFNs, 
            fRead ? LOCKFLAG_WRITE : LOCKFLAG_READ
        );
            

        //
        // If the function succeds, Check to make sure that the pages are physically contiguous.
        // If they are not then do the unaligned buffer case.
        //
        if(fPagesLocked)
        {
            ulNumPages =1 + ((ULONG(m_pucDmaBuffer) + pSgBuf[0].sb_len - 1) >> m_ulPageShift) - 
                             ( ULONG(m_pucDmaBuffer) >> m_ulPageShift);

            for(ulPage = 0; ulPage< (ulNumPages - 1); ulPage++)
            {
                if(PFNs[ulPage] !=PFNs[ulPage + 1])
                {
                    m_fAligned = FALSE;    
                    break;
                }
            }

            //
            // If it is aligned then calculate the current physical address.
            //
            if(m_fAligned )
            {
                //* * * UserKInfo[KINX_PFN_SHIFT]. 

                m_ulDmaPhysBuff = PFNs[0] + ((ULONG)m_pucDmaBuffer & (ulPageSize -1));
                m_ulDmaCount    = pSgBuf[0].sb_len;
            }
            else
            {   
                //
                // Unlock the pages and free the Mapped pointer.
                //
                fLockRet = UnlockPages
                ( 
                    m_pucDmaBuffer,
                    pSgBuf[0].sb_len
                );
                ASSERT(fLockRet);
            }
        }
    }
    else
    {
        m_fAligned = FALSE;    
    }

    //
    // If the pSgBuf are unaligned copy the entire buffer to our buffer.
    //
    if(!m_fAligned )
    {
        DEBUGMSG( ZONE_DMA, (TEXT("ATAPI:SetupDMA Unaligned copy in SetupDMA.\r\n")));
        ulDmaCount  = 0;
        for (ulBuffer = 0; ulBuffer < dwSgCount; ulBuffer++) 
        {
            if(!fRead)
            {
                if (pSgBuf[ulBuffer].sb_len >0x8000 || pSgBuf[ulBuffer].sb_len <=0 || pBuffer == NULL || m_pucStaticBuffer == NULL)
                {
                    DEBUGMSG
                    ( 
                        ZONE_DMA, 
                        (
                            TEXT("ATAPI:SetupDMA pSgBuf[ulBuffer].sb_len was %ld * * *\r\n"),
                            pSgBuf[ulBuffer].sb_len
                        )
                    );
                }

				pBuffer = pSgBuf[ulBuffer].sb_buf;//(LPBYTE)MapCallerPtr(pSgBuf[ulBuffer].sb_buf,  pSgBuf[ulBuffer].sb_len);
//               pBuffer = (LPBYTE)MapPtrToProcess(pSgBuf[ulBuffer].sb_buf, GetCallerProcess());
                memcpy(m_pucStaticBuffer + ulDmaCount, pBuffer, pSgBuf[ulBuffer].sb_len);
            }
            ulDmaCount+= pSgBuf[ulBuffer].sb_len;
        }
        m_ulDmaCount    = ulDmaCount;
        m_pucDmaBuffer  = m_pucStaticBuffer;
        m_ulDmaPhysBuff = m_ulStaticPhysBuff;
    }


    //
    // Setup DMA controller.  
    // Check to make sure that this bit change cannot occur in one write.
    //
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_DONEINTEN;
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_BWC_FULLTRANS; 
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_PW_WORD;
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_TM_SOFTINIT; 
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_ETDP_AHIGH_OUTPUT; 
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_DREQP_HIGHLEVEL;
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_RSS_INTIDE; 
    // m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_NO_HDSK;
    // * * * CAMSDB - Test for proper DMA channel setup. (START)
    // DumbCntrlRead = m_pulDmaBase[M2M_CTRL>>2]; //* * * According to SPEC>
    // * * * CAMSDB - Test for proper DMA channel setup. (END)
    m_ulDmaCtrlReg  = M2M_CTRL_DONEINTEN         |
                      M2M_CTRL_BWC_FULLTRANS     |
                      M2M_CTRL_PW_WORD           |
                      M2M_CTRL_ETDP_AHIGH_OUTPUT |
                      M2M_CTRL_DREQP_HIGHLEVEL   |
                      M2M_CTRL_RSS_INTIDE        |
                      M2M_CTRL_NO_HDSK;

    //
    // Setup the DMA ctrl register.
    //
    if(fRead)
    {
        m_ulDmaCtrlReg  |= M2M_CTRL_SAH | M2M_CTRL_TM_HARDINITP2M;
    }
    else
    {
        m_ulDmaCtrlReg  |= M2M_CTRL_DAH | M2M_CTRL_TM_HARDINITM2P;
    }

    //
    // Setup the source and destination with there proper values.
    //
    switch(m_ulCurrentMode)
    {
// EP931x rev E1 doesn't support UWDMA
/*	    case MWDMA_MODE0:
        case MWDMA_MODE1:
        case MWDMA_MODE2:
            m_ulDmaCtrlReg |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;
            ulIDESource = 0x800a001C;  // IDE_MDMADATAIN
            ulIDEDest   = 0x800a0018;  // IDE_UDMADATAOUT
            break;

*/
        case UDMA_MODE0:
        case UDMA_MODE1:
        case UDMA_MODE2:
        case UDMA_MODE3:
//        case UDMA_MODE4:

            //* * * The timing below is the only reliable one that will work.
            //* * * More research needs to be done as to why...(START)
            m_ulDmaCtrlReg |= (fRead?1:2)<<M2M_CTRL_PWSC_SHIFT;
            ulIDESource = 0x800a0024; // IDE_UDMADATAIN
            ulIDEDest   = 0x800a0020; // IDE_UDMADATAOUT
            break;
        default:
            DEBUGMSG
            ( 
                1, 
                (
                    TEXT("ATAPI:SetupDMA EP9312 unsupported dma mode.\r\n")
                )
            );
            break;
    }

    //
    // Write out the DMA control register, then read it back to
    // make sure that it takes effect.
    //
    m_pulDmaBase[M2M_CTRL>>2] = m_ulDmaCtrlReg;
    ulDumbCntrlRead           = m_pulDmaBase[M2M_CTRL>>2]; 

    //
    // Clear the status register.
    //
    m_pulDmaBase[M2M_STATUS>>2] = 0;

    //
    // Bit definitions are the same for Udma and Mdma.
    //
    if(fRead)
    {
        m_pulDmaBase[M2M_SAR_BASE0>>2] = ulIDESource;        
        m_pulDmaBase[M2M_DAR_BASE0>>2] = m_ulDmaPhysBuff;       

        //
        // Write the extra data to location zero for now.
        //
        //m_pulDmaBase[M2M_SAR_BASE1>>2] = ulIDESource;        
        //m_pulDmaBase[M2M_DAR_BASE1>>2] = 0;       
    }
    else
    {
        m_pulDmaBase[M2M_SAR_BASE0>>2] = m_ulDmaPhysBuff;       
        m_pulDmaBase[M2M_DAR_BASE0>>2] = ulIDEDest;       

        //
        // Write the extra data to location zero for now.
        //
        // m_pulDmaBase[M2M_SAR_BASE1>>2] = 0;       
        // m_pulDmaBase[M2M_DAR_BASE1>>2] = ulIDEDest;       
    }

    //
    // Figure out the number of bytes to transfer. Round up.
    //

    //* * * This is needed for MDMA modes for CD/DVD drives.
    //* * * Probably not needed anymore...
    // if (m_ulDmaCount >= 0x10000)
    //    m_ulDmaCount = 0xFFFC;

    m_pulDmaBase[M2M_BCR0>>2] = m_ulDmaCount;
    // m_pulDmaBase[M2M_BCR1>>2] = 8;

 
    return TRUE;
}


//****************************************************************************
// CEP931xPort::BeginDMA
//****************************************************************************
// Begins the DMA engine.
// 
//
BOOL CEP931xPort::BeginDMA(BOOL fRead) 
{ 
    // volatile register ULONG           ulIdeCtrl;
    // volatile register ULONG ulDMAStatReg;
    // ULONG           BusyDMARQCount = 0;
    // DWORD TimeOut = 2, DMAREQLowCount = 0, DMAREQWentLow = 0; //* * * Was 10

    volatile ULONG           ulDumbCntrlRead;

    DEBUGMSG
    ( 
        ZONE_DMA, 
        (
            TEXT("ATAPI:BeginDMA\r\n")
        )
    );

    //
    // If the we are reading/writing directly to the memory buffers, we must
    // flush the data cache.
    // 
    //
    if(m_fAligned)
    {
        #if (_WIN32_WCE>=420)
        //
        // If we are running on Windows CE 4.2 flush the only the 
        // portion of the cache that we need.
        //
        // If we are writing to the hard drive, have the cache write
        // its contents to memory.
        //
        // If we are reading the hard drive, write to memory and 
        // discard the data in the cache.
        //
        CacheRangeFlush
        (
            m_pucDmaBuffer,
            m_ulDmaCount,
            fRead? CACHE_SYNC_DISCARD: CACHE_SYNC_WRITEBACK
        );
        #else
        CacheSync(CACHE_SYNC_DISCARD);
        #endif // 0
    }

    //
    // Original code waited for Busy to be  0 or for DMARQ is 1.
    // I am not sure if I need to do this also.
    //


    //
    // Check to see if there is data in the UDMA write buffer.
    //
    if(!(*IDE_UDMAWFST & 0x100) && !m_fDMARead)
    {
        DumpIDEState();
        DumpDmaState();
    }


    //
    // Setup the DMA control register and clear the start bit.
    //
    m_pulDmaBase[M2M_CTRL>>2] = m_ulDmaCtrlReg |= M2M_CTRL_ENABLE;
    ulDumbCntrlRead= m_pulDmaBase[M2M_CTRL>>2]; 

    //
    // Make sure there are no glitches involving CS0 or CS1 and STOP/DIOWn
    // when switching modes:  deassert CS0 and CS1.
    //
    *IDE_CTRL |= IDE_CTRL_CS0 | IDE_CTRL_CS1;

    switch(m_ulCurrentMode)
    {
// EP931x rev E1 doesn't support UWDMA
/*        case MWDMA_MODE0:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (0<<IDE_CFG_MODE_SHIFT);
            *IDE_MDMAOP = (fRead? 0: IDE_MDMAOP_RWOP);
            *IDE_MDMAOP |= IDE_MDMAOP_MEN ;
            break;
        case MWDMA_MODE1:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (1<<IDE_CFG_MODE_SHIFT);
            *IDE_MDMAOP = (fRead? 0: IDE_MDMAOP_RWOP);
            *IDE_MDMAOP |= IDE_MDMAOP_MEN ;
            break;
        case MWDMA_MODE2:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (2<<IDE_CFG_MODE_SHIFT);
            *IDE_MDMAOP = (fRead? 0: IDE_MDMAOP_RWOP);
            *IDE_MDMAOP |= IDE_MDMAOP_MEN ;
            break;
			*/
        case UDMA_MODE0:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (0<<IDE_CFG_MODE_SHIFT);
            *IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
            *IDE_UDMAOP |=IDE_UDMAOP_MEN ;
            break;
        case UDMA_MODE1:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (1<<IDE_CFG_MODE_SHIFT);
            *IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
            *IDE_UDMAOP |=IDE_UDMAOP_MEN ;
            break;
        case UDMA_MODE2:

⌨️ 快捷键说明

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