isafloppyctrl.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,560 行 · 第 1/3 页
C
1,560 行
Command.DiskHeadSel = 0;
//
// 0
//
} else {
Command.DiskHeadSel = 1;
//
// 1
//
}
CommandPointer = (UINT8 *) (&Command);
for (Index = 0; Index < sizeof (FDD_COMMAND_PACKET2); Index++) {
if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {
return EFI_DEVICE_ERROR;
}
}
//
// Experience value
//
gBS->Stall (250000);
//
// need modify according to 1.44M or 2.88M
//
if (EFI_ERROR (SenseIntStatus (FdcDev, &StatusRegister0, &PresentCylinderNumber))) {
return EFI_DEVICE_ERROR;
}
if ((StatusRegister0 & 0xf0) == 0x20 && PresentCylinderNumber == 0) {
FdcDev->PresentCylinderNumber = 0;
FdcDev->ControllerState->NeedRecalibrate = FALSE;
return EFI_SUCCESS;
} else {
Count--;
if (Count == 0) {
return EFI_DEVICE_ERROR;
}
}
}
//
// end while
//
return EFI_SUCCESS;
}
EFI_STATUS
Seek (
IN FDC_BLK_IO_DEV *FdcDev,
IN EFI_LBA Lba
)
/*++
Routine Description: Set the head of floppy drive to the new cylinder
Parameters:
FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
Lba EFI_LBA : The logic block address want to seek
Returns:
EFI_SUCCESS: Execute the Seek operation successfully
EFI_DEVICE_ERROR: Fail to execute the Seek operation
--*/
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: FdcDev - add argument and description to function comment
// GC_TODO: Lba - add argument and description to function comment
{
FDD_SEEK_CMD Command;
UINT8 EndOfTrack;
UINT8 Head;
UINT8 Cylinder;
UINT8 StatusRegister0;
UINT8 *CommandPointer;
UINT8 PresentCylinderNumber;
UINTN Index;
UINT8 DelayTime;
if (FdcDev->ControllerState->NeedRecalibrate) {
if (EFI_ERROR (Recalibrate (FdcDev))) {
FdcDev->ControllerState->NeedRecalibrate = TRUE;
return EFI_DEVICE_ERROR;
}
}
EndOfTrack = DISK_1440K_EOT;
//
// Calculate cylinder based on Lba and EOT
//
Cylinder = (UINT8) ((UINTN) Lba / EndOfTrack / 2);
//
// if the destination cylinder is the present cylinder, unnecessary to do the
// seek operation
//
if (FdcDev->PresentCylinderNumber == Cylinder) {
return EFI_SUCCESS;
}
//
// Calculate the head : 0 or 1
//
Head = (UINT8) ((UINTN) Lba / EndOfTrack % 2);
EfiZeroMem (&Command, sizeof (FDD_SEEK_CMD));
Command.CommandCode = SEEK_CMD;
if (FdcDev->Disk == FDC_DISK0) {
Command.DiskHeadSel = 0;
//
// 0
//
} else {
Command.DiskHeadSel = 1;
//
// 1
//
}
Command.DiskHeadSel |= Head << 2;
Command.NewCylinder = Cylinder;
CommandPointer = (UINT8 *) (&Command);
for (Index = 0; Index < sizeof (FDD_SEEK_CMD); Index++) {
if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {
return EFI_DEVICE_ERROR;
}
}
//
// Io delay
//
gBS->Stall (100);
//
// Calculate waiting time
//
if (FdcDev->PresentCylinderNumber > Cylinder) {
DelayTime = (UINT8) (FdcDev->PresentCylinderNumber - Cylinder);
} else {
DelayTime = (UINT8) (Cylinder - FdcDev->PresentCylinderNumber);
}
gBS->Stall ((DelayTime + 1) * 4000);
if (EFI_ERROR (SenseIntStatus (FdcDev, &StatusRegister0, &PresentCylinderNumber))) {
return EFI_DEVICE_ERROR;
}
if ((StatusRegister0 & 0xf0) == 0x20) {
FdcDev->PresentCylinderNumber = Command.NewCylinder;
return EFI_SUCCESS;
} else {
FdcDev->ControllerState->NeedRecalibrate = TRUE;
return EFI_DEVICE_ERROR;
}
}
EFI_STATUS
SenseIntStatus (
IN FDC_BLK_IO_DEV *FdcDev,
IN OUT UINT8 *StatusRegister0,
IN OUT UINT8 *PresentCylinderNumber
)
/*++
Routine Description: Do the Sense Interrupt Status command, this command
resets the interrupt signal
Parameters:
StatusRegister0 UINT8 *: Be used to save Status Register 0 read from FDC
PresentCylinderNumber UINT8 *: Be used to save present cylinder number
read from FDC
Returns:
EFI_SUCCESS: Execute the Sense Interrupt Status command successfully
EFI_DEVICE_ERROR: Fail to execute the command
--*/
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: FdcDev - add argument and description to function comment
// GC_TODO: StatusRegister0 - add argument and description to function comment
// GC_TODO: PresentCylinderNumber - add argument and description to function comment
{
UINT8 command;
command = SENSE_INT_STATUS_CMD;
if (EFI_ERROR (DataOutByte (FdcDev, &command))) {
return EFI_DEVICE_ERROR;
}
if (EFI_ERROR (DataInByte (FdcDev, StatusRegister0))) {
return EFI_DEVICE_ERROR;
}
if (EFI_ERROR (DataInByte (FdcDev, PresentCylinderNumber))) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
SenseDrvStatus (
IN FDC_BLK_IO_DEV *FdcDev,
IN EFI_LBA Lba
)
/*++
Routine Description: Do the Sense Drive Status command
Parameters:
FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
Lba EFI_LBA : Logic block address
Returns:
EFI_SUCCESS: Execute the Sense Drive Status command successfully
EFI_DEVICE_ERROR: Fail to execute the command
EFI_WRITE_PROTECTED:The disk is write protected
--*/
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: FdcDev - add argument and description to function comment
// GC_TODO: Lba - add argument and description to function comment
{
FDD_COMMAND_PACKET2 Command;
UINT8 Head;
UINT8 EndOfTrack;
UINTN Index;
UINT8 StatusRegister3;
UINT8 *CommandPointer;
//
// Sense Drive Status command obtains drive status information,
// it has not execution phase and goes directly to the result phase from the
// command phase, Status Register 3 contains the drive status information
//
EfiZeroMem (&Command, sizeof (FDD_COMMAND_PACKET2));
Command.CommandCode = SENSE_DRV_STATUS_CMD;
if (FdcDev->Disk == FDC_DISK0) {
Command.DiskHeadSel = 0;
} else {
Command.DiskHeadSel = 1;
}
EndOfTrack = DISK_1440K_EOT;
Head = (UINT8) ((UINTN) Lba / EndOfTrack % 2);
Command.DiskHeadSel |= Head << 2;
CommandPointer = (UINT8 *) (&Command);
for (Index = 0; Index < sizeof (FDD_COMMAND_PACKET2); Index++) {
if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {
return EFI_DEVICE_ERROR;
}
}
if (EFI_ERROR (DataInByte (FdcDev, &StatusRegister3))) {
return EFI_DEVICE_ERROR;
}
//
// Io delay
//
gBS->Stall (50);
//
// Check Status Register 3 to get drive status information
//
return CheckStatus3 (StatusRegister3);
}
EFI_STATUS
DetectMedia (
IN FDC_BLK_IO_DEV *FdcDev
)
/*++
Routine Description: Update the disk media properties and if necessary
reinstall Block I/O interface
Parameters:
FdcDev FDC_BLK_IO_DEV *: A pointer to Data Structure FDC_BLK_IO_DEV
Returns:
EFI_SUCCESS: Do the operation successfully
EFI_DEVICE_ERROR: Fail to the operation
--*/
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: FdcDev - add argument and description to function comment
{
EFI_STATUS Status;
BOOLEAN bReset;
BOOLEAN bReadOnlyLastTime;
BOOLEAN bMediaPresentLastTime;
bReset = FALSE;
bReadOnlyLastTime = FdcDev->BlkIo.Media->ReadOnly;
bMediaPresentLastTime = FdcDev->BlkIo.Media->MediaPresent;
//
// Check disk change
//
Status = DisketChanged (FdcDev);
switch (Status) {
case EFI_MEDIA_CHANGED:
FdcDev->BlkIo.Media->MediaId++;
FdcDev->BlkIo.Media->MediaPresent = TRUE;
bReset = TRUE;
break;
case EFI_NO_MEDIA:
FdcDev->BlkIo.Media->MediaPresent = FALSE;
break;
case EFI_SUCCESS:
break;
default:
MotorOff (FdcDev);
return Status;
//
// EFI_DEVICE_ERROR
//
}
if (FdcDev->BlkIo.Media->MediaPresent) {
//
// Check disk write protected
//
Status = SenseDrvStatus (FdcDev, 0);
if (Status == EFI_WRITE_PROTECTED) {
FdcDev->BlkIo.Media->ReadOnly = TRUE;
} else {
FdcDev->BlkIo.Media->ReadOnly = FALSE;
}
}
if (FdcDev->BlkIo.Media->MediaPresent && (bReadOnlyLastTime != FdcDev->BlkIo.Media->ReadOnly)) {
bReset = TRUE;
}
if (bMediaPresentLastTime != FdcDev->BlkIo.Media->MediaPresent) {
bReset = TRUE;
}
if (bReset) {
Status = gBS->ReinstallProtocolInterface (
FdcDev->Handle,
&gEfiBlockIoProtocolGuid,
&FdcDev->BlkIo,
&FdcDev->BlkIo
);
if (EFI_ERROR (Status)) {
return Status;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
Setup (
IN FDC_BLK_IO_DEV *FdcDev
)
/*++
Routine Description: Set the data rate and so on
Parameters:
None
Returns:
EFI_SUCCESS:
--*/
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: FdcDev - add argument and description to function comment
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
{
EFI_STATUS Status;
//
// Set data rate 500kbs
//
FdcWritePort (FdcDev, FDC_REGISTER_CCR, 0x0);
//
// Io delay
//
gBS->Stall (50);
Status = Specify (FdcDev);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
ReadWriteDataSector (
IN FDC_BLK_IO_DEV *FdcDev,
IN VOID *HostAddress,
IN EFI_LBA Lba,
IN UINTN NumberOfBlocks,
IN BOOLEAN Read
)
/*++
Routine Description: Read or Write a number of blocks in the same cylinder
Parameters:
FdcDev FDC_BLK_IO_DEV * : A pointer to Data Structure FDC_BLK_IO_DEV
Buffer VOID *:
Lba EFI_LBA:
NumberOfBlocks UINTN:
Read BOOLEAN:
Returns:
EFI_SUCCESS:
--*/
// GC_TODO: function comment is missing 'Arguments:'
// GC_TODO: FdcDev - add argument and description to function comment
// GC_TODO: HostAddress - add argument and description to function comment
// GC_TODO: Lba - add argument and description to function comment
// GC_TODO: NumberOfBlocks - add argument and description to function comment
// GC_TODO: Read - add argument and description to function comment
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
// GC_TODO: EFI_TIMEOUT - add return value to function comment
// GC_TODO: EFI_DEVICE_ERROR - add return value to function comment
{
EFI_STATUS Status;
FDD_COMMAND_PACKET1 Command;
FDD_RESULT_PACKET Result;
UINTN Index;
UINTN Times;
UINT8 *CommandPointer;
EFI_PHYSICAL_ADDRESS DeviceAddress;
EFI_INTERFACE_DEFINITION_FOR_ISA_IO *IsaIo;
UINTN NumberofBytes;
VOID *Mapping;
EFI_ISA_IO_PROTOCOL_OPERATION Operation;
VOID *Buffer;
EFI_STATUS Status1;
UINT8 Channel;
EFI_ISA_ACPI_RESOURCE *ResourceItem;
UINT32 Attribute;
Status = Seek (FdcDev, Lba);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
//
// Map Dma
//
IsaIo = FdcDev->IsaIo;
NumberofBytes = NumberOfBlocks * 512;
if (Read == READ) {
Operation = EfiIsaIoOperationSlaveWrite;
} else {
Operation = EfiIsaIoOperationSlaveRead;
}
ResourceItem = IsaIo->ResourceList->ResourceItem;
Index = 0;
while (ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList) {
if (ResourceItem[Index].Type == EfiIsaAcpiResourceDma) {
break;
}
Index++;
}
if (ResourceItem[Index].Type == EfiIsaAcpiResourceEndOfList) {
return EFI_DEVICE_ERROR;
}
Channel = (UINT8) IsaIo->ResourceList->ResourceItem[Index].StartRange;
Attribute = IsaIo->ResourceList->ResourceItem[Index].Attribute;
Status1 = IsaIo->Map (
IsaIo,
Operation,
Channel,
Attribute,
HostAddress,
&NumberofBytes,
&DeviceAddress,
&Mapping
);
if (EFI_ERROR (Status1)) {
return Status1;
}
Buffer = (UINT8 *) (UINTN) DeviceAddress;
//
// Allocate Read or Write command packet
//
EfiZeroMem (&Command, sizeof (FDD_COMMAND_PACKET1));
if (Read == READ) {
Command.CommandCode = READ_DATA_CMD | CMD_MT | CMD_MFM | CMD_SK;
} else {
Command.CommandCode = WRITE_DATA_CMD | CMD_MT | CMD_MFM;
}
FillPara (FdcDev, Lba, &Command);
//
// Write command bytes to FDC
//
CommandPointer = (UINT8 *) (&Command);
for (Index = 0; Index < sizeof (FDD_COMMAND_PACKET1); Index++) {
if (EFI_ERROR (DataOutByte (FdcDev, CommandPointer++))) {
return EFI_DEVICE_ERROR;
}
}
//
// wait for some time
//
Times = (STALL_1_SECOND / 50) + 1;
do {
if ((FdcReadPort (FdcDev, FDC_REGISTER_MSR) & 0xc0) == 0xc0) {
break;
}
gBS->Stall (50);
Times = Times - 1;
} while (Times);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?