📄 ata.c
字号:
SetResStopwatch(10000); // us order, 10000us = 10ms
#endif
uRemainderCount = uSectorCount;
uCurrentLba = uLBA;
uRound = 0;
while(uRemainderCount != 0) {
if(uRemainderCount>256) {
uCurrentCount = 256; //0 means 256
uRemainderCount -= 256;
} else {
uCurrentCount = uRemainderCount;
uRemainderCount = 0;
}
uCurrentLba = uLBA + uRound*256;
uCurrentDstAddr = uDesAddress + uRound*256*ATA_SECTORSIZE;
uAtaHostAddr = (unsigned short*)uCurrentDstAddr;
SetAtaDevice(uCurrentLba, uCurrentCount);
WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);
while(uCurrentCount-- ) {
WaitForDeviceReady();
#if PERF_TEST_PIO_D
StartStopwatch(); // Start timer
#endif
for (i=0;i<ATA_SECTORSIZE/2;i++) {
GetDataFromDevice(uAtaHostAddr);
uAtaHostAddr++;
}
#if PERF_TEST_PIO_D
op_time += EndStopwatch(); // end timer, us order
#endif
}
WaitForDeviceReady();
uRound++;
}
#if PERF_TEST_PIO_D
printf ("PIO Reading time : %d us, Performance : %lf MByte/sec\n"
,op_time,(float)(uSectorCount*512./op_time));
#endif
return TRUE;
}
// modify 070704
bool WriteSectors_PioDma(unsigned int uLBA, unsigned int uSectorCount, unsigned int uSrcAddress)
{
unsigned int uCurrentCount;
unsigned int uRemainderCount;
unsigned int uCurrentLba;
unsigned int uCurrentSrcAddr;
unsigned int uRound;
unsigned int i;
#if PERF_TEST_PIO_D
unsigned int op_time = 0;
SetResStopwatch(10000); // us order, 10000us = 10ms
#endif
uRemainderCount = uSectorCount;
uCurrentLba = uLBA;
uRound = 0;
while(uRemainderCount != 0) {
if(uRemainderCount>256) {
uCurrentCount = 256; //0 means 256
uRemainderCount -= 256;
} else {
uCurrentCount = uRemainderCount;
uRemainderCount = 0;
}
uCurrentLba = uLBA + uRound*256;
uCurrentSrcAddr = uSrcAddress + uRound*256*ATA_SECTORSIZE;
SetAtaDevice(uCurrentLba, uCurrentCount);
WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR);
while(uCurrentCount-- ) {
Outp32(ATA_SBUF_START, uCurrentSrcAddr);
Outp32(ATA_SBUF_SIZE, 1*ATA_SECTORSIZE - 1);
Outp32(ATA_XFR_NUM, (1*ATA_SECTORSIZE));
WaitForDeviceReady();
SetConfigMode(PIO_DMA, TRUE); // write
#if PERF_TEST_PIO_D
StartStopwatch(); // Start timer
#endif
SetTransferCommand(ATA_CMD_START);
WaitForTransferDone();
SetTransferCommand(ATA_CMD_ABORT);
#if PERF_TEST_PIO_D
op_time += EndStopwatch(); // end timer, us order
#endif
SetConfigMode(PIO_CPU, FALSE);
uCurrentSrcAddr += 512;
}
WaitForDeviceReady();
uRound++;
}
#if PERF_TEST_PIO_D
printf ("PIO Writing time : %d us, Performance : %lf MByte/sec\n"
,op_time,(float)(uSectorCount*512./op_time));
#endif
return TRUE;
}
// modify 070704
bool ReadSectors_PioDma(unsigned int uLBA, unsigned int uSectorCount, unsigned int uDesAddress)
{
unsigned int uCurrentCount;
unsigned int uRemainderCount;
unsigned int uCurrentLba;
unsigned int uCurrentDstAddr;
unsigned int uRound;
unsigned int i;
#if PERF_TEST_PIO_D
unsigned int op_time = 0;
SetResStopwatch(10000); // us order, 10000us = 10ms
#endif
uRemainderCount = uSectorCount;
uCurrentLba = uLBA;
uRound = 0;
while(uRemainderCount != 0) {
if(uRemainderCount>256) {
uCurrentCount = 256; //0 means 256
uRemainderCount -= 256;
} else {
uCurrentCount = uRemainderCount;
uRemainderCount = 0;
}
uCurrentLba = uLBA + uRound*256;
uCurrentDstAddr = uDesAddress + uRound*256*ATA_SECTORSIZE;
SetAtaDevice(uCurrentLba, uCurrentCount);
WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);
while(uCurrentCount-- ) {
Outp32(ATA_TBUF_START, uCurrentDstAddr);
Outp32(ATA_TBUF_SIZE, 1*ATA_SECTORSIZE - 1);
Outp32(ATA_XFR_NUM, 1*ATA_SECTORSIZE);
WaitForDeviceReady();
SetConfigMode(PIO_DMA, FALSE); // read
#if PERF_TEST_PIO_D
StartStopwatch(); // Start timer
#endif
SetTransferCommand(ATA_CMD_START);
WaitForTransferDone();
SetTransferCommand(ATA_CMD_ABORT);
#if PERF_TEST_PIO_D
op_time += EndStopwatch(); // end timer, us order
#endif
SetConfigMode(PIO_CPU, FALSE);
uCurrentDstAddr += 512;
}
WaitForDeviceReady();
uRound++;
}
#if PERF_TEST_PIO_D
printf ("PIO Reading time : %d us, Performance : %lf MByte/sec\n"
,op_time,(float)(uSectorCount*512./op_time));
#endif
return TRUE;
}
bool WriteSectors_Udma(unsigned int uLBA, unsigned int uSectorCount, unsigned int uSrcAddress)
{
unsigned int uCurrentCount;
unsigned int uRemainderCount;
unsigned int uCurrentLba;
unsigned int uCurrentSrcAddr;
unsigned int uRound, i;
unsigned int rw_time = 0;
unsigned int t_time = 0;
#if PERF_TEST_UDMA_D
unsigned int op_time[255][3] = 0;
SetResStopwatch(10000); // us order, interval 10000us = 10ms
#endif
uRemainderCount = uSectorCount;
uRound = 0;
while(uRemainderCount != 0) {
if(uRemainderCount>256) {
uCurrentCount = 256; //0 means 256
uRemainderCount -= 256;
} else {
uCurrentCount = uRemainderCount;
uRemainderCount = 0;
}
uCurrentLba = uLBA + uRound*256;
uCurrentSrcAddr = uSrcAddress + uRound*256*ATA_SECTORSIZE;
#if 0
StartWritingBlocks(uCurrentLba, uCurrentCount, uCurrentSrcAddr);
IsWritingBlocksDone();
#else
#if PERF_TEST_UDMA_D
StartStopwatch(); // Start timer
#endif
/*Source Buffer 1 Setting*/
Outp32(ATA_SBUF_START, uCurrentSrcAddr);
Outp32(ATA_SBUF_SIZE, uCurrentCount*ATA_SECTORSIZE - 1);
Outp32(ATA_XFR_NUM, uCurrentCount*ATA_SECTORSIZE);
SetAtaDevice(uCurrentLba, uCurrentCount);
WriteOnTaskFileReg(DEV_COMMAND,WRITEDMA);
WaitForDeviceReady();
SetConfigMode(UDMA, TRUE);
#if PERF_TEST_UDMA_D
op_time[uRound][0] = EndStopwatch(); // end timer, us order
StartStopwatch(); // Start timer
#endif
/*ATA Transfer Command */
// ChangeBufferControl(UDMA);
// SetBufferDirection(WRITEDMA);
SetTransferCommand(ATA_CMD_START);
#if 1
WaitForTransferDone();
#else // abort operation
while(1){
Inp32(ATA_XFR_CNT, temp);
if(temp <= uCurrentCount*ATA_SECTORSIZE) break;
}
#endif
SetTransferCommand(ATA_CMD_ABORT);
// SetBufferDirection(0); // clear to H
// ChangeBufferControl(PIO_CPU);
#if PERF_TEST_UDMA_D
op_time[uRound][1] = EndStopwatch(); // end timer, us order
StartStopwatch(); // Start timer
#endif
SetConfigMode(PIO_CPU, TRUE);
WaitForDeviceReady();
uCfgReg &= (~0x200); // disable ATA DMA auto mode
Outp32(ATA_CFG, uCfgReg);
#if PERF_TEST_UDMA_D
op_time[uRound][2] = EndStopwatch(); // end timer, us order
#endif
#endif
uRound++;
}
#if PERF_TEST_UDMA_D
printf ("\n** UDMA writing performance measuring\n");
for (i=0; i<uRound; i++)
{
printf(" track %d : ready = %dus, r/w = %dus, aborting = %dus \n",
i,op_time[i][0], op_time[i][1], op_time[i][2]);
rw_time += op_time[i][1];
t_time += op_time[i][0] + op_time[i][1] + op_time[i][2];
}
printf ("** UDMA only writing time : %d us, only W Performance : %lf MByte/sec\n"
,rw_time,(float)(uSectorCount*512./rw_time));
printf ("** UDMA total writing time : %d us, total W Performance : %lf MByte/sec\n"
,t_time,(float)(uSectorCount*512./t_time));
#endif
return TRUE;
}
bool ReadSectors_Udma(unsigned int uLBA, unsigned int uSectorCount, unsigned int uDstAddress)
{
unsigned int uCurrentCount;
unsigned int uRemainderCount;
unsigned int uCurrentLba;
unsigned int uCurrentDstAddr;
unsigned int uRound, i;
unsigned int rw_time = 0;
unsigned int t_time = 0;
#if PERF_TEST_UDMA_D
unsigned int op_time[255][3] = 0;
SetResStopwatch(10000); // us order, 10000us = 10ms
#endif
uRemainderCount = uSectorCount;
uRound = 0;
while(uRemainderCount != 0) {
if(uRemainderCount>256) {
uCurrentCount = 256; //0 means 256
uRemainderCount -= 256;
} else {
uCurrentCount = uRemainderCount;
uRemainderCount = 0;
}
uCurrentLba = uLBA + uRound*256;
uCurrentDstAddr = uDstAddress + uRound*256*ATA_SECTORSIZE;
#if 0
StartReadingBlocks(uCurrentLba, uCurrentCount, uCurrentDstAddr);
IsReadingBlocksDone();
#else
#if PERF_TEST_UDMA_D
StartStopwatch(); // Start timer
#endif
/*Track Buffer 1 Setting*/
Outp32(ATA_TBUF_START, uCurrentDstAddr);
Outp32(ATA_TBUF_SIZE, uCurrentCount*ATA_SECTORSIZE - 1);
Outp32(ATA_XFR_NUM, uCurrentCount*ATA_SECTORSIZE);
SetAtaDevice(uCurrentLba, uCurrentCount);
WriteOnTaskFileReg(DEV_COMMAND,READDMA);
WaitForDeviceReady(); // too long time.... in UDMA mode
TDelay(100);
SetConfigMode(UDMA, FALSE);
#if PERF_TEST_UDMA_D
op_time[uRound][0] = EndStopwatch(); // end timer, us order
StartStopwatch(); // Start timer
#endif
/*ATA Transfer Command */
// ChangeBufferControl(UDMA);
// SetBufferDirection(READDMA);
SetTransferCommand(ATA_CMD_START);
WaitForTransferDone(); // Host
SetTransferCommand(ATA_CMD_ABORT);
// SetBufferDirection(0); // clear to H
// ChangeBufferControl(PIO_CPU);
#if PERF_TEST_UDMA_D
op_time[uRound][1] = EndStopwatch(); // end timer, us order
StartStopwatch(); // Start timer
#endif
SetConfigMode(PIO_CPU, FALSE);
WaitForDeviceReady();
uCfgReg &= (~0x200); // disable ATA DMA auto mode
Outp32(ATA_CFG, uCfgReg);
#if PERF_TEST_UDMA_D
op_time[uRound][2] = EndStopwatch(); // end timer, us order
#endif
#endif
uRound++;
}
#if PERF_TEST_UDMA_D
printf ("\n** UDMA reading performance measuring\n");
for (i=0; i<uRound; i++)
{
printf(" track %d : ready = %dus, r/w = %dus, aborting = %dus \n",
i,op_time[i][0], op_time[i][1], op_time[i][2]);
rw_time += op_time[i][1];
t_time += op_time[i][0] + op_time[i][1] + op_time[i][2];
}
printf ("** UDMA only reading time : %d us, only R Performance : %lf MByte/sec\n"
,rw_time,(float)(uSectorCount*512./rw_time));
printf ("** UDMA total reading time : %d us, total R Performance : %lf MByte/sec\n"
,t_time,(float)(uSectorCount*512./t_time));
#endif
return TRUE;
}
void InitBufferControl(void) // added by junon for second UDMA test b'd 060902
{
#ifdef __EVT1
//rGPACDH = 0x1aa8a; // GPA10 RDATA_OEN setting
#else
rGPBCON = rGPBCON & ~((3<<8)|(3)) | (1<<8)|(1); // GPB0,4 output setting (TOUT0, TCLK - TP21,20)
rGPBCON = rGPBCON & ~((3<<12)|(3<<10)) | (1<<12)|(1<<10); // GPB5,6 output setting (nXBACK, nXBREQ)
rGPBDAT = rGPBDAT & ~((7<<4)|(1)) | (1<<6); // GPB6->high, GPB0,4,5->low
#endif
DbgAta(("IBC - rGPBCON = 0x%x \n",rGPBCON));
}
void ChangeBufferControl(ATA_MODE mode) // only for SMDK b'd 060902 using additianal logic
{
if (mode == UDMA)
rGPBDAT = rGPBDAT | (1<<4)|(1); // GPB0->high,GPB4->high => UDMA mode
else // PIO
rGPBDAT = rGPBDAT & ~(1<<4) | (1); // GPB0->high,GPB4->low => ATA PIO mode
DbgAta(("BC - rGPBDAT = 0x%x \n",rGPBDAT));
}
void SetBufferDirection(unsigned int dir) // only for SMDK b'd 060812 using additianal logic
{
switch(dir)
{
case READDMA :
rGPBDAT &= ~(1<<5); // GPB5 -> L, buffer direction - read setting s
rGPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable
break;
case WRITEDMA :
rGPBDAT |= (1<<5); // GPB5 -> H, buffer direction - write setting
rGPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable 060812
break;
default : // clear
rGPBDAT &= ~(1<<5); // GPB5 -> L, buffer direction - read setting -> must change to PIO mode
rGPBDAT |= (1<<6); // GPB6 -> H, buffer Output disable
break;
}
DbgAta(("BD - rGPBDAT = 0x%x \n",rGPBDAT));
}
///////////////////// for currupted data test // hready test
bool StartWriting(U32 uStBlock, U32 uBlocks, U32 uBufAddr)
{
/*Source Buffer Setting*/
Outp32(ATA_SBUF_START, uBufAddr);
Outp32(ATA_SBUF_SIZE, uBlocks*ATA_SECTORSIZE);
Outp32(ATA_XFR_NUM, uBlocks*ATA_SECTORSIZE);
//Outp32(ATA_XFR_NUM, (uBlocks+3)*ATA_SECTORSIZE);
printf("ATA_XFR_NUM= %x\n",rATA_XFR_NUM);
SetAtaDevice(uStBlock, uBlocks);
WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR);
WaitForDeviceReady();
SetConfigMode(eMode, TRUE);
SetTransferCommand(ATA_CMD_START); //START
//*(volatile unsigned *)ATA_COMMAND = 2; //abort
WaitForHostReady(); /// needed
#if USE_SWAP
ATA_Command(0);
#else
*(volatile unsigned *)ATA_COMMAND = 0; //STOP
#endif
WaitForHostReady(); /// needed
#if USE_SWAP
ATA_Command(0);
#else
*(volatile unsigned *)ATA_COMMAND = 3; //CONTINUE
#endif
return TRUE;
}
bool StartReading(U32 uStBlock, U32 uBlocks, U32 uBufAddr)
{
//Track Buffer 1 Setting
Outp32(ATA_TBUF_START, uBufAddr);
Outp32(ATA_TBUF_SIZE, uBlocks*ATA_SECTORSIZE);
//Outp32(ATA_XFR_NUM, (uBlocks)*ATA_SECTORSIZE);
Outp32(ATA_XFR_NUM, (uBlocks+4)*ATA_SECTORSIZE);
SetAtaDevice(uStBlock, uBlocks);
WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);
WaitForDeviceReady();
SetConfigMode(eMode, FALSE);
SetTransferCommand(ATA_CMD_START); //START
//*(volatile unsigned *)ATA_COMMAND = 2; //abort
WaitForHostReady(); /// needed
#if USE_SWAP
ATA_Command(0);
#else
*(volatile unsigned *)ATA_COMMAND = 0; //STOP
#endif
WaitForHostReady(); /// needed
#if USE_SWAP
ATA_Command(0);
#else
*(volatile unsigned *)ATA_COMMAND = 3; //CONTINUE
#endif
return TRUE;
}
///////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -