📄 ide.c
字号:
{
// TODO:
// AtapiSetInfo();
} else
{
//
// Set Multiple Mode if ATA Device
//
m_bSectorsPerBlock= 1;
}
// m_fLBAMode = (m_Id.Capabilities & 0x0200) ? TRUE : FALSE;
// m_fLBAMode = TRUE;
// if (!(m_Id.GeneralConfiguration & 0x8000)) {
if (!IsAtapiDevice())
{
// m_bReadCommand = ATA_CMD_READ ;
// m_bWriteCommand = ATA_CMD_WRITE ;
if (m_Id.MaximumBlockTransfer != 0)
{
SelectDevice();
WriteSectorCount( (BYTE)m_Id.MaximumBlockTransfer) ;
WriteCommand(ATA_CMD_SET_MULTIPLE);
if (!WaitOnBusy(FALSE) && (GetAltStatus() & ATA_STATUS_READY))
{
// m_bReadCommand = ATA_CMD_MULTIPLE_READ ;
// m_bWriteCommand = ATA_CMD_MULTIPLE_WRITE ;
m_bSectorsPerBlock = m_Id.MaximumBlockTransfer;
}
}
//DEBUGMSG( ZONE_INIT, (TEXT("ATAPI: Idenitfy - MultipleMode Set to= %ld Sectors\r\n"),m_Id.MaximumBlockTransfer));
}
//DEBUGMSG( ZONE_INIT, (TEXT("ATAPI:Identify Completed Stage 2 Status=%02X\r\n"),GetAltStatus()));
return(0);
}
BOOL WaitForDRQ()
{
DWORD i,j;
BYTE bStatus;
for (i=0; i< DEFAULT_WAIT_CHECK_ITER; i++)
{
for (j=0; j<DEFAULT_WAIT_SAMPLE_TIMES; j++) {
bStatus = GetAltStatus() & (ATA_STATUS_BUSY|ATA_STATUS_DATA_REQ);
if (bStatus & ATA_STATUS_BUSY) {
continue;
}
if (bStatus & ATA_STATUS_DATA_REQ){
// DEBUGMSG(ZONE_IO, (TEXT("ATAPI: ATA_STATUS_DATA_REQ J=: %x \r\n"),j));
return TRUE;
}
DelayInuSec(DEFAULT_WAIT_STALL_TIME);
}
// DEBUGMSG( ZONE_WARNING, (TEXT("ATAPI:WaitForDRQ Status=%02X Error=%02X Reason=%02X\r\n"), GetAltStatus(), GetError(), GetReason()));
}
//RetailPrint1("ATAPIPCI: ATA_STATUS_DATA_REQ (Sleep)i= %x \r\n",i);
return(bStatus == ATA_STATUS_DATA_REQ);
}
BYTE BIOS_ReadSectors(UCHAR Drive, ULONG dwStartSector, UCHAR nSectors, PUCHAR pBuffer)
{
DWORD dwSectorsToTransfer, dwSectorsPerBlock, dwBytesPerBlock;
volatile ULONG ulIdeCtrl;
SelectDevice();
if (WaitOnBusy(FALSE) & ATA_STATUS_BUSY)
{
return -1;
}
GetBaseStatus();
ulIdeCtrl = *IDE_CTRL;
WriteSectorCount((BYTE)nSectors);
// SERPRINT( "BIOS_ReadSectors dwStartSector = %d.\r\n",dwStartSector);
if (m_fLBAMode == TRUE)
{
WriteSectorNumber( (BYTE)dwStartSector);
WriteLowCount((BYTE)(dwStartSector >> 8));
WriteHighCount((BYTE)(dwStartSector >> 16));
WriteDriveHeadReg((BYTE)((dwStartSector >> 24) | ATA_HEAD_LBA_MODE) | ((m_dwDevice == 0 ) ? ATA_HEAD_DRIVE_1 : ATA_HEAD_DRIVE_2));
} else
{ // translate LBA to CHS format
DWORD dwSectors = m_Id.CurrentSectorsPerTrack;
DWORD dwHeads = m_Id.NumberOfCurrentHeads;
WriteSectorNumber((BYTE)((dwStartSector % dwSectors) + 1));
WriteLowCount((BYTE) (dwStartSector /(dwSectors*dwHeads)));
WriteHighCount((BYTE)((dwStartSector /(dwSectors*dwHeads)) >> 8));
WriteDriveHeadReg((BYTE)(((dwStartSector/dwSectors)% dwHeads) | ((m_dwDevice == 0 ) ? ATA_HEAD_DRIVE_1 : ATA_HEAD_DRIVE_2)));
}
if(nSectors>1)
WriteCommand(ATA_CMD_MULTIPLE_READ);
else
WriteCommand(ATA_CMD_READ);
if (!WaitForDRQ())
{
//DEBUGMSG( ZONE_IO, (TEXT("ATAPI:ReadWrite- WaitforDRQ failed \r\n")));
return -1;
}
dwSectorsPerBlock = m_bSectorsPerBlock;
dwSectorsToTransfer = nSectors;
while(dwSectorsToTransfer)
{
if (dwSectorsPerBlock > dwSectorsToTransfer)
{
dwSectorsPerBlock = dwSectorsToTransfer;
}
dwSectorsToTransfer -= dwSectorsPerBlock;
if (!WaitForDRQ())
{
//DEBUGMSG( ZONE_IO, (TEXT("ATAPI:ReadWrite- WaitforDRQ failed \r\n")));
break;
}
dwBytesPerBlock = dwSectorsPerBlock * BYTES_PER_SECTOR;
if (m_f16Bit)
{
ReadWordBuffer( (PWORD)pBuffer, dwBytesPerBlock/2);
}
else
{
ReadByteBuffer( (PBYTE)pBuffer, dwBytesPerBlock);
}
pBuffer += dwBytesPerBlock;
}
return 0;
}
int init_ide(void)
{
//
// Get drive geometry info - needed for LBA -> P-CHS convertion
//
// SERPRINT("init_ide\r\n");
if (id_drive())
return(-1);
return(0);
}
BOOL OEMHDDPlatformInit(VOID)
{
// For now, the RTL8139 product NIC driver requires an ILR in the PCI
// config space header otherwise it isn't able to get interrupts...
//
//InitNIC();
// SERPRINT("OEMHDDPlatformInit\r\n");
return(TRUE);
}
BOOL getfirstpartitionlba(PULONG pFirstPartitionLBA)
{
ULONG uFirstPartitionLBA;
UCHAR bFirstPartitionType;
UCHAR bsect[SECTOR_SIZE];
// SERPRINT("getfirstpartitionlba\r\n");
memset (&bsect[0], 0, SECTOR_SIZE);
if (FALSE == ReadSectors( g_FATParms.DriveId, 0, 1, (PUCHAR) &bsect[0] ) )
{
// SERPRINT( "ERROR: Couldn't read MBR.\r\n" );
return(-1);
}
// EdbgDumpHexBuf((PUCHAR)&bsect[0],SECTOR_SIZE);
//
// Check to make sure that it is a valid boot sector or bios parameter block.
//
if(bsect[0x1FE] != 0x55 && bsect[0x1FF] != 0xAA)
{
SERPRINT("No MBR or BPB found.\r\n");
return -1;
}
//
// Check to see if the first sector is the Bios paramter block like
// floppies
//
if(bsect[0] == 0xEB)
{
// SERPRINT("OEM_Identifier - %s\r\n", (char *)(bsect + 3));
// SERPRINT("BigNumberOfSectors - 0x%x\r\n", (ULONG)(bsect + 0x20));
*pFirstPartitionLBA = 0;
return 0;
}
bFirstPartitionType= *((PUCHAR)&bsect[0x1C2]);
uFirstPartitionLBA = *((PULONG)&bsect[0x1C6]);
// SERPRINT("bFirstPartitionType = 0x%x\r\n",(ULONG)bFirstPartitionType);
// SERPRINT("uFirstPartitionLBA = 0x%x\r\n", (ULONG)uFirstPartitionLBA);
// SERPRINT("0x%x - State of partition. 00 not active, 80h active\r\n", (ULONG)bsect[0x1BE]);
// SERPRINT("0x%x - Head where partiton Starts\r\n",(ULONG)bsect[0x1BF]);
// SERPRINT("0x%x - Sector and cylinder where the partition starts\r\n",(ULONG)*(USHORT *)(bsect + 0x1C0));
// SERPRINT("0x%x - Partition Type\r\n",(ULONG)bsect[0x1C2]);
// SERPRINT("0x%x - Head where the partition ends.\r\n",(ULONG)bsect[0x1C3]);
// SERPRINT("0x%x - Sector and cylinder where the partition ends.\r\n",(ULONG)*(USHORT *)(bsect + 0x1C4));
// SERPRINT("0x%x - Distance, in sectors to the first sector of the partition.\r\n",*(ULONG *)(bsect + 0x1C6));
// SERPRINT("0x%x - Number of sectors in the partition.\r\n",*(ULONG * )(bsect + 0x1CC));
if( bFirstPartitionType==0x05 || // EXTENDED
bFirstPartitionType==0x0F || // WIN95 EXTENDED
bFirstPartitionType==0x85 // LINUX EXTENDED
)
{
//
// If first partition is a extended partition.
// Try to find the first logic partition.
//
memset (&bsect[0], 0, SECTOR_SIZE);
if (FALSE == ReadSectors( g_FATParms.DriveId, uFirstPartitionLBA, 1, (PUCHAR) &bsect[0] ) )
{
// SERPRINT( "ERROR: Couldn't read BOOT in FAT.\r\n" );
return(-1);
}
// EdbgDumpHexBuf((PUCHAR)&bsect[0],SECTOR_SIZE);
bFirstPartitionType= *((PUCHAR)&bsect[0x1C2]);;
uFirstPartitionLBA += *((PULONG)&bsect[0x1C6]);
}
if( bFirstPartitionType==0x01 || // FAT32
bFirstPartitionType==0x04 || // FAT16 <32M
bFirstPartitionType==0x06 || // FAT16
bFirstPartitionType==0x0B || // WIN95 FAT32
bFirstPartitionType==0x0C || // WIN95 FAT32
bFirstPartitionType==0x0E || // WIN95 FAT16
bFirstPartitionType==0x11 || // HIDDEN FAT12
bFirstPartitionType==0x14 || // HIDDEN FAT16
bFirstPartitionType==0x1B || // HIDDEN FAT32
bFirstPartitionType==0x1C || // HIDDEN FAT32
bFirstPartitionType==0x1E || // HIDDEN LBA VFAT
bFirstPartitionType==0x83 // LINUX
)
{
*pFirstPartitionLBA = uFirstPartitionLBA;
return 0;
}
// SERPRINT("FAT Partition not found.\r\n");
return -1;
}
DWORD OEMHDDPreDownload(VOID)
{
return(BL_DOWNLOAD);
}
DWORD OEMHDDImageCheck(VOID)
{
ULONG uFirstPartitionLBA;
UCHAR pName[] = KIMAGE_NAME;
// SERPRINT("OEMHDDImageCheck.\r\n");
//
g_bstartcounting = 0;
g_sectorsread = 0;
if( m_BootDeviceType == BOOT_FROM_PCMCIA)
{
// SERPRINT("OEMHDDImageCheck: BOOT_FROM_PCMCIA.\r\n");
//
// Select Operation Mode Of CF Card to 16 bit I/O Mapped Mode.
//
*CF_CONFIG = CONFIG_LEVIRQ | 1;
SelectDevice();
ide_reset();
if (init_ide())
{
// SERPRINT("ERROR: IDE device initialization failed.\r\n");
return(-1);
}
}
else
{
ide_reset();
}
if(getfirstpartitionlba(&uFirstPartitionLBA)==-1)
{
return(-1);
}
// Initialize FAT structs
if (!InitFAT(uFirstPartitionLBA))
{
// SERPRINT("ERROR: FAT initialization failed.\r\n");
return(-1);
}
// SERPRINT("Looking for NK.bin in root directory.\r\n");
// Open image (finds starting LBA and size - inits structs for later ops)
// Only read is supported
if (0 == OpenFile( (PCHAR)pName))
{
// SERPRINT("Warning: No BIN file found in root of drive.\r\n");
return(-1);
}
// Display status bar
//create_statusbar(&g_statbar, 0, (g_fileinfo.fsize / SECTOR_SIZE) - 1);
g_bstartcounting = 1;
return(0);
}
BOOL OEMHDDReadData(
DWORD cbData,
LPBYTE pbData
)
{
BOOL stat=0;
stat = lReadFile((unsigned char *)pbData, cbData);
if (stat == FALSE)
{
SERPRINT("ERROR: lReadFile failed in OEMHDDReadData.\r\n");
return(FALSE);
}
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -