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

📄 atapiromi.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }

exit:;
    return bRet;
}

// ----------------------------------------------------------------------------
// Function: MainIoctl
//     This is redundant
//
// Parameters:
//     pIOReq -
// ----------------------------------------------------------------------------

DWORD
CRomiDisk::MainIoctl(
    PIOREQ pIOReq
    )
{
    DEBUGMSG(ZONE_IOCTL, (_T(
        "Atapi!CRomiDisk::MainIoctl> IOCTL(%d), device(%d) \r\n"
        ), pIOReq->dwCode, m_dwDeviceId));

    return CDisk::MainIoctl(pIOReq);
}

// ----------------------------------------------------------------------------
// Function: InitializePort
//     Initialize IST/ISR
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

BOOL 
CRomiDisk::InitializePort(
    )
{
    BOOL RetValue=TRUE;
    PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};
    
    m_pATAReg = (PBYTE)m_pPort->m_dwRegBase;

    m_pATARegAlt = (PBYTE)m_pPort->m_dwRegAlt;
    m_pBMCommand = (PBYTE)m_pPort->m_dwBMR;

    m_dwIndirectMode = m_pPort->m_pDskReg[m_dwDeviceId]->dwIndirectMode;

    // Map it if it is Memeory Mapped IO.
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_GPIO;    
    m_vpIOPORTRegs = (S3C6410_GPIO_REG *)MmMapIoSpace(ioPhysicalBase , sizeof(S3C6410_GPIO_REG),FALSE);
    if (m_vpIOPORTRegs == NULL)
    {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,(TEXT("For m_vpIOPORTRegs: MmMapIoSpace() failed IOPORT!\r\n")));
        RetValue = FALSE;
        goto init_done;
    }
    
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_SYSCON;    
    m_vpSYSCONRegs = (S3C6410_SYSCON_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_SYSCON_REG), FALSE);
    if (m_vpSYSCONRegs == NULL)
    {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,(TEXT("For m_vpSYSCONRegs: MmMapIoSpace() failed SYSCON!\r\n")));
        RetValue = FALSE;
        goto init_done;        
    }

    ConfigPort();

    if (m_pPort->m_pDskReg[m_dwDeviceId]->dwInterruptDriven || m_pPort->m_pDskReg[m_dwDeviceId]->dwEnableUDMA)
    {
        if (m_pPort->m_hIRQEvent) {
            m_dwDeviceFlags |= DFLAGS_DEVICE_INITIALIZED;
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T("atapiRomi already initialized\n")));
            return TRUE;
        }
        // create interrupt event
        if (NULL == (m_pPort->m_hIRQEvent = CreateEvent(NULL, FALSE, FALSE, NULL))) {
            DEBUGMSG(ZONE_INIT|ZONE_ERROR, (_T(
                "Atapi!CRomiDisk::ConfigPort> Failed to create interrupt event for device(%d)\r\n"
                ), m_dwDeviceId));
            return FALSE;
        }
    }
    
init_done:
    if ( RetValue != TRUE )
    {
        if ( m_vpSYSCONRegs)
        {
            MmUnmapIoSpace((PVOID)m_vpSYSCONRegs, sizeof(S3C6410_SYSCON_REG));
            m_vpSYSCONRegs= NULL;
        }
    
        if ( m_vpIOPORTRegs)
        {
            MmUnmapIoSpace((PVOID)m_vpIOPORTRegs, sizeof(S3C6410_GPIO_REG));
            m_vpIOPORTRegs= NULL;
        }        
    }

    return RetValue;

    //WriteDriveHeadReg(0x40);
}

// ----------------------------------------------------------------------------
// Function: ConfigPort
//     Initialize DATA/ADDR/Control port
//
// Parameters:
//     None
// ----------------------------------------------------------------------------

void
CRomiDisk::ConfigPort(
    )
{
    m_vpIOPORTRegs->GPPPUD |= (m_vpIOPORTRegs->GPPPUD & (~(0x3) << 28)) | (0x2 << 28);

    // Chip Selection signal in S3C6410 is controlled using "MEM_SYS_CFG" register in SYSCON.
    // MEM_SYS_CFG[5:4] = 2'b11 -> CFCON CS0, CFCON CS1
    m_vpSYSCONRegs->MEM_SYS_CFG |= ((m_vpSYSCONRegs->MEM_SYS_CFG & (~(0x3F<<0)))|(0x1<<5)|(0x1<<4));
    m_vpIOPORTRegs->GPBCON &= ~(0xF<<16);
    m_vpIOPORTRegs->GPBCON |= (4<<16);        // CF Data DIR

    if ( m_dwIndirectMode == 1 )
    {
        m_vpSYSCONRegs->MEM_SYS_CFG &= ~(0x1<<14); // InDirectMode
        m_dwOPMode = IndirectMode;
        DEBUGMSG(ZONE_INIT,(TEXT("[CF-ATA] Mode : InDirect Mode\n")));
    }
    else
    {
        m_vpSYSCONRegs->MEM_SYS_CFG |= (0x1<<14); // Use independent CF interface (DirectMode)
        m_dwOPMode = DirectMode;
        DEBUGMSG(ZONE_INIT,(TEXT("[CF-ATA] Mode : Direct Mode\n")));
    }

    // Set the GPIO for CF_Data, CF_Addr, IORDY, IOWR, IORD, CE[0], and CE[1]
    // Details.
    // 1. GPKCON0[31:0]  - DATA_CF[7:0] -> 4'b0101
    // 2. GPKCON1[31:0]  - DATA_CF[15:8] -> 4'b0101
    // 3. GPLCON0[11:0]  - ADDR_CF[2:0] -> 4'b0110
    // 4. GPMCON[19:16] - IORDY_CF -> 4'b0110
    // 5. GPMCON[15:12] - IOWR_CF -> 4'b0110
    // 6. GPMCON[11:8]   - IORD_CF -> 4'b0110
    // 7. GPMCON[7:4]      - CE_CF[1] -> 4'b0110
    // 8. GPMCON[3:0]     - CE_CF[0] -> 4'b0110


    if(m_dwOPMode == DirectMode)
    {
        m_vpIOPORTRegs->GPKCON0 = (m_vpIOPORTRegs->GPKCON0 & ~(0xFFFFFFFF)) | (0x55555555); // D: Set XhiDATA[7:0] pins as CF Data[7:0] 

        m_vpIOPORTRegs->GPKCON1 = (m_vpIOPORTRegs->GPKCON1 & ~(0xFFFFFFFF)) | (0x55555555); // D: Set XhiDATA[15:8] pins as CF Data[15:8]

        m_vpIOPORTRegs->GPLCON0 = (m_vpIOPORTRegs->GPLCON0 & ~(0xFFF)) | (0x666);           // A: Set XhiADDR[2:0] pins as CF ADDR[2:0]

        m_vpIOPORTRegs->GPMCON  = (m_vpIOPORTRegs->GPMCON & ~(0xFFFFF)) | (0x66666);        // IORDY_CF, IOWR_CF, IORD_CF, CE_CF[1:0]
    }

    m_vpIOPORTRegs->GPMCON = (m_vpIOPORTRegs->GPMCON &  ~(0xF<<20)) | 0x1<<20;              // set XhINTR/CF Data Dir./GPM5 as output
    m_vpIOPORTRegs->GPMDAT = (m_vpIOPORTRegs->GPMDAT | 0x1 << 5);                           // GPM[5] -> High

    WriteReg(MUX_REG, 0x07);
    WriteReg(MUX_REG, 0x03);
    WriteReg(MUX_REG, 0x01);
    Sleep(100);


    WriteReg(ATA_PIO_TIME, 0x1c238);
    WriteReg(ATA_UDMA_TIME, 0x20B1362);

    WriteReg(ATA_IRQ, ReadReg(ATA_IRQ) | 0x1f);
    WriteReg(ATA_IRQ_MASK, ReadReg(ATA_IRQ_MASK) | 0x1f);

    WriteReg(ATA_CFG, ReadReg(ATA_CFG) & ~(0x40));

    WriteReg(ATA_CONTROL, ReadReg(ATA_CONTROL) | 0x1);    // ATA is enabled, When this value is set to 1, delay of 200ms will be required(UserManual).
    Sleep(200);

    // Make the ADDR_CF0 port high for CF card boot up
    m_vpIOPORTRegs->GPNCON = (m_vpIOPORTRegs->GPNCON & ~(0x3<<16)) | (0x1<<16);     // set XEINT8/ADDR_CF0/GPN8 as output
    m_vpIOPORTRegs->GPNDAT |= (0x1<<8);                                             // GPN[8] -> High
    Sleep(100);
    m_vpIOPORTRegs->GPNDAT &= ~(0x1<<8);                                            // GPN[8] -> Low

}

// ----------------------------------------------------------------------------
// Function: TranslateAddress
//     Translate a system address to a bus address for the DMA controller
//
// Parameters:
//     pdwAddr -
// ----------------------------------------------------------------------------

BOOL
CRomiDisk::TranslateAddress(
    PDWORD pdwAddr
    )
{
    // translate a system address to a bus address for the DMA bus controller

    PHYSICAL_ADDRESS SystemLogicalAddress, TransLogicalAddress;
    DWORD dwBus;

    dwBus = m_pPort->m_pController->m_dwi.dwBusNumber;

    // translate address
    SystemLogicalAddress.HighPart = 0;
    SystemLogicalAddress.LowPart = *pdwAddr;
    if (!HalTranslateSystemAddress(PCIBus, dwBus, SystemLogicalAddress, &TransLogicalAddress)) {
        return FALSE;
    }

    *pdwAddr = TransLogicalAddress.LowPart;

    return TRUE;
}

 BOOL
CRomiDisk::WakeUp(
    )
{
    ConfigPort();
    return CDisk::Init(NULL);
}

CDiskPower *
CRomiDisk::GetDiskPowerInterface(
    void
    )
{
    CDiskPower *pDiskPower = new CDiskPower;
    return pDiskPower;
}

void
CRomiDisk::SetPioMode(UCHAR  pmode)
{
    UINT8 nMode;
    UINT32 uT1;
    UINT32 uT2;
    UINT32 uTeoc;
    UINT32 i;

    UINT32 uPioTime[5];
    UINT32 m_uPioT1[5] = {70,50,30,30,25};
    UINT32 m_uPioT2[5] = {290,290,290,80,70};
    UINT32 m_uPioTeoc[5] = {20,15,10,10,10};

    UINT32 uCycleTime = (UINT32)(1000000000/S3C6410_HCLK);

    UINT32 uTemp = ReadReg(ATA_CFG);

    if ((pmode & (UCHAR)0x3) == 1)
        nMode = PIO3;
    else if ((pmode & (UCHAR)0x3) == 3)
        nMode = PIO4;
    else
        nMode = PIO2 ;


    for (i=0; i<5; i++)
    {
        uT1   = (m_uPioT1[i]  /uCycleTime + 1)&0xff;
        uT2   = (m_uPioT2[i]  /uCycleTime + 1)&0xff;
        uTeoc = (m_uPioTeoc[i]/uCycleTime + 1)&0x0f;
        uPioTime[i] = (uTeoc<<12)|(uT2<<4)|uT1;
    }

    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DAD, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_FED, 0x3);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_SCR, (0x8 |(nMode&0x7)));
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LLR, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LMR, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LHR, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DVR, 0x40);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_CSD, ATAPI_CMD_SET_FEATURES);
    WaitForNoBusyStatus();
    switch(pmode) {
        case PIO1:
            uTemp &= (~0x2); //IORDY disable
            WriteReg(ATA_PIO_TIME, uPioTime[1]);
            break;
        case PIO2:
            uTemp &= (~0x2); //IORDY disable
            WriteReg(ATA_PIO_TIME, uPioTime[2]);
            break;
        case PIO3:
            uTemp |= 0x2; //IORDY enable
            WriteReg(ATA_PIO_TIME, uPioTime[3]);
            break;
        case PIO4:
            uTemp |= 0x2; //IORDY enable
            WriteReg(ATA_PIO_TIME, uPioTime[4]);
            break;
        default:
            uTemp &= (~0x2); //IORDY disable
            WriteReg(ATA_PIO_TIME, uPioTime[0]);
            break;
    }

    WriteReg(ATA_CFG, uTemp);
}


void
CRomiDisk::SetUdmaMode()
{

    UINT32 uTdvh1;
    UINT32 uTdvs;
    UINT32 uTrp;
    UINT32 uTss;
    UINT32 uTackenv;
    UINT32 i;

    UINT32 uUdmaTime[5] = {0};
    UINT32 uUdmaTdvh[5] = {20,20,10,10,10};
    UINT32 uUdmaTdvs[5] = {100,60,50,35,20};
    UINT32 uUdmaTrp[5] = {160,125,100,100,100};
    UINT32 uUdmaTss[5] = {50,50,50,50,50};
    UINT32 uUdmaTackenvMin[5] = {20,20,20,20,20};
    UINT32 uUdmaTackenvMax[5] = {70,70,70,55,55};
    UINT32 uCycleTime = (UINT32)(1000000000/S3C6410_HCLK);


    for (i=0; i<5; i++) 
    {
        uTdvh1  = (uUdmaTdvh[i] / uCycleTime /*+ 1*/)&0x0f;
        uTdvs   = (uUdmaTdvs[i] / uCycleTime /*+ 1*/)&0xff;
        uTrp    = (uUdmaTrp[i]  / uCycleTime /*+ 1*/)&0xff;
        uTss    = (uUdmaTss[i]  / uCycleTime /*+ 1*/)&0x0f;
        uTackenv= (uUdmaTackenvMin[i]/uCycleTime /*+ 1*/)&0x0f;
        uUdmaTime[i] = (uTdvh1<<24)|(uTdvs<<16)|(uTrp<<8)|(uTss<<4)|uTackenv;
    }

    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DAD, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_FED, 0x3);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_SCR, (0x40 |((BYTE)m_dwCurrentUDMAMode&0x7)));
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LLR, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LMR, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_LHR, 0x0);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_DVR, 0x40);
    ATA_WRITE_BYTE(m_pATAReg + ATA_PIO_CSD, ATAPI_CMD_SET_FEATURES);

    WaitForNoBusyStatus();


    switch(m_dwCurrentUDMAMode)
    {
        case UDMA0:
            //*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[0];
            WriteReg(ATA_UDMA_TIME, uUdmaTime[0]);
            break;
        case UDMA1:
            WriteReg(ATA_UDMA_TIME, uUdmaTime[1]);
            break;
        case UDMA2:
            WriteReg(ATA_UDMA_TIME, uUdmaTime[2]);
            break;
        case UDMA3:
            WriteReg(ATA_UDMA_TIME, uUdmaTime[3]);
            break;
        case UDMA4:
            WriteReg(ATA_UDMA_TIME, uUdmaTime[4]);
            break;
        default:
            DEBUGMSG(ZONE_INIT|ZONE_ERROR,(TEXT("UDMA mode is supported between 0 to 4 !!!! . %d\r\n"),m_dwCurrentUDMAMode));
            break;
    }
}


⌨️ 快捷键说明

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