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

📄 atamx31.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 4 页
字号:

			DDKIomuxGetPadConfig(DDK_IOMUX_PAD_CSI_D15, &slew, &drive, &mode, &trig, &pull);
			DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSI_D15, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, mode, trig, pull);

			DDKIomuxGetPadConfig(DDK_IOMUX_PAD_CSI_MCLK, &slew, &drive, &mode, &trig, &pull);
			DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSI_MCLK, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, mode, trig, pull);

			DDKIomuxGetPadConfig(DDK_IOMUX_PAD_CSI_VSYNC, &slew, &drive, &mode, &trig, &pull);
			DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSI_VSYNC, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, mode, trig, pull);

			DDKIomuxGetPadConfig(DDK_IOMUX_PAD_CSI_HSYNC, &slew, &drive, &mode, &trig, &pull);
			DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSI_HSYNC, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, mode, trig, pull);

			DDKIomuxGetPadConfig(DDK_IOMUX_PAD_CSI_PIXCLK, &slew, &drive, &mode, &trig, &pull);
			DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSI_PIXCLK, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, mode, trig, pull);

			DDKIomuxGetPadConfig(DDK_IOMUX_PAD_I2C_CLK, &slew, &drive, &mode, &trig, &pull);
			DDKIomuxSetPadConfig(DDK_IOMUX_PAD_I2C_CLK, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, mode, trig, pull);

			DDKIomuxGetPadConfig(DDK_IOMUX_PAD_I2C_DAT, &slew, &drive, &mode, &trig, &pull);
			DDKIomuxSetPadConfig(DDK_IOMUX_PAD_I2C_DAT, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, mode, trig, pull);
		}

    bRet = TRUE;

exit:
    return bRet;
}


// ----------------------------------------------------------------------------
// Function: InitializePort
//     Initialize ATA Port
//
// Parameters:
//     None
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
// ----------------------------------------------------------------------------

BOOL CMX31Disk::InitializePort(void)
{
    PHYSICAL_ADDRESS phyAddr;
    BOOL bRet = FALSE;

    DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk: InitializePort+")));
    if(g_pVAtaReg == NULL)
    {
        phyAddr.QuadPart = BSP_BASE_REG_PA_PBC_BASE;
        g_pPBC = (PCSP_PBC_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_PBC_REGS), FALSE);
        if (g_pPBC == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("CMX31Disk: MmMapIoSpace failed!\r\n")));
            goto exit;
        }

        phyAddr.QuadPart = CSP_BASE_REG_PA_ATA_CTRL;
        g_pVAtaReg = (PCSP_ATA_REG) MmMapIoSpace(phyAddr, sizeof(CSP_ATA_REG), FALSE);

        // Check if virtual mapping failed
        if (g_pVAtaReg == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("CMX31Disk: MmMapIoSpace failed!\r\n")));
            goto exit;
        }

        m_pATAReg = (PBYTE) (g_pVAtaReg);
        m_pATARegAlt = (PBYTE) (g_pVAtaReg);

        ConfigureRegisterBlock(4);

        DDKClockSetGatingMode(DDK_CLOCK_GATE_INDEX_ATA, DDK_CLOCK_GATE_MODE_ENABLED_ALL);
		
        ConfigureIOMUXPad(0);
		
        SetTimingRegisters(0, PIO_MODE, CLOCK_PERIOD);
        SetTimingRegisters(0, MDMA_MODE, CLOCK_PERIOD);
        SetTimingRegisters(0, UDMA_MODE, CLOCK_PERIOD);

        OUTREG8(&g_pVAtaReg->ATAControl, 0x00);
        Sleep(20);
        OUTREG8(&g_pVAtaReg->ATAControl, 0x40);
        Sleep(20);
    }
    bRet = TRUE;

exit:;
    DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk: InitializePort-")));
    return bRet;
}

// ----------------------------------------------------------------------------
// Function: ShowRegisters
//     Print current ATA registers
//
// Parameters:
//     None
// Returns:
//     None
// ----------------------------------------------------------------------------
void CMX31Disk::ShowRegisters(UCHAR usel)
{
	if(usel & 0x01)
	{
		DEBUGMSG(ZONE_INIT, (_T("ATAReg: ATA_TIME_CONFIG0 %p,0x%08x\n"), &g_pVAtaReg->ATA_TIME_CONFIG0, INREG32(&g_pVAtaReg->ATA_TIME_CONFIG0)));
		DEBUGMSG(ZONE_INIT, (_T("ATAReg: ATA_TIME_CONFIG1 %p,0x%08x\n"), &g_pVAtaReg->ATA_TIME_CONFIG1, INREG32(&g_pVAtaReg->ATA_TIME_CONFIG1)));
		DEBUGMSG(ZONE_INIT, (_T("ATAReg: ATA_TIME_CONFIG2 %p,0x%08x\n"), &g_pVAtaReg->ATA_TIME_CONFIG2, INREG32(&g_pVAtaReg->ATA_TIME_CONFIG2)));
		DEBUGMSG(ZONE_INIT, (_T("ATAReg: ATA_TIME_CONFIG3 %p,0x%08x\n"), &g_pVAtaReg->ATA_TIME_CONFIG3, INREG32(&g_pVAtaReg->ATA_TIME_CONFIG3)));
		DEBUGMSG(ZONE_INIT, (_T("ATAReg: ATA_TIME_CONFIG4 %p,0x%08x\n"), &g_pVAtaReg->ATA_TIME_CONFIG4, INREG32(&g_pVAtaReg->ATA_TIME_CONFIG4)));
		DEBUGMSG(ZONE_INIT, (_T("ATAReg: ATA_TIME_CONFIG5 %p,0x%08x\n"), &g_pVAtaReg->ATA_TIME_CONFIG5, INREG32(&g_pVAtaReg->ATA_TIME_CONFIG5)));

		DEBUGMSG(ZONE_INIT, (_T("ATAReg: ATAControl %p,0x%02x\n"), &g_pVAtaReg->ATAControl, INREG8(&g_pVAtaReg->ATAControl)));
		DEBUGMSG(ZONE_INIT, (_T("ATAReg: InterruptPending %p,0x%02x\n"), &g_pVAtaReg->InterruptPending, INREG8(&g_pVAtaReg->InterruptPending)));
	} 

	if(usel & 0x02)
	{
	}
}

#ifdef USE_SDMA

// ----------------------------------------------------------------------------
// Function: SetupDMA
//     Setup DMA transfer
//
// Parameters:
//     pSgBuf -
//     dwSgCount -
//     fRead -
// ----------------------------------------------------------------------------
BOOL CMX31Disk::SetupDMA(PSG_BUF pSgBuf, DWORD dwSgCount, BOOL fRead)
{
    UINT8 chan = fRead ? DmaChanATARx : DmaChanATATx;
    BOOL rc = TRUE;
#ifdef USE_SDMA_SG_LIST
    BOOL fAlign = TRUE;
#else
    BOOL fAlign = FALSE;
#endif
    DWORD dwLockedPages = 0;
    DWORD dwSize;

    // get the total size for this transfer in bytes
    m_dwTransferSize = 0;

    for(DWORD i = 0; i < dwSgCount; i++)
        m_dwTransferSize+=pSgBuf[i].sb_len;   
    
    DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::SetupDMA(%d, %d)+\n"), fRead, m_dwTransferSize * BYTES_PER_SECTOR));
    
    m_pDMASgBuf = pSgBuf;
    m_dwAlignedSgCount = 0;
    m_dwAlignedDescCount = 0;
    m_dwAlignedSgBytes = 0;
    m_DMAChan = chan;
    
    OUTREG8(&g_pVAtaReg->ATAControl, 0x40);  
    
    DWORD currentSg = 0;
    DWORD currentDesc = 0;
    DWORD pdwPages[ATA_MAX_DESC_COUNT];
    
    // For each ATA watermark aligned scatter/gather buffer 
    while((currentSg < dwSgCount) && fAlign)
    {    
        // Map address and check for security violation
        LPBYTE pBuffer = (LPBYTE)MapCallerPtr((LPVOID)pSgBuf[currentSg].sb_buf, pSgBuf[currentSg].sb_len);
        if (pSgBuf[currentSg].sb_buf != NULL && pBuffer == NULL) 
        {
            // security violation
            ERRORMSG(ZONE_ERROR, (TEXT(
                "CMX31Disk::SetupDMA> Failed to map pointer to caller\r\n"
                )));
            rc = FALSE;
            goto cleanUp;
        }
        
        if (!LockPages(pBuffer,pSgBuf[currentSg].sb_len,pdwPages, fRead ? LOCKFLAG_WRITE : LOCKFLAG_READ))
        {
            DEBUGMSG(ZONE_ERROR, (TEXT(
                "CMX31Disk::SetupDMA> LockPages failed\r\n"
                )));
            // Try to fall back to copy using aligned buffer
            fAlign = FALSE;
            break;
        }
        else
        {
            // Keep track of how many pages we have locked so we can
            // unlock them if we encounter a failure
            dwLockedPages++;
        }
        
        DWORD dwMaxPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(pSgBuf[currentSg].sb_buf,pSgBuf[currentSg].sb_len);
        DWORD dwTempLen = pSgBuf[currentSg].sb_len;
        DWORD dwTempPtr = (DWORD)pBuffer;

        for(DWORD i = 0; (i < dwMaxPages) && (dwTempLen > 0) && fAlign; i++)
        {                                   
            // try and rule out broken values
            DEBUGCHK(pdwPages[i] != 0);
            
            DWORD dwPhys = pdwPages[i] << UserKInfo[KINX_PFN_SHIFT]; // get the start address of pages        
            DWORD dwOffset = dwTempPtr & (UserKInfo[KINX_PAGESIZE] - 1); // offset into page, if any                       
            dwSize = UserKInfo[KINX_PAGESIZE] - dwOffset;
            
            if(dwSize > dwTempLen)
                dwSize = dwTempLen;
            
            dwPhys += dwOffset;                
            
            dwTempLen -= dwSize;
            dwTempPtr += dwSize;
            
            // If we have any unaligned SG pages, perform remainder of transfer
            // using a copy into an aligned buffer.  We require the buffers to
            // be cache line aligned to prevent coherency problems that may
            // result from concurrent accesses to cache line data that is
            // "shared" between the DMA and the CPU
            if (fRead && ((dwSize & CACHE_LINE_SIZE_MASK) || (dwPhys & CACHE_LINE_SIZE_MASK)))
            {
                //DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::SetupDMA unaligned page (sg = %d, page = %d, size = %d\r\n"), currentSg, i, dwSize));
                UnlockPages(pBuffer,pSgBuf[currentSg].sb_len);
                --dwLockedPages;

                fAlign = FALSE;
            }
            else if(!fRead && ((dwSize & 0x3) || (dwPhys & 0x3)))
            {
                UnlockPages(pBuffer,pSgBuf[currentSg].sb_len);
                --dwLockedPages;

                fAlign = FALSE;
            }
            else
            {
                // if we're at the end to enable the intr flag
                DWORD dwFlags;
                if(dwTempLen == 0 && (currentSg == (dwSgCount - 1)))
                    dwFlags = DDK_DMA_FLAGS_INTR | DDK_DMA_FLAGS_WRAP;
                else
                    dwFlags = DDK_DMA_FLAGS_CONT;
                
                //RETAILMSG(TRUE, (_T("DDKSdmaSetBufDesc-SG (BD[%d], chan = %d, flags = 0x%x, size = %d\r\n"), currentDesc, chan, dwFlags, dwSize));
	 
                // add new descriptor to chain
                DDKSdmaSetBufDesc(chan, currentDesc, dwFlags, dwPhys,
                    0, DDK_DMA_ACCESS_32BIT, (WORD)dwSize);
                
                ++currentDesc;
                
            }
            
        }
	 
        if (fAlign)
   {
            // Keep track of the aligned SG buffers.  If we encounter a
            // a misaligned length while walking through the current 
            // SG buffer pages, we will punt the remainder of the list back to
            // MapDMABuffers implementation
            m_dwAlignedSgBytes += pSgBuf[currentSg].sb_len;
            m_dwAlignedDescCount = currentDesc;
            m_dwAlignedSgCount = ++currentSg;
        }        
     
    }

    if (!fAlign)
    {
        if (fRead)
        {
            dwSize = m_dwTransferSize - m_dwAlignedSgBytes;
   } 
	 else
	 {
            dwSize = MoveDMABuffer(pSgBuf, m_dwAlignedSgCount, dwSgCount, fRead);
            DEBUGCHK(dwSize == (m_dwTransferSize - m_dwAlignedSgBytes));
        }
        
        DEBUGCHK(!(dwSize & (ATA_DMA_WATERMARK - 1)));
        
        //RETAILMSG(TRUE, (_T("DDKSdmaSetBufDesc (BD[%d], chan = %d, flags = 0x%x, size = %d\r\n"), dwAlignedDescCount, chan, DDK_DMA_FLAGS_INTR | DDK_DMA_FLAGS_WRAP, dwSize));
        
     // Set number of bytes to transfer
        DDKSdmaSetBufDesc(chan, m_dwAlignedDescCount, 
            DDK_DMA_FLAGS_INTR | DDK_DMA_FLAGS_WRAP, 
            PhysDMABufferAddr.LowPart, 0, DDK_DMA_ACCESS_32BIT, 
            (WORD)(dwSize)); 
    }

	 
    DDKSdmaStartChan(chan);

	 // set fifo alarm to 16 halfwords, midway
	 OUTREG8(&g_pVAtaReg->FIFOAlarm, ATA_DMA_WATERMARK/2) ;
	 
	 OUTREG8(&g_pVAtaReg->InterruptClear, 0xff);
	 OUTREG8(&g_pVAtaReg->InterruptEnable, 0x80);
	
cleanUp:
    if(!rc)
    {
        // Unlock any previous locked page ranges
        for(DWORD i = 0; i < dwLockedPages; i++)
        {
            LPBYTE pUnlockBuffer = (LPBYTE)MapCallerPtr((LPVOID)pSgBuf[i].sb_buf, pSgBuf[i].sb_len);        
            UnlockPages(pUnlockBuffer,pSgBuf[i].sb_len);
        }
        
    }
    
    return rc;
}

// ----------------------------------------------------------------------------
// Function: BeginDMA
//     Begin DMA transfer
//
// Parameters:
//     fRead -
// ----------------------------------------------------------------------------

BOOL
CMX31Disk::BeginDMA(
    BOOL fRead
    )
{
	 DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::BeginDMA+\n")));
	
    if (m_dwAlignedSgCount > 0)
    {
        CacheSync(CACHE_SYNC_DISCARD);
    }
	 
	 fSDMAIntrEnable = TRUE;
	
   BYTE bTransferMode = (BYTE)m_pPort->m_pDskReg[m_dwDeviceId]->dwTransferMode;
    
	 switch(bTransferMode)
	 {
		 case 0x20:  // MDMA_MODE:
		 case 0x21:
 		 case 0x22:
			 OUTREG8(&g_pVAtaReg->ATAControl, fRead ? 0xd8 : 0xea);  
			 break;
		 case 0x40:  // UDMA_MODE:
		 case 0x41:
		 case 0x42:
		 case 0x43:
		 case 0x44:
		 case 0x45:
			 OUTREG8(&g_pVAtaReg->ATAControl, fRead ? 0xdc : 0xee);
			 break;
	 }
	 DEBUGMSG(ZONE_FUNC, (_T("CMX31Disk::BeginDMA-\n")));
   return TRUE;
}

// ----------------------------------------------------------------------------
// Function: EndDMA
//     End DMA transfer
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL
CMX31Disk::EndDMA(
    )
{

⌨️ 快捷键说明

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