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

📄 ep931xide.cpp

📁 Cirrus EP9315 wince bsp
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//**********************************************************************
//                                                                      
// Filename: EP931xide.cpp
//                                                                      
// Description: IDE driver for the internal EP931x port.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2003, All Rights Reserved                       
//                                                                      
//**********************************************************************
#include "atamain.h"
#include <oalintr.h>
#include <CEDDK.h>
#include "ep931xide.h"
#include <hwdefs.h>
#include <dbgapi.h>
#define     DELAY_5NS                   __emit(0xe1a00000);

#define     DELAY_10NS                  __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     

#define     DELAY_50NS                  __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);     \
                                        __emit(0xe1a00000);

#define     DELAY_100NS                 DELAY_50NS              \
                                        DELAY_50NS


//#define DATA_REGISTER         0x00
//#define ERRORREGISTER        0x01
//#define FEATURESREGISTER     0x01
//#define SECTORCOUNTREGISTER  0x02
//#define SECTORNUMBERREGISTER 0x03
//#define CYLINDERLOWREGISTER  0x04
//#define CYLINDERHIGHREGISTER 0x05
//#define DEVICEHEADREGISTER   0x06
//#define COMMANDREGISTER      0x07
//#define STATUSREGISTER       0x07
// ATA Control Registers

//#define DEVICECONTROLREGISTER   0x06
//#define ALTERNATESTATUSREGISTER 0x06

//****************************************************************************
// ATAReadRegister
//****************************************************************************
// 
// 
__inline ULONG ATAReadRegister(ULONG ulRegister)
{

    ULONG uiValue;
    register ULONG ulControl;
    

    //
    // Setup the control register for a read.
    //
    *IDE_CTRL = ulControl = IDE_CTRL_DIOR | IDE_CTRL_DIOW | ulRegister;

    //
    // See Section 10.2.2 of the ATA/ATAPI Specification Version 5 for Delay
    // Information.
    //
    // PIO Mode 0 - Delay for 70ns. 
    // PIO Mode 1 - Delay for 50ns. 
    // PIO Mode 2 - Delay for 30ns. 
    // PIO Mode 3 - Delay for 30ns. 
    // PIO Mode 4 - Delay for 25ns. 
    //
    // For a write to a APB register with HCLK at 100Mhz is 130ns.
    // No extra delay is needed.
    //
    *IDE_CTRL = ulControl &= ~IDE_CTRL_DIOR;

    //
    // See Section 10.2.2 of the ATA/ATAPI Specification Version 5 for Delay
    // Information.
    //
    // PIO Mode 0 - Delay for 290ns. 
    // PIO Mode 1 - Delay for 290s. 
    // PIO Mode 2 - Delay for 290s. 
    // PIO Mode 3 - Delay for 80ns. 
    // PIO Mode 4 - Delay for 70ns. 
    //
    // For a write to a APB register with HCLK at 100Mhz is 130ns.
    // No extra delay is needed.
    //

    *IDE_CTRL = ulControl |= IDE_CTRL_DIOR;

    uiValue = *IDE_DATAIN;

    if(ulRegister == CSDA_DATA_REG)
    {
        return(uiValue & 0xFFFF);
    }
    else
    {
        return(uiValue & 0xFF);
    }
}

//-----------------------------------------------------------------------------
//
//  Function Name: ATAWriteCommandRegister
//
//  Function Description: Writes an 8-bit value to an ATA command register.
//
//-----------------------------------------------------------------------------
__inline void ATAWriteRegister(ULONG ulRegister, UINT uiData)
{
    register ULONG   ulControl;


    //
    // Setup the control register for a write.
    //
    *IDE_CTRL       = ulControl = IDE_CTRL_DIOR | IDE_CTRL_DIOW | ulRegister;
    *IDE_DATAOUT    = uiData;

    //
    // See Section 10.2.2 of the ATA/ATAPI Specification Version 5 for Delay
    // Information.
    //
    // PIO Mode 0 - Delay for 70ns. 
    // PIO Mode 1 - Delay for 50ns. 
    // PIO Mode 2 - Delay for 30ns. 
    // PIO Mode 3 - Delay for 30ns. 
    // PIO Mode 4 - Delay for 25ns. 
    //
    // For a write to a APB register with HCLK at 100Mhz is 130ns.
    // No extra delay is needed.
    //
    *IDE_CTRL = ulControl &= ~IDE_CTRL_DIOW;

    //
    // See Section 10.2.2 of the ATA/ATAPI Specification Version 5 for Delay
    // Information.
    //
    // PIO Mode 0 - Delay for 290ns. 
    // PIO Mode 1 - Delay for 290s. 
    // PIO Mode 2 - Delay for 290s. 
    // PIO Mode 3 - Delay for 80ns. 
    // PIO Mode 4 - Delay for 70ns. 
    //
    // For a write to a APB register with HCLK at 100Mhz is 130ns.
    // No extra delay is needed.
    //
    *IDE_CTRL = ulControl |= IDE_CTRL_DIOW;

    //
    // See Section 10.2.2 of the ATA/ATAPI Specification Version 5 for Delay
    // Information.  There are also delays from all the returns and
    // function calls so I am not putting the full delay in.
    //
    // PIO Mode 0 - N/A
    // PIO Mode 1 - N/A
    // PIO Mode 2 - N/A
    // PIO Mode 3 - Delay for 70ns. 
    // PIO Mode 4 - Delay for 25ns. 
    //
    // This 25ns easily gets eaten up by the function call return call and the few
    // necessary instructions in the functions were it is used.
    // DELAY_10NS
    // DELAY_10NS
    // DELAY_10NS
}



//****************************************************************************
// CEP931xPort::Init
//****************************************************************************
//
// Return TRUE  - Success
//        FALSE - Failure
//

BOOL CEP931xPort::Init()
{
    BOOL    bResult = TRUE;
    ULONG   ulShifted;
	int ThreadPriority;
    
    //
    // Find out the shift factor for the page size.
    //
    m_ulPageShift = 0;
    ulShifted     = UserKInfo[KINX_PAGESIZE];  
    while(ulShifted != 1)
    {
        m_ulPageShift++;
        ulShifted= ulShifted>>1;
    }


    //
    // Create an event and a thread, and then associate them. 
    //
    m_hIdeIntEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
    if(!m_hIdeIntEvent)
    {
        DEBUGMSG( ZONE_INIT, (TEXT("CEP931xDisk::Init Failed to Create Interrupt Event.\r\n")));
        bResult = FALSE;
    }

    //
    // Get the event handle, register the interrupt, and then
    // associate it with the event.
    //
    if(bResult)
    {
        bResult = InterruptInitialize(SYSINTR_IDE, m_hIdeIntEvent, NULL, 0) ;
        if(!bResult)
        {
            DEBUGMSG( ZONE_INIT, (TEXT("CEP931xDisk::Init Failed to InitializeInterrupt.\r\n")));
        }
    }

    //
    // Allocate a DMA buffer if the buffer is unaligned.  This is used if the 
    // buffer is unaligned. HalAllocateCommonBuffer
    //
    if(bResult)
    {
        m_pucStaticBuffer = (PUCHAR) AllocPhysMem
        (
            131072,                   
            PAGE_READWRITE | PAGE_NOCACHE,
            0,
            0,
            &m_ulStaticPhysBuff
        );
        bResult = m_pucStaticBuffer ?TRUE:FALSE;
    }
    

    if(bResult)
    {
        //
        // Initialize the IDE interface to PIO mode 4.
        //
        *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_PIOEN | IDE_CFG_PIO4 | (1 <<IDE_CFG_WST_SHIFT);

        *IDE_CTRL = IDE_CTRL_DIOR | IDE_CTRL_DIOW | CSDA_DATA_REG;


        //
        // Make sure that MDMA and UDMA are disabled.
        //
        *IDE_MDMAOP = 0;
        *IDE_UDMAOP = 0;    
    }

    return bResult;
}

//****************************************************************************
// CEP931xPort::~CEP931xPort
//****************************************************************************
// Destructor
// 
//
CEP931xPort::~CEP931xPort()
{
    BOOL    bResult = TRUE;

    if(m_hIdeIntEvent)
    {
        CloseHandle(m_hIdeIntEvent);
    }

    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; //* * * CAMSDB Added this 05/05/05. The original
                            //* * * value for alignment was 0x3.
	volatile register int DumbCntrlRead;
    

    DEBUGMSG
    ( 
        ZONE_DMA, 
        (
            TEXT("ATAPI:SetupDMA Request = %s SgCount=%ld\r\n"), 
            fRead ? TEXT("Read") : TEXT("Write"), 
            dwSgCount
        )
    );


	//* * * NOTE: Bootup default value is:0x04030000.  Which says 
	//* * * the following channels are on:
	//        PWRCNT_DMAM2MCH0            0x04000000
    //        PWRCNT_DMAM2MCH1            0x08000000 (Not applicable here)
    //        PWRCNT_DMAM2PCH1            0x00010000
    //        PWRCNT_DMAM2PCH0            0x00020000

    //
    // Stop any DMA that is occuring.
    //

	// * * * CAMSDB - Took this out because it's very stpuid. = m_pulDmaBase[M2M_CTRL>>2] &= ~M2M_CTRL_START;

	//* * * CAMSDB - Clear out control so it's very null.
    m_pulDmaBase[M2M_CTRL>>2] = 0;

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

    //
    // Lets save off the DMA information. What?
    //

	m_fAligned          = TRUE; 
    ulDmaCount        = 0;

    //
    // Check if either the buffer or the buffer length is unaligned.  If the buffers are not 
    //

	//* * * CAMSDB - Original line.  Changed 05/08/04 (START)
	//if(dwSgCount ==1 && !((ULONG)pSgBuf[0].sb_buf & 0x3) && !(pSgBuf[0].sb_len & 0x3))
	//* * * CAMSDB - Original line.  Changed 05/08/04 (END)

	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 = (LPBYTE)MapPtrToProcess(pSgBuf[0].sb_buf, GetCallerProcess());

        //
        // Lock the pages for reading or writing.
        //
        fPagesLocked = LockPages
        ( 
            m_pucDmaBuffer, 

⌨️ 快捷键说明

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