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

📄 ep931xide.cpp

📁 Cirrus EP9315 wince bsp
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            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) >> 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 )
    {
	//RETAILMSG( 1, (TEXT("     * * * 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( 1, (TEXT("     * * * pSgBuf[ulBuffer].sb_len was %ld * * *\r\n"),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;
    }

	//* * * This is really stupid and not optimal. This should get tokenized
    //* * * and placed in the PORT class.

    //* * * Setup DMA controller.
	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)

    //
    // Setup the DMA ctrl register.
    //
    if(fRead)
    {
        //* * * Original = m_ulDmaCtrlReg    = M2M_CTRL_SAH | M2M_CTRL_TM_HARDINITP2M;
		m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_SAH;
		m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_TM_HARDINITP2M;
		m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_NO_HDSK;

    }
    else
    {
		//* * * Original = m_ulDmaCtrlReg    = M2M_CTRL_DAH | M2M_CTRL_TM_HARDINITM2P;
		m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_DAH;
		m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_TM_HARDINITM2P;
		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)

    //
    // Setup the source and destination with there proper values.
    //
    switch(m_ulCurrentMode)
    {
        case MWDMA_MODE0:
        case MWDMA_MODE1:
        case MWDMA_MODE2:
            //* * * Original  = m_ulDmaCtrlReg |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;
			m_pulDmaBase[M2M_CTRL>>2] |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;
			ulIDESource = 0x800a001C; 
            ulIDEDest   = 0x800a0018; 
            break;
        case UDMA_MODE0:
        case UDMA_MODE1:
        case UDMA_MODE2:
        case UDMA_MODE3:
        case UDMA_MODE4:
            //* * * Original = m_ulDmaCtrlReg |= (fRead?1:2)<<M2M_CTRL_PWSC_SHIFT;

		    //* * * The timing below is the only reliable one that will work.
			//* * * More research needs to be done as to why...(START)
		
			m_pulDmaBase[M2M_CTRL>>2] |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;

		    //* * * The timing above is the only reliable one that will work.
			//* * * More research needs to be done as to why...(END)

			ulIDESource = 0x800a0024; 
			ulIDEDest   = 0x800a0020; 
            break;
        default:
            DEBUGMSG
            ( 
                1, 
                (
                    TEXT("ATAPI:SetupDMA EP9312 unsupported dma mode.\r\n")
                )
            );
            break;
    }

	//* * * 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)

    //
    // 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;       
    }
    else
    {
        m_pulDmaBase[M2M_SAR_BASE0>>2] = m_ulDmaPhysBuff;       
        m_pulDmaBase[M2M_DAR_BASE0>>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;

	//
    // The IDE controller is now using DMA, yay sure Ron...
    //
    m_bDMAState = TRUE;
 
    return TRUE;
}

//****************************************************************************
// CEP931xPort::BeginDMA
//****************************************************************************
// Begins the DMA engine.
// 
//
BOOL CEP931xPort::BeginDMA(BOOL fRead) 
{ 
    volatile register BYTE            bStatus;
    volatile register ULONG           ulIdeCtrl;
    ULONG           ulOP, BusyDMARQCount = 0;
	volatile int DumbCntrlRead;
    DWORD TimeOut = 2, DMAREQLowCount = 0, DMAREQWentLow = 0; //* * * Was 10
	volatile register ULONG ulDMAStatReg;
	ULONG DumbCount0 = 0,DumbCount1 = 0, DumbCount2 = 0, DumbCount3 = 0;

    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
    }

    //
    // Setup the DMA control register and clear the start bit.
    //

	//  * * Origina; = m_pulDmaBase[M2M_CTRL>>2] = m_ulDmaCtrlReg |= M2M_CTRL_ENABLE;
    m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_ENABLE;
	
	DumbCntrlRead = m_pulDmaBase[M2M_CTRL>>2]; //  * * According to SPEC>

	//* * * This is really stupid and not optimal. This should get tokenized
    //* * * and placed in the PORT class.
    switch(m_ulCurrentMode)
    {
        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 = ulOP =(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:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (2<<IDE_CFG_MODE_SHIFT);
            *IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
            *IDE_UDMAOP |=IDE_UDMAOP_MEN ;
            break;
        case UDMA_MODE3:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (3<<IDE_CFG_MODE_SHIFT);
            *IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
            *IDE_UDMAOP |=IDE_UDMAOP_MEN ;
            break;
        case UDMA_MODE4:
            *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (4<<IDE_CFG_MODE_SHIFT);
            *IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
            *IDE_UDMAOP |=IDE_UDMAOP_MEN ;
            break;
        default:
            DEBUGMSG
            ( 
                1, 
                (
                    TEXT("ATAPI:BeginDMA EP9312 unsupported dma mode.\r\n")
                )
            );
            break;
    }

	//* * * Wait for the DMA controller to latch a completion INT. (START)
	BusyDMARQCount = 0;
	ulIdeCtrl = m_pulDmaBase[M2M_INT>>2];
    while(!(ulIdeCtrl & 0x00000002))
    {
		StallExecution (1);
		ulIdeCtrl = m_pulDmaBase[M2M_INT>>2];
		
		if (++BusyDMARQCount >=6000000L)
			{
			DEBUGMSG( ZONE_WARNING, (TEXT("* * * ATAPI:BeginDMA - Broke out of waiting for DMA interrupt.* * *\r\n")));
			//RETAILMSG( 1, (TEXT("ATAPI:BeginDMA - Broke out of DMAREQ and BUSY wait#2.\r\n")));
			break;
			}
    }
	//* * * Wait for the DMA controller to latch a completion INT. (END)

	//* * * See if the DMA is not done or was paused.
	if (m_pulDmaBase[M2M_BCR0>>2] !=0)
		DEBUGMSG( ZONE_WARNING, (TEXT("* * * ATAPI:BeginDMA - BCR was not 0x00, it was 0x%08x.* * *\r\n"),m_pulDmaBase[M2M_BCR0>>2]));
	
	//RETAILMSG( ZONE_WARNING, (TEXT("ATAPI:BeginDMA Waiting for DMA INT took - %ld uS\r\n"),BusyDMARQCount));
	DEBUGMSG ( ZONE_WARNING, (TEXT("* * * It took %lduS for DMA INT to trigger. * * *\r\n"),BusyDMARQCount));

    return TRUE;
}

//****************************************************************************
// CEP931xPort::WaitForDMAREQFromDMACtrlr.  NOTE: This is not used and can
//                                          be taken out.
//****************************************************************************
// Waits for DMAREQ cycling from the DMA controllers perspective.
// 
//
BOOL CEP931xPort::WaitForDMAREQFromDMACtrlr(BOOL HighOrLow)  
{ 
    DWORD TimeOut = 50000;
	register ULONG ulDMAStatReg;
	ULONG DumbCount0 = 0;

	if (HighOrLow == TRUE)
		{
		//* * * Wait while DMAREQ from the DMA controllers perspective, is HIGH.
		do
			{
			ulDMAStatReg = (ULONG)m_pulDmaBase[M2M_STATUS>>2];
			StallExecution (1);

			//* * * Wait for (1 x TimeOut)us.
			if (++DumbCount0>TimeOut)
				break;

			}while ((ulDMAStatReg & 0x00002000));
		}
	else
		{
		//* * * Wait while DMAREQ from the DMA controllers perspective, is LOW.
		do
			{
			ulDMAStatReg = (ULONG)m_pulDmaBase[M2M_STATUS>>2];
			StallExecution (1);

			//* * * Wait for (1 x TimeOut)us.
			if (++DumbCount0>TimeOut)
				break;

			}while (!(ulDMAStatReg & 0x00002000));
		}

	//* * * See if the DMA is not done or was paused.
	if (m_pulDmaBase[M2M_BCR0>>2] !=0)
		{
		}
	

⌨️ 快捷键说明

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