biosint13.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 1,444 行 · 第 1/4 页
C
1,444 行
/*++
Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
BiosInt13.c
Abstract:
Routines that use BIOS to support INT 13 devices.
Revision History
--*/
#include "BiosDriver.h"
INTN
PrintBlkIO (
BIOS_BLK_IO_DEV *Dev
);
EFI_STATUS
BiosBlkIoReset (
IN EFI_BLOCK_IO *This,
IN BOOLEAN ExtendedVerification
);
EFI_STATUS
BiosBlkIoReadBlocks (
IN EFI_BLOCK_IO *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
BiosBlkIoWriteBlocks (
IN EFI_BLOCK_IO *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
OUT VOID *Buffer
);
EFI_STATUS
BiosBlkIoFlushBlocks (
IN EFI_BLOCK_IO *This
);
STATIC UINTN
Int13GetDeviceParameters (
IN BIOS_LEGACY_DRIVE *Drive
);
STATIC UINTN
Int13Extensions(
IN BIOS_LEGACY_DRIVE *Drive
);
STATIC UINTN
GetDriveParameters(
IN BIOS_LEGACY_DRIVE *Drive
);
VOID
PrintOnDriveAccess (
IN EFI_BLOCK_IO *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
OUT VOID *Buffer,
IN CHAR16 *TypeString
);
//
// Address packet is a buffer under 1 MB for all version EDD calls
//
extern EDD_DEVICE_ADDRESS_PACKET *GlobalEDDBufferUnder1MB;
//
// This is a buffer for INT 13h func 48 information
//
extern BIOS_LEGACY_DRIVE *GlobalLegacyDriverUnder1MB;
//
// Buffer of 0xFE00 bytes for EDD 1.1 transfer must be under 1 MB
// 0xFE00 bytes is the max transfer size supported.
//
extern VOID *GlobalEDD11Buffer;
//
// Global Io Functions
//
extern EFI_DEVICE_IO_INTERFACE *GlobalIoFncs;
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
UINTN
BiosGetNumberOfDiskettes (
VOID
)
{
UINT8 NumberOfDrives;
#ifdef SOFT_SDV
NumberOfDrives = 0;
return NumberOfDrives;
#endif
//
// Read BIOS Data Area for Info
//
NumberOfDrives = *(UINT8 *)0x410;
return (UINTN)(((NumberOfDrives >> 6) & 0x03) + 1);
}
UINTN
BiosGetNumberOfHardDrives (
VOID
)
{
UINTN NumberOfDrives;
//
// Return the number of drives from the BIOS data area
//
NumberOfDrives = (*(UINT8 *)0x0475);
return NumberOfDrives;
}
BOOLEAN
BiosInitBlkIo (
IN BIOS_BLK_IO_DEV *Dev
)
{
EFI_BLOCK_IO *BlkIo;
EFI_BLOCK_IO_MEDIA *BlkMedia;
BIOS_LEGACY_DRIVE *Bios;
BlkIo = &Dev->BlkIo;
BlkIo->Media = &Dev->BlkMedia;
BlkMedia = BlkIo->Media;
Bios = &Dev->Bios;
if (Int13GetDeviceParameters (Bios)) {
if (Int13Extensions (Bios)) {
BlkMedia->LastBlock = (EFI_LBA)Bios->Parameters.PhysicalSectors - 1;
BlkMedia->BlockSize = (UINT32)Bios->Parameters.BytesPerSector;
if ((Bios->Parameters.Flags & EDD_DEVICE_REMOVABLE) == EDD_DEVICE_REMOVABLE) {
BlkMedia->RemovableMedia = TRUE;
}
} else {
//
// Legacy Interfaces
//
BlkMedia->BlockSize = 512;
BlkMedia->LastBlock = (Bios->MaxHead + 1) * Bios->MaxSector * (Bios->MaxCylinder + 1) - 1;
}
DEBUG ((D_INIT, "BlockSize = %d LastBlock = %d\n",BlkMedia->BlockSize,BlkMedia->LastBlock));
BlkMedia->LogicalPartition = FALSE;
BlkMedia->WriteCaching = FALSE;
//
// BugBug: Need to set this for removable media devices if they do not
// have media present
//
BlkMedia->ReadOnly = FALSE;
BlkMedia->MediaPresent = TRUE;
BlkIo->Reset = BiosBlkIoReset;
BlkIo->FlushBlocks = BiosBlkIoFlushBlocks;
if (!Bios->ExtendedInt13) {
//
// Legacy interfaces
//
BlkIo->ReadBlocks = BiosReadLegacyDrive;
BlkIo->WriteBlocks = BiosWriteLegacyDrive;
} else if ((Bios->EDDVersion == EDD_VERSION_30) && (Bios->Extensions64Bit)) {
//
// EDD 3.0 Required for Device path, but extended reads are not required.
//
BlkIo->ReadBlocks = EDD30BiosReadBlocks;
BlkIo->WriteBlocks = EDD30BiosWriteBlocks;
} else {
//
// Assume EDD 1.1 - Read and Write functions.
// This could be EDD 3.0 without Extensions64Bit being set.
// If it's EDD 1.1 this will work, but the device path will not
// be correct. This will cause confusion to EFI OS installation.
//
// ASSERT (Bios->EDD);
BlkIo->ReadBlocks = EDD11BiosReadBlocks;
BlkIo->WriteBlocks = EDD11BiosWriteBlocks;
}
BlkMedia->LogicalPartition = FALSE;
BlkMedia->WriteCaching = FALSE;
return TRUE;
}
return FALSE;
}
#if EFI_DEBUG
INTN
PrintBlkIO (
BIOS_BLK_IO_DEV *Dev
)
{
BIOS_LEGACY_DRIVE *Bios;
BOOLEAN Valid = FALSE;
Bios = &Dev->Bios;
Print (L"\n\n Letter %c Number %x EDD Version %x\n", Bios->Letter, Bios->Number, Bios->EDDVersion);
Print (L" Block Size = %X\n", Dev->BlkIo.Media->BlockSize);
if (Bios->ExtendedInt13) {
Print (L"XINT13 ");
}
if (Bios->DriveLockingAndEjecting) {
Print (L"EJECT ");
}
if (Bios->EDD) {
Print (L"EDD ");
}
if (Bios->Floppy) {
Print (L"Floppy ");
}
if (Bios->ParametersValid) {
Print (L"Valid ");
Valid = TRUE;
}
Print (L"\n");
if (Valid) {
Print (L" Sector Size %x", Bios->Parameters.BytesPerSector);
Print (L" Size %lx", Bios->Parameters.PhysicalSectors);
Print (L" Struct Size %x \n", Bios->Parameters.StructureSize);
}
return 0;
}
#endif
VOID
PrintOnDriveAccess (
IN EFI_BLOCK_IO *This,
IN UINT32 MediaId,
IN EFI_LBA LBA,
IN UINTN BufferSize,
OUT VOID *Buffer,
IN CHAR16 *TypeString
)
{
Print (L"BlkIo %s LBA %lx MediaID %x Size %x", TypeString, LBA, MediaId, BufferSize);
}
STATIC UINTN
Int13GetDeviceParameters (
IN BIOS_LEGACY_DRIVE *Drive
)
{
UINTN CarryFlag;
UINT16 Cylinder;
IA32_RegisterSet_t Regs;
Regs.h.AH = 0x08;
Regs.h.DL = Drive->Number;
CarryFlag = Int86(0x13, &Regs);
DEBUG ((D_INIT, "Int13GetDeviceParameters: INT 13 08 DL=%02x : CF=%d AH=%02x\n",Drive->Number,CarryFlag,Regs.h.AH));
if (CarryFlag || Regs.h.AH != 0x00) {
Drive->ErrorCode = Regs.h.AH;
return FALSE;
}
if (Drive->Floppy) {
if (Regs.h.BL == 0x10) {
Drive->ATAPI_Floppy = TRUE;
} else {
Drive->MaxHead = Regs.h.DH;
Drive->MaxSector = Regs.h.CL;
Drive->MaxCylinder = Regs.h.CH;
if (Drive->MaxSector == 0) {
//
// BugBug: You can not trust the Carry flag.
//
return FALSE;
}
}
} else {
Drive->MaxHead = Regs.h.DH & 0x3f;
Cylinder = ((UINT16)Regs.h.DH & 0xc0) << 4;
Cylinder |= ((UINT16)Regs.h.CL & 0xc0) << 2;
Drive->MaxCylinder = Cylinder + Regs.h.CH;
Drive->MaxSector = Regs.h.CL & 0x3f;
}
return TRUE;
}
STATIC UINTN
Int13Extensions(
IN BIOS_LEGACY_DRIVE *Drive
)
{
INTN CarryFlag;
IA32_RegisterSet_t Regs;
Regs.h.AH = 0x41;
Regs.x.BX = 0x55aa;
Regs.h.DL = Drive->Number;
CarryFlag = Int86(0x13, &Regs);
DEBUG ((D_INIT, "Int13Extensions: INT 13 41 DL=%02x : CF=%d BX=%04x\n",Drive->Number,CarryFlag,Regs.x.BX));
if (CarryFlag || Regs.x.BX != 0xaa55) {
Drive->ExtendedInt13 = FALSE;
Drive->DriveLockingAndEjecting = FALSE;
Drive->EDD = FALSE;
return(FALSE);
}
Drive->EDDVersion = Regs.h.AH;
Drive->ExtendedInt13 = (BOOLEAN)((Regs.x.CX & 0x01) == 0x01);
Drive->DriveLockingAndEjecting = (BOOLEAN)((Regs.x.CX & 0x02) == 0x02);
Drive->EDD = (BOOLEAN)((Regs.x.CX & 0x04) == 0x04);
Drive->Extensions64Bit = (BOOLEAN)(Regs.x.CX & 0x08);
Drive->ParametersValid = (UINT8)GetDriveParameters(Drive);
return Drive->ParametersValid;
}
STATIC UINTN
GetDriveParameters(
IN BIOS_LEGACY_DRIVE *Drive
)
{
INTN CarryFlag;
IA32_RegisterSet_t Regs;
UINTN PointerMath;
Regs.h.AH = 0x48;
Regs.h.DL = Drive->Number;
//
// EDD Buffer must be passed in with max buffer size as first entry in the buffer
//
GlobalLegacyDriverUnder1MB->Parameters.StructureSize = sizeof(EDD_DRIVE_PARAMETERS);
Regs.x.DS = _FP_SEG (&GlobalLegacyDriverUnder1MB->Parameters);
Regs.x.SI = _FP_OFF (&GlobalLegacyDriverUnder1MB->Parameters);
CarryFlag = Int86(0x13, &Regs);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?