📄 atapiromi.cpp
字号:
// ----------------------------------------------------------------------------
// Function: BeginDMA
// Begin DMA transfer
//
// Parameters:
// fRead -
// ----------------------------------------------------------------------------
BOOL
CRomiDisk::BeginDMA(
BOOL fRead
)
{
BYTE bStatus, bCommand;
CacheSync(CACHE_SYNC_DISCARD);
WriteBMCommand(0);
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(
)
{
// BOOL retVal;
//jungpil
//memory controller settings are not recovered from Wakeup
m_vpEBIRegs->EBICON |= (1<<10)|(1<<9);
m_vpIOPORTRegs->GPGCON |= (3<<30)|(3<<28)|(3<<26)|(3<<24)|(3<<22);
#if (BSP_TYPE == BSP_SMDK2443)
m_vpIOPORTRegs->GPADAT = 0x1aa8a; // GPA10 RDATA_OEN setting
#elif (BSP_TYPE == BSP_SMDK2450)
m_vpIOPORTRegs->GPACON |= (1<<27)|(1<<11)|(1<<14)|(1<<13);// nWE_CF,nOE_CF,nRCS3,nRCS2 enable //S3C2450X01
// m_vpIOPORTRegs->GPACON &= ~(0x1<<10); // GPA10 RDATA_OEN setting
#endif // (BSP_TYPE == BSP_SMDK2443)
m_vpIOPORTRegs->MISCCR &=(~(1<<30)); // card detect when card is detected ,the bit should be '0'.
m_vpIOPORTRegs->GPADAT &=~(0x1<<13);
Sleep(2);
*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x07;
Sleep(2);
*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x03;
Sleep(2);
*((UINT32 *)(m_pATAReg + MUX_REG)) = 0x01;
Sleep(500);
*((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_CONTROL)) |= 0x1;
//power on
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] = {100,60,40,40,40}; // min = {70,50,30,30,25};
UINT32 m_uPioT2[5] = {400,300,290,130,70}; // min = {290,290,290,80,70};
UINT32 m_uPioTeoc[5] = {100,25,10,10,10}; // min = {20,15,10,10,10};
UINT32 uCycleTime = (UINT32)(1000000000/S3C2450_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_vATAPIRegs->ATA_IRQ=0xff;
// g_vATAPIRegs->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,20,20,10}; //{7,7,7,7,7};
UINT32 uUdmaTdvs[5] = {100,60,40,25,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 uUdmaTackenvMin[5] = {70,70,70,55,55};
UINT32 uCycleTime = (UINT32)(1000000000/S3C2450_HCLK);
#if 1
m_vpIOPORTRegs->GPADAT &= ~(1<<5); // GPA10 RDATA_fOEN setting
// rGPACDH = 0xaa8a; // GPA10 RDATA_OEN setting
// rGPBCON = rGPBCON & ~(3<<12) | (1<<12); // GPB6 output setting (nXBREQ)
// rGPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable
#else
g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0xf<<10)) | (5<<10); // GPB5,6 output mode
g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0x3<<8)) |( 1<<8); // GPB4 output mode
g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0x3<<0)) |( 1<<0); // GPB4 output mode
g_vIOPORTRegs->GPBDAT |= (3<<5); // GPB5,6 -> H
#endif
// ChangeBufferControl(PIO_CPU);
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_SCR, (0x40 |(3&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)
// switch(3)
{
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 + -