📄 ideutils.c
字号:
return 0;
}
#if MULTIPLE_SECTOR_WRITE
pusBuffer = (unsigned short*)malloc(256 * gusSectorsPerTrack * sizeof(unsigned short));
if (!pusBuffer)
{
printf("multiWrite: memory allocation failure.\n");
return 0;
}
#endif // MULTIPLE_SECTOR_WRITE
printf("writing %d sectors on device 0. Hit any key to abort.\r",
iNumSectorsToWrite);
// Flush input buffer.
#if 0
while (-1 != nr_uart_rxchar(0)) {}
#else
getchar();
#endif
uiStartTime = getTime();
// Write forever (up to the number of sectors requested, or keypress).
while (1)
{
for (iCylinder = 0; iCylinder < gusLogicalCylinders; ++iCylinder)
{
for (iHead = 0; iHead < gusLogicalHeads; ++iHead)
{
// Do this checking here, rather than on a sector-by-sector basis, to
// boost performance.
#if 0
if (-1 != nr_uart_rxchar(0))
#else
getchar();
#endif
{
goto computeStats;
}
#if MULTIPLE_SECTOR_WRITE
// Done yet?
if (iNumSectorsWritten >= iNumSectorsToWrite)
{
goto computeStats;
}
randomizeBuffer(gusSectorsPerTrack, pusBuffer);
iResult = writeSectorsCHS(0, iCylinder, iHead, 1, gusSectorsPerTrack, pusBuffer);
if (!iResult)
{
printf("(0, %d, %d, %d, %d) failed.\r",
iCylinder, iHead, iSectorNumber, gusSectorsPerTrack);
}
else
{
iNumSectorsWritten += gusSectorsPerTrack;
if (gbVerbose)
{
printf("(0, %d, %d, %d, %d) succeeded.\r",
iCylinder, iHead, iSectorNumber, gusSectorsPerTrack);
printSectorBuffer(gusSectorsPerTrack, pusBuffer);
}
}
#else // !MULTIPLE_SECTOR_WRITE
for (iSectorNumber = 1; iSectorNumber <= gusSectorsPerTrack; ++iSectorNumber)
{
// Done yet?
if (iNumSectorsWritten >= iNumSectorsToWrite)
{
goto computeStats;
}
randomizeBuffer(1, usBuffer);
iResult = writeSectorsCHS(0, iCylinder, iHead, iSectorNumber, 1, usBuffer);
if (!iResult)
{
printf("(0, %d, %d, %d, 1) failed.\r",
iCylinder, iHead, iSectorNumber);
}
else
{
iNumSectorsWritten++;
if (gbVerbose)
{
printf("(0, %d, %d, %d, 1) succeeded.\r",
iCylinder, iHead, iSectorNumber);
printSectorBuffer(1, usBuffer);
}
}
}
#endif // MULTIPLE_SECTOR_WRITE
}
}
}
computeStats:
#if MULTIPLE_SECTOR_WRITE
if (pusBuffer)
{
free(pusBuffer);
pusBuffer = 0;
}
#endif // MULTIPLE_SECTOR_WRITE
uiDeltaTime = getTime() - uiStartTime;
printf("%d sectors written in %d.%d s\r",
iNumSectorsWritten, uiDeltaTime / 1000, uiDeltaTime % 1000);
printf("at 512 bytes/sector, that's %d bytes/second\r\r",
(int)(iNumSectorsWritten * 512. * 1000 / uiDeltaTime));
return 1;
}
int writeCHS(char *szArg)
{
int i;
int iCylinder, iHead, iSector;
unsigned short usBuffer[256];
if (3 != sscanf(szArg, "%d %d %d\r", &iCylinder, &iHead, &iSector))
{
printf("writeCHS: arg '%s' makes no sense.\r", szArg);
return 0;
}
// Make some random data, for now.
for (i = 0; i < sizeof(usBuffer) / sizeof(*usBuffer); ++i)
{
usBuffer[i] = (rand() & 0xFFFF00) >> 8;
}
printf("writeCHS: cylinder: %d; head; %d; sector: %d\r",
iCylinder, iHead, iSector);
if (!writeSectorsCHS(0, iCylinder, iHead, iSector, 1, usBuffer))
{
printf("writeCHS() failed.\r");
return 0;
}
if (gbVerbose)
{
printSectorBuffer(1, usBuffer);
}
return 1;
}
int readCHS(char *szArg)
{
int iCylinder, iHead, iSector;
unsigned short usBuffer[256];
if (3 != sscanf(szArg, "%d %d %d\r", &iCylinder, &iHead, &iSector))
{
printf("readCHS: arg '%s' makes no sense.\r", szArg);
return 0;
}
printf("readCHS: cylinder: %d; head; %d; sector: %d\r",
iCylinder, iHead, iSector);
if (!readSectorsCHS(0, iCylinder, iHead, iSector, 1, usBuffer))
{
printf("readCHS() failed.\r");
return 0;
}
if (gbVerbose)
{
printSectorBuffer(1, usBuffer);
}
return 1;
}
int LBA2CHS(int iLBA, int *piC, int *piH, int *piS)
{
// CHS addressing should be interpreted as:
// cylinder: most-significant part (changes slowest)
// head : next-most-significant part
// sector : least-significant part (changes fastest)
// Some IDE drives do their own LBA translation, but not the
// old ones. If an IDE drive supports LBA translation, then
// the CHS parameters of a read- or write-sector commands are
// interpreted differently by the drive itself, if LBA mode is
// enabled (bit 6 of the Device/Head register = 1).
// For now, assume no LBA support in the drive. Build our own,
// instead. It would be more clever to use LBA support if present
// in the drive, and use our own translation if necessary.
// The equation:
// LBA(C, H, S) = S - 1 + ((C * nHeads + H) * nSectorsPerTrack)
// (Note the implicit dependence on drive parameters nHeads (gusLogicalHeads)
// and nSectorsPerTrack (gusSectorsPerTrack).)
// So
// S = 1 + LBA % nSectorsPerTrack
// H = ((LBA) idiv nSectorsPerTrack) % nHeads
// C = ((LBA idiv nSectorsPerTrack) idiv nHeads
int iTmp;
if (!piS || !piH || !piC || !gusLogicalHeads || !gusSectorsPerTrack)
{
printf("bogus values in LBA2CHS()\r");
return 0;
}
*piS = 1 + iLBA % gusSectorsPerTrack;
iTmp = iLBA / gusSectorsPerTrack;
*piH = iTmp % gusLogicalHeads;
*piC = iTmp / gusLogicalHeads;
return 1;
}
int testLBA2CHS(char *szArg)
{
int iC, iH, iS, iLBA;
if (1 != sscanf(szArg, "%d", &iLBA))
{
printf("testLBA2CHS: arg '%s' makes no sense.\r", szArg);
return 0;
}
LBA2CHS(iLBA, &iC, &iH, &iS);
printf("LBA: %d;\r\tC: %d; H: %d; S: %d\r",
iLBA, iC, iH, iS);
return 1;
}
int writeLogicalSector(unsigned long ulLBA, unsigned long ulNumSectors, unsigned short *pusBuffer)
{
int iC, iH, iS;
if (gusLBAmode)
{
// check LBA range
if ((ulLBA + ulNumSectors) > gulLBAcapacity)
{
// Fatal error.
return 0;
}
// Write the sector.
if (!writeSectorsLBA(0, ulLBA, ulNumSectors, pusBuffer))
{
// Non-fatal error.
printf("writeSectorsLBA() failed.\r");
return 0;
}
}
else
{
// Translate the logical address to CHS.
if (!LBA2CHS(ulLBA, &iC, &iH, &iS))
{
// Fatal error.
return 0;
}
// Write the sector.
if (!writeSectorsCHS(0, iC, iH, iS, ulNumSectors, pusBuffer))
{
// Non-fatal error.
printf("writeSectorsCHS() failed.\r");
return 0;
}
}
return 1;
}
int readLogicalSector(unsigned long ulLBA, unsigned long ulNumSectors, unsigned short *pusBuffer)
{
int iC, iH, iS;
if (gusLBAmode)
{
// check LBA range
if ((ulLBA + ulNumSectors) > gulLBAcapacity)
{
// Fatal error.
return 0;
}
// Read the sector.
if (!readSectorsLBA(0, ulLBA, ulNumSectors, pusBuffer))
{
// Non-fatal error.
printf("readSectorsLBA() failed.\r");
return 0;
}
}
else
{
// Translate the logical address to CHS.
if (!LBA2CHS(ulLBA, &iC, &iH, &iS))
{
// Fatal error.
return 0;
}
// Request the sector.
if (!readSectorsCHS(0, iC, iH, iS, ulNumSectors, pusBuffer))
{
// Non-fatal error.
printf("readSectorsCHS() failed.\r");
return 0;
}
}
return 1;
}
int writeLBA(char *szArg)
{
unsigned long ulLBA, ulNumSectors;
unsigned short *pusBuffer;
int iRet;
if (2 != sscanf(szArg, "%lu %lu", &ulLBA, &ulNumSectors))
{
printf("writeLBA: arg '%s' makes no sense.\r", szArg);
return 0;
}
// Allocate the buffer.
pusBuffer = (unsigned short*)malloc(sizeof(unsigned short) * ulNumSectors * 256);
if (0 == pusBuffer)
{
printf("writeLBA: memory allocation failure.\r");
return 0;
}
randomizeBuffer(ulNumSectors, pusBuffer);
iRet = writeLogicalSector(ulLBA, ulNumSectors, pusBuffer);
if (gbVerbose)
{
printSectorBuffer(1, pusBuffer);
}
if (pusBuffer)
{
free(pusBuffer);
pusBuffer = 0;
}
return iRet;
}
int readLBA(char *szArg)
{
unsigned long ulLBA, ulNumSectors;
unsigned short *pusBuffer;
int iRet = 1;
if (2 != sscanf(szArg, "%lu %lu", &ulLBA, &ulNumSectors))
{
printf("readLBA: arg '%s' makes no sense.\r", szArg);
return 0;
}
// Allocate the buffer.
pusBuffer = (unsigned short*)malloc(256 * sizeof(unsigned short) * ulNumSectors);
if (!pusBuffer)
{
printf("readLBA:memory allocation failure.\r");
return 0;
}
iRet = readLogicalSector(ulLBA, ulNumSectors, pusBuffer);
if (!iRet)
{
printf("readLBA() failed.\r");
}
else
{
if (gbVerbose)
{
printSectorBuffer(ulNumSectors, pusBuffer);
}
}
if (pusBuffer)
{
free(pusBuffer);
pusBuffer = 0;
}
return iRet;
}
int hexNibbleToInt(unsigned char ucNibble)
{
ucNibble -= '0';
if (ucNibble > 10)
{
ucNibble &= ~0x20; // Convert to upper case.
ucNibble -= 'A' - '0' - 10; // Subtract out letterness less digitness.
}
return 0xF & ucNibble;
}
int IDE_initialize(void)
{
IDE_setVerbosity(0);
alt_avalon_ide_cf_init( ctl_base );
#if 1
{
// Register test:
unsigned char ucWrite;
unsigned char ucRead;
int iGood = 1;
for (ucWrite = 0; ucWrite < 10; ++ucWrite)
{
IOWR_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base, ucWrite);
// usleep(100000); // 0.1 sec
ucRead = IORD_ALTERA_AVALON_CF_IDE_SECTOR_NUMBER(ide_base);
if (ucWrite != ucRead)
{
iGood = 0;
printf("verify fail: wrote 0x%X, read 0x%X\n", ucWrite, ucRead);
}
}
if (iGood)
{
// printf("wrote and verified %d values successfully.\n", ucWrite);
}
else
{
printf("ERROR: Failed to connect with Compact Flash card.\n");
printf(" Did you remember to insert or re-insert the card?\n");
return ( 0 );
}
}
#endif
// enable insert detect interrupt
alt_irq_register(ctl_irq, 0, CTLTrapHandler);
IOWR_ALTERA_AVALON_CF_CTL_CONTROL(ctl_base, ALTERA_AVALON_CF_CTL_STATUS_POWER_MSK
+ ALTERA_AVALON_CF_CTL_STATUS_IRQ_EN_MSK);
// enable IDE interrupts
alt_irq_register(ide_irq, 0, IDETrapHandler);
IOWR_ALTERA_AVALON_CF_IDE_CTL(ctl_base, ALTERA_AVALON_CF_IDE_CTL_IRQ_EN_MSK);
if (!IDE_identifyDevice(0))
{
return 0;
}
IDE_initializeDeviceParameters(0, getLogicalHeads(),
getLogicalCylinders(), getSectorsPerTrack());
return 1;
}
int IDE_deinitialize(void)
{
// Turn off the IDE controller, disable interrupts
IOWR_ALTERA_AVALON_CF_CTL_CONTROL(ctl_base, 0);
IOWR_ALTERA_AVALON_CF_IDE_CTL(ctl_base, 0);
alt_irq_register(ide_irq, 0, 0);
alt_irq_register(ctl_irq, 0, 0);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -