📄 atapiromi.cpp
字号:
WriteBMTable(m_pPRDPhys);
bStatus = ReadBMStatus();
bStatus |= 0x06;
// bStatus |= 0x66;
WriteBMStatus(bStatus);
if (fRead) {
bCommand = 0x08 | 0x01;
}
else {
bCommand = 0x00 | 0x01;
}
WriteBMCommand(bCommand);
bStatus = ReadBMStatus();
return TRUE;
}
// ----------------------------------------------------------------------------
// Function: EndDMA
// End DMA transfer
//
// Parameters:
// None
// ----------------------------------------------------------------------------
BOOL
CRomiDisk::EndDMA(
)
{
BYTE bStatus = ReadBMStatus();
if ((bStatus & BM_STATUS_INTR) && (bStatus & BM_STATUS_ACTIVE)) {
DEBUGMSG(ZONE_DMA, (_T(
"Atapi!CRomiDisk::EndDMA> Status: active; status(0x%x)\r\n"
), bStatus));
}
else if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) {
DEBUGMSG(ZONE_DMA, (_T(
"Atapi!CRomiDisk::EndDMA> Status: inactive; status(0x%x)\r\n"
), bStatus));
}
else if (!(bStatus & BM_STATUS_INTR)&& (bStatus & BM_STATUS_ACTIVE)) {
DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
"Atapi!CRomiDisk::EndDMA> Interrupt delayed; status(0x%x)\r\n"
), bStatus));
BOOL bCount = 0;
while (TRUE) {
StallExecution(100);
bCount++;
bStatus = ReadBMStatus();
if ((bStatus & BM_STATUS_INTR) && !(bStatus & BM_STATUS_ACTIVE)) {
DEBUGMSG(ZONE_DMA, (_T(
"Atapi!CRomiDisk::EndDMA> DMA complete after delay; status(0x%x)\r\n"
), bStatus));
break;
}
else {
DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
"Atapi!CRomiDisk::EndDMA> Interrupt still delayed; status(0x%x)\r\n"
), bStatus));
if (bCount > 10) {
WriteBMCommand(0);
return FALSE;
}
}
}
}
else {
if (bStatus & BM_STATUS_ERROR) {
DEBUGMSG(ZONE_ERROR|ZONE_DMA, (_T(
"Atapi!CRomiDisk::EndDMA> Error; (0x%x)\r\n"
), bStatus));
DEBUGCHK(0);
return FALSE;
}
}
WriteBMCommand(0);
return TRUE;
}
// ----------------------------------------------------------------------------
// Function: AbortDMA
// Abort DMA transfer
//
// Parameters:
// None
// ----------------------------------------------------------------------------
BOOL
CRomiDisk::AbortDMA(
)
{
DWORD i;
WriteBMCommand(0);
for (i = 0; i < m_dwSGCount; i++) {
if (!m_pSGCopy[i].pDstAddress) {
UnlockPages(m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
}
}
// free all but the first @MIN_PHYS_PAGES pages; these are fixed
for (i = MIN_PHYS_PAGES; i < m_dwPhysCount; i++) {
FreePhysMem(m_pPhysList[i].pVirtualAddress);
}
return FALSE;
}
// ----------------------------------------------------------------------------
// Function: CompleteDMA
// Complete DMA transfer
//
// Parameters:
// pSgBuf -
// dwSgCount -
// fRead -
// ----------------------------------------------------------------------------
BOOL
CRomiDisk::CompleteDMA(
PSG_BUF pSgBuf,
DWORD dwSgCount,
BOOL fRead
)
{
DWORD i;
for (i = 0; i < m_dwSGCount; i++) {
if (m_pSGCopy[i].pDstAddress) {
// this corresponds to an unaligned region; copy it back to the
// scatter/gather buffer
memcpy(m_pSGCopy[i].pDstAddress, m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
}
else {
// this memory region needs to be unlocked
UnlockPages(m_pSGCopy[i].pSrcAddress, m_pSGCopy[i].dwSize);
}
}
// free all but the first @MIN_PHYS_PAGES pages; the first @MIN_PHYS_PAGES
// pages are fixed
for (i = MIN_PHYS_PAGES; i < m_dwPhysCount; i++) {
FreePhysMem(m_pPhysList[i].pVirtualAddress);
}
return TRUE;
}
BOOL
CRomiDisk::WakeUp(
)
{
// 2007.04.11 D.Baek
// Notes :
// Chip Selection signal in S3C6400 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);
if ( m_dwIndirectMode == 1 )
{
m_vpSYSCONRegs->MEM_SYS_CFG &= ~(0x1<<14); // InDirectMode
m_dwOPMode = IndirectMode;
RETAILMSG(1,(TEXT("[CF-ATA] Mode : InDirect Mode\n")));
}
else
{
m_vpSYSCONRegs->MEM_SYS_CFG |= (0x1<<14); // Use independent CF interface (DirectMode)
m_dwOPMode = DirectMode;
RETAILMSG(1,(TEXT("[CF-ATA] Mode : Direct Mode\n")));
}
// 2007.04.11 D.Baek
// 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[74] - CE_CF[1] -> 4'b0110
// 8. GPMCON[3:0] - CE_CF[0] -> 4'b0110
if(m_dwOPMode == DirectMode)
{
m_vpIOPORTRegs->GPKCON0 &= ~(0xFFFFFFFF);
m_vpIOPORTRegs->GPKCON0 |= (0x55555555);
m_vpIOPORTRegs->GPKCON1 &= ~(0xFFFFFFFF);
m_vpIOPORTRegs->GPKCON1 |= (0x55555555);
//RETAILMSG(1,(TEXT("GPKCON0,1 : OK\r\n")));
m_vpIOPORTRegs->GPLCON0 &= ~(0xFFF);
m_vpIOPORTRegs->GPLCON0 |= (0x666);
m_vpIOPORTRegs->GPMCON &= ~(0xFFFFF);
m_vpIOPORTRegs->GPMCON |= (0x66666);
}
{
m_vpIOPORTRegs->GPMCON &= ~(0xFFFFFF);
m_vpIOPORTRegs->GPMCON |= (0x166666);
m_vpIOPORTRegs->GPMDAT &= ~(0x3<<5);
m_vpIOPORTRegs->GPMDAT |= (0x1<<5); // Set the GPMDAT[5] as HIGH
}
//2007.04.28 D.Baek
//The "output enable" and "Card Power Enable" signal is NOT connected. Namely, it is uncontrollable.
#if 1
*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x07;
*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x03;
#endif
*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x01;
Sleep(100);
*((UINT32 *)(m_pATAReg + ATA_PIO_TIME)) = 0x1c238;
*((UINT32 *)(m_pATAReg + ATA_UDMA_TIME)) = 0x20B1362 ;
*((UINT32 *)(m_pATAReg + ATA_IRQ)) |= 0x1f;
*((UINT32 *)(m_pATAReg + ATA_IRQ_MASK)) |= 0x1f;
*((UINT32 *)(m_pATAReg + ATA_CFG)) &= ~(0x40);
*((UINT32 *)(m_pATAReg + ATA_CONTROL)) |= 0x1;
Sleep(100);
m_vpIOPORTRegs->GPNCON &= ~(0x3<<16);
m_vpIOPORTRegs->GPNCON |= (0x1<<16); // Set GPN8 to output
m_vpIOPORTRegs->GPNDAT |= (0x1<<8);
Sleep(100);
m_vpIOPORTRegs->GPNDAT &= ~ (0x1<<8);
return CDisk::Init(NULL); // It is the simplest way and best way.
}
CDiskPower *
CRomiDisk::GetDiskPowerInterface(
void
)
{
CDiskPower *pDiskPower = new CRomiDiskPower;
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,30}; // min = {70,50,30,30,25};
UINT32 m_uPioT2[5] = {290,290,290,80,70}; // min = {290,290,290,80,70};
UINT32 m_uPioTeoc[5] = {20,20,10,10,10}; // min = {20,15,10,10,10};
UINT32 uCycleTime = (UINT32)(1000000000/S3C6400_HCLK);
*/
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/S3C6400_HCLK);
UINT32 uTemp = *((UINT32 *)(m_pATAReg + 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;
}
// g_vpATAPIRegs->ATA_IRQ=0xff;
// g_vpATAPIRegs->ATA_IRQ_MASK = ATAPI_MASK;
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) { // modified by Bryan W. Lee (Oct. 19th, 2005)
case PIO1:
uTemp &= (~0x2); //IORDY disable
*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[1];
break;
case PIO2:
uTemp &= (~0x2); //IORDY disable
*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[2];
break;
case PIO3:
uTemp |= 0x2; //IORDY enable
*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[3];
break;
case PIO4:
uTemp |= 0x2; //IORDY enable
*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[4];
break;
default:
uTemp &= (~0x2); //IORDY disable
*(UINT32 *)(m_pATAReg + ATA_PIO_TIME) = uPioTime[0];
break;
}
*(UINT32 *)(m_pATAReg + ATA_CFG) = uTemp;
}
void
CRomiDisk::SetUdmaMode()
{
UINT32 uTdvh1;
UINT32 uTdvs;
UINT32 uTrp;
UINT32 uTss;
UINT32 uTackenv;
UINT32 i;
UINT32 uUdmaTime[5];
UINT32 uUdmaTdvh[5] = {20,20,10,10,10}; //{7,7,7,7,7};
UINT32 uUdmaTdvs[5] = {100,60,50,35,20}; //{70,48,31,20,7};
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/S3C6400_HCLK);
//UINT32 uCycleTime = 7;
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;
uTackenv= (uUdmaTackenvMax[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];
break;
case UDMA1:
*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[1];
break;
case UDMA2:
*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[2];
break;
case UDMA3:
*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[3];
break;
case UDMA4:
*(UINT32 *)(m_pATAReg + ATA_UDMA_TIME) = uUdmaTime[4];
break;
default:
RETAILMSG(1,(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 + -