📄 ep931xide.cpp
字号:
pSgBuf[0].sb_len,
PFNs,
fRead ? LOCKFLAG_WRITE : LOCKFLAG_READ
);
//
// If the function succeds, Check to make sure that the pages are physically contiguous.
// If they are not then do the unaligned buffer case.
//
if(fPagesLocked)
{
ulNumPages = 1 + ( (ULONG(m_pucDmaBuffer) + pSgBuf[0].sb_len) >> m_ulPageShift) -
( ULONG(m_pucDmaBuffer) >> m_ulPageShift);
for(ulPage = 0; ulPage< (ulNumPages - 1); ulPage++)
{
if(PFNs[ulPage] !=PFNs[ulPage + 1])
{
m_fAligned = FALSE;
break;
}
}
//
// If it is aligned then calculate the current physical address.
//
if(m_fAligned )
{
//* * * UserKInfo[KINX_PFN_SHIFT].
m_ulDmaPhysBuff = PFNs[0] + ((ULONG)m_pucDmaBuffer & (ulPageSize -1));
m_ulDmaCount = pSgBuf[0].sb_len;
}
else
{
//
// Unlock the pages and free the Mapped pointer.
//
fLockRet = UnlockPages
(
m_pucDmaBuffer,
pSgBuf[0].sb_len
);
ASSERT(fLockRet);
}
}
}
else
{
m_fAligned = FALSE;
}
//
// If the pSgBuf are unaligned copy the entire buffer to our buffer.
//
if(!m_fAligned )
{
//RETAILMSG( 1, (TEXT(" * * * Unaligned copy in SetupDMA... * * *\r\n")));
ulDmaCount = 0;
for (ulBuffer = 0; ulBuffer < dwSgCount; ulBuffer++)
{
if(!fRead)
{
if (pSgBuf[ulBuffer].sb_len >0x8000 || pSgBuf[ulBuffer].sb_len <=0 || pBuffer == NULL || m_pucStaticBuffer == NULL)
DEBUGMSG( 1, (TEXT(" * * * pSgBuf[ulBuffer].sb_len was %ld * * *\r\n"),pSgBuf[ulBuffer].sb_len));
pBuffer = (LPBYTE)MapPtrToProcess(pSgBuf[ulBuffer].sb_buf, GetCallerProcess());
memcpy(m_pucStaticBuffer + ulDmaCount, pBuffer, pSgBuf[ulBuffer].sb_len);
}
ulDmaCount+= pSgBuf[ulBuffer].sb_len;
}
m_ulDmaCount = ulDmaCount;
m_pucDmaBuffer = m_pucStaticBuffer;
m_ulDmaPhysBuff = m_ulStaticPhysBuff;
}
//* * * This is really stupid and not optimal. This should get tokenized
//* * * and placed in the PORT class.
//* * * Setup DMA controller.
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_DONEINTEN;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_BWC_FULLTRANS;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_PW_WORD;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_TM_SOFTINIT;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_ETDP_AHIGH_OUTPUT;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_DREQP_HIGHLEVEL;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_RSS_INTIDE;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_NO_HDSK;
//* * * CAMSDB - Test for proper DMA channel setup. (START)
DumbCntrlRead = m_pulDmaBase[M2M_CTRL>>2]; //* * * According to SPEC>
//* * * CAMSDB - Test for proper DMA channel setup. (END)
//
// Setup the DMA ctrl register.
//
if(fRead)
{
//* * * Original = m_ulDmaCtrlReg = M2M_CTRL_SAH | M2M_CTRL_TM_HARDINITP2M;
m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_SAH;
m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_TM_HARDINITP2M;
m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_NO_HDSK;
}
else
{
//* * * Original = m_ulDmaCtrlReg = M2M_CTRL_DAH | M2M_CTRL_TM_HARDINITM2P;
m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_DAH;
m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_TM_HARDINITM2P;
m_pulDmaBase[M2M_CTRL>>2] |=M2M_CTRL_NO_HDSK;
}
//* * * CAMSDB - Test for proper DMA channel setup. (START)
DumbCntrlRead = m_pulDmaBase[M2M_CTRL>>2]; //* * * According to SPEC>
//* * * CAMSDB - Test for proper DMA channel setup. (END)
//
// Setup the source and destination with there proper values.
//
switch(m_ulCurrentMode)
{
case MWDMA_MODE0:
case MWDMA_MODE1:
case MWDMA_MODE2:
//* * * Original = m_ulDmaCtrlReg |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;
m_pulDmaBase[M2M_CTRL>>2] |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;
ulIDESource = 0x800a001C;
ulIDEDest = 0x800a0018;
break;
case UDMA_MODE0:
case UDMA_MODE1:
case UDMA_MODE2:
case UDMA_MODE3:
case UDMA_MODE4:
//* * * Original = m_ulDmaCtrlReg |= (fRead?1:2)<<M2M_CTRL_PWSC_SHIFT;
//* * * The timing below is the only reliable one that will work.
//* * * More research needs to be done as to why...(START)
m_pulDmaBase[M2M_CTRL>>2] |= (fRead?3:3)<<M2M_CTRL_PWSC_SHIFT;
//* * * The timing above is the only reliable one that will work.
//* * * More research needs to be done as to why...(END)
ulIDESource = 0x800a0024;
ulIDEDest = 0x800a0020;
break;
default:
DEBUGMSG
(
1,
(
TEXT("ATAPI:SetupDMA EP9312 unsupported dma mode.\r\n")
)
);
break;
}
//* * * CAMSDB - Test for proper DMA channel setup. (START)
DumbCntrlRead = m_pulDmaBase[M2M_CTRL>>2]; //* * * According to SPEC>
//* * * CAMSDB - Test for proper DMA channel setup. (END)
//
// Clear the status register.
//
m_pulDmaBase[M2M_STATUS>>2] = 0;
//
// Bit definitions are the same for Udma and Mdma.
//
if(fRead)
{
m_pulDmaBase[M2M_SAR_BASE0>>2] = ulIDESource;
m_pulDmaBase[M2M_DAR_BASE0>>2] = m_ulDmaPhysBuff;
}
else
{
m_pulDmaBase[M2M_SAR_BASE0>>2] = m_ulDmaPhysBuff;
m_pulDmaBase[M2M_DAR_BASE0>>2] = ulIDEDest;
}
//
// Figure out the number of bytes to transfer. Round up.
//
//* * * This is needed for MDMA modes for CD/DVD drives.
//* * * Probably not needed anymore...
if (m_ulDmaCount >= 0x10000)
m_ulDmaCount = 0xFFFC;
m_pulDmaBase[M2M_BCR0>>2] = m_ulDmaCount;
//
// The IDE controller is now using DMA, yay sure Ron...
//
m_bDMAState = TRUE;
return TRUE;
}
//****************************************************************************
// CEP931xPort::BeginDMA
//****************************************************************************
// Begins the DMA engine.
//
//
BOOL CEP931xPort::BeginDMA(BOOL fRead)
{
volatile register BYTE bStatus;
volatile register ULONG ulIdeCtrl;
ULONG ulOP, BusyDMARQCount = 0;
volatile int DumbCntrlRead;
DWORD TimeOut = 2, DMAREQLowCount = 0, DMAREQWentLow = 0; //* * * Was 10
volatile register ULONG ulDMAStatReg;
ULONG DumbCount0 = 0,DumbCount1 = 0, DumbCount2 = 0, DumbCount3 = 0;
DEBUGMSG
(
ZONE_DMA,
(
TEXT("ATAPI:BeginDMA\r\n")
)
);
//
// If the we are reading/writing directly to the memory buffers, we must
// flush the data cache.
//
//
if(m_fAligned)
{
#if (_WIN32_WCE>=420)
//
// If we are running on Windows CE 4.2 flush the only the
// portion of the cache that we need.
//
// If we are writing to the hard drive, have the cache write
// its contents to memory.
//
// If we are reading the hard drive, write to memory and
// discard the data in the cache.
//
CacheRangeFlush
(
m_pucDmaBuffer,
m_ulDmaCount,
fRead? CACHE_SYNC_DISCARD: CACHE_SYNC_WRITEBACK
);
#else
CacheSync(CACHE_SYNC_DISCARD);
#endif // 0
}
//
// Setup the DMA control register and clear the start bit.
//
// * * Origina; = m_pulDmaBase[M2M_CTRL>>2] = m_ulDmaCtrlReg |= M2M_CTRL_ENABLE;
m_pulDmaBase[M2M_CTRL>>2] |= M2M_CTRL_ENABLE;
DumbCntrlRead = m_pulDmaBase[M2M_CTRL>>2]; // * * According to SPEC>
//* * * This is really stupid and not optimal. This should get tokenized
//* * * and placed in the PORT class.
switch(m_ulCurrentMode)
{
case MWDMA_MODE0:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (0<<IDE_CFG_MODE_SHIFT);
*IDE_MDMAOP = (fRead? 0: IDE_MDMAOP_RWOP);
*IDE_MDMAOP |= IDE_MDMAOP_MEN ;
break;
case MWDMA_MODE1:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (1<<IDE_CFG_MODE_SHIFT);
*IDE_MDMAOP = (fRead? 0: IDE_MDMAOP_RWOP);
*IDE_MDMAOP |= IDE_MDMAOP_MEN ;
break;
case MWDMA_MODE2:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_MDMAEN | (2<<IDE_CFG_MODE_SHIFT);
*IDE_MDMAOP = ulOP =(fRead? 0: IDE_MDMAOP_RWOP);
*IDE_MDMAOP |= IDE_MDMAOP_MEN ;
break;
case UDMA_MODE0:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (0<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE1:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (1<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE2:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (2<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE3:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (3<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
case UDMA_MODE4:
*IDE_CFG = IDE_CFG_IDEEN | IDE_CFG_UDMAEN | (4<<IDE_CFG_MODE_SHIFT);
*IDE_UDMAOP = (fRead? 0: IDE_UDMAOP_RWOP);
*IDE_UDMAOP |=IDE_UDMAOP_MEN ;
break;
default:
DEBUGMSG
(
1,
(
TEXT("ATAPI:BeginDMA EP9312 unsupported dma mode.\r\n")
)
);
break;
}
//* * * Wait for the DMA controller to latch a completion INT. (START)
BusyDMARQCount = 0;
ulIdeCtrl = m_pulDmaBase[M2M_INT>>2];
while(!(ulIdeCtrl & 0x00000002))
{
StallExecution (1);
ulIdeCtrl = m_pulDmaBase[M2M_INT>>2];
if (++BusyDMARQCount >=6000000L)
{
DEBUGMSG( ZONE_WARNING, (TEXT("* * * ATAPI:BeginDMA - Broke out of waiting for DMA interrupt.* * *\r\n")));
//RETAILMSG( 1, (TEXT("ATAPI:BeginDMA - Broke out of DMAREQ and BUSY wait#2.\r\n")));
break;
}
}
//* * * Wait for the DMA controller to latch a completion INT. (END)
//* * * See if the DMA is not done or was paused.
if (m_pulDmaBase[M2M_BCR0>>2] !=0)
DEBUGMSG( ZONE_WARNING, (TEXT("* * * ATAPI:BeginDMA - BCR was not 0x00, it was 0x%08x.* * *\r\n"),m_pulDmaBase[M2M_BCR0>>2]));
//RETAILMSG( ZONE_WARNING, (TEXT("ATAPI:BeginDMA Waiting for DMA INT took - %ld uS\r\n"),BusyDMARQCount));
DEBUGMSG ( ZONE_WARNING, (TEXT("* * * It took %lduS for DMA INT to trigger. * * *\r\n"),BusyDMARQCount));
return TRUE;
}
//****************************************************************************
// CEP931xPort::WaitForDMAREQFromDMACtrlr. NOTE: This is not used and can
// be taken out.
//****************************************************************************
// Waits for DMAREQ cycling from the DMA controllers perspective.
//
//
BOOL CEP931xPort::WaitForDMAREQFromDMACtrlr(BOOL HighOrLow)
{
DWORD TimeOut = 50000;
register ULONG ulDMAStatReg;
ULONG DumbCount0 = 0;
if (HighOrLow == TRUE)
{
//* * * Wait while DMAREQ from the DMA controllers perspective, is HIGH.
do
{
ulDMAStatReg = (ULONG)m_pulDmaBase[M2M_STATUS>>2];
StallExecution (1);
//* * * Wait for (1 x TimeOut)us.
if (++DumbCount0>TimeOut)
break;
}while ((ulDMAStatReg & 0x00002000));
}
else
{
//* * * Wait while DMAREQ from the DMA controllers perspective, is LOW.
do
{
ulDMAStatReg = (ULONG)m_pulDmaBase[M2M_STATUS>>2];
StallExecution (1);
//* * * Wait for (1 x TimeOut)us.
if (++DumbCount0>TimeOut)
break;
}while (!(ulDMAStatReg & 0x00002000));
}
//* * * See if the DMA is not done or was paused.
if (m_pulDmaBase[M2M_BCR0>>2] !=0)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -