Newer
Older
AMI-Aptio-BIOS-Reversed / CsmBlockIo / CsmBlockIo.md
@Ajax Dong Ajax Dong 2 days ago 15 KB Init

CsmBlockIo

Function Table

Address Name Description
CsmAssert
CsmDebugPrint
CsmCheckDebugLevel
CsmMatchGuid
CsmReverseQword
CsmZeroMem
CsmGetCurrentAllocation
CsmLegacyRegionAllocate
CsmBbsTableCopy
CsmBbsTableAllocate
Int13SaveState
Int13RestoreState
Int13GetStatus
Int13ErrorStub
Int13ReadWriteChs
Int13ExtendedRead
Int13ChsReadWrite
Int13ExtendedWrite
DiskInfoIdentify
CsmDiskInfoHandler
CsmBlockIoEntryPoint
CsmBlockIoInitDevice
CsmBlockIoCloseDevice
CsmFindInIplDt
CsmInitInt13Handler
Int13IdentifyDevice
Int13GetDriveParameters
Int13ChsGeometry
BbsDeviceTypeBuilder
Global Data
Protocol GUID definitions (.rdata section)
EFI_GUID gEfiLegacyInterruptProtocolGuid = EFI_LEGACY_INTERRUPT_PROTOCOL_GUID; // 0x3270
0x3250 EFI_GUID gCsmBlockIoInternalGuid = EFI_CSM_BLOCK_IO_INTERNAL_GUID; // 0x3260
0x3280 EFI_GUID gEfiLegacyRegionProtocolGuid = EFI_LEGACY_REGION_PROTOCOL_GUID; // 0x3290
0x32F0 EFI_GUID gEfiLegacyBiosPlatformProtocolGuid = EFI_LEGACY_BIOS_PLATFORM_PROTOCOL_GUID; // 0x3300
0x3310 EFI_GUID gEfiLegacyMbrProtocolGuid = EFI_LEGACY_MBR_PROTOCOL_GUID; // 0x32D0
Protocol GUIDs installed by this driver
EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID; // 0x32B0
0x32E0 EFI_GUID gEfiLegacyBiosProtocolGuid = EFI_LEGACY_BIOS_PROTOCOL_GUID; // 0x32C0
HOB list pointer (cached, from DxeHobLib)
VOID *mHobList = NULL; // 0x33B8
Debug output driver handle (from sub_275C)
VOID *mDebugOutputHandle = NULL; // 0x33B0
UINT8 mCmosScratchRegister = 0; // 0x33D8
INT13 handler state save/restore
UINT32 mInt13SavedEflags = 0; // 0x33DC
Temporary buffer for INT13 data transfer
VOID *mInt13TransferBuffer = NULL; // 0x33E0
Segment for INT13 data transfer
UINT16 mInt13TransferSegment = 0; // 0x33E8
0x33F0 //
Contains a CRC/checksum and function pointers for internal dispatch
typedef struct {
Describes the legacy BIOS extension protocol interface
Default BBS type value
UINT32 mDefaultBbsType = 0x4FF7F; // 0x3378
IPLDT handle allocation counter
UINT64 mIplDtHandleCounter = 0; // 0x3380
Reference count for the IPLDT allocation (sub_FA8)
UINT64 mIplDtRefCount = 0; // 0x3388
Dispatch table pointer (off_3330 = &mDispatchTable)
LegacyBiosExt pointer (off_3360 = &mLegacyBiosExtTable)
Library Helpers
sub_2824 -- Debug assert helper
Calls gDebugOutput->DebugAssert(FileName, LineNumber, Description)
VOID EFIAPI
sub_27DC -- Debug print helper (log with format)
sub_275C -- Get debug output protocol handle
Locates the EFI_DEBUG_OUTPUT_PROTOCOL (at 0x3240) from the HOB list
VOID *
Locate debug protocol from HOB
if (EFI_ERROR (gBS->LocateProtocol (
0x3240 NULL
sub_2864 -- Check CMOS scratch register for debug level
Reads CMOS offset 0x4B, checks debug enable bit
UINT32 CsmCheckDebugLevel (
sub_28B4 -- Get HOB list pointer (DxeHobLib)
sub_2B2C -- Compare GUID at HOB entry with target guid
BOOLEAN CsmMatchGuid (
0x32A0 V2 = CsmReverseQword ((UINT64 *)TargetGuid);
0x32A8 V2 = CsmReverseQword ((UINT64 )((UINT8 )TargetGuid + 8));
sub_2B9C -- Reverse 8 bytes for GUID comparison
UINT64 CsmReverseQword (
sub_2C20 -- ZeroMemory
VOID CsmZeroMem (
sub_2C80 -- Memory copy (overlap-safe)
Handle overlapping buffers
OverlapReversed = FALSE;
Aligned copy (8-byte aligned)
AlignCheck = (UINTN)S & 7;
sub_29B8 -- Get current allocation position from legacy region
Walks a header-terminated chain of blocks starting at the
legacy region memory buffer. Each block has 4-byte header:
byte0 = type (0xFF = end, 0x00 = unused)
byte1 = 0x7F marker
Returns the total payload size allocated so far (skip 4-byte header).
UINT64 CsmGetCurrentAllocation (
Check for end-of-table or unused entry marker
if (Ptr[0] == 0x7F && Ptr[1] == 0xFF) {
End marker found return total + 4 (skip header)
return Total + 4;
sub_298C -- Allocate boot services data pool
Wrapper for gBS->AllocatePool (EfiBootServicesData, Size, &Buffer)
UINT64 CsmLegacyRegionAllocate (
sub_2AE4 -- Allocate and copy a BBS type table to boot services data pool
UINT64 CsmBbsTableCopy (
sub_2A0C -- Legacy region allocation wrapper
If pBbsType is provided, allocate and copy the BBS type table.
If NULL, free the allocation.
UINT64 CsmBbsTableAllocate (
INT13 Subsystem: State Save/Restore
sub_26F4 -- Save current interrupt state for a device
Saves global INT13 eflags into the per-device saved-flags array
then replaces it with the device's current flags value.
The saved-flags array is indexed by the device number stored at
UINT8 Int13SaveState (
Save current global eflags into the per-device slot
mInt13SavedEflags = Private->Int13SavedFlags[FlagsIndex];
Replace with device's current flags
sub_2734 -- Restore previous interrupt state for a device
Restores the global INT13 eflags value from the per-device saved array.
UINT8 Int13RestoreState (
Restore saved eflags from the per-device slot
INT13 Handler Functions
sub_1AB0 -- INT13h disk I/O status check (function 0x01)
EFI_STATUS Int13GetStatus (
reload context+0x89
sub_1AAC -- INT13h error handler (stub)
VOID Int13ErrorStub (
empty -- placeholder for Int13Error function pointer
sub_1B48 -- INT13h Read Sectors (CHS mode, function 0x02)
Used when device has CHS geometry (original IDE/ATA)
EFI_STATUS Int13ReadWriteChs (
Build INT13 CHS packet
extended read
Disk changed re-detect geometry
Copy data from transfer buffer
if (mCommand == 0x02) // read
sub_1E18 -- INT13h Extended Read (function 0x42)
For LBA mode with extended INT13 support (EDD-1.1+)
EFI_STATUS Int13ExtendedRead (
Build extended INT13 packet
First copy data into transfer buffer, then issue INT13
if (Command == 0x03) { // write
sub_2104 -- INT13h CHS read/write (traditional CHS, function 0x02/0x03)
EFI_STATUS Int13ChsReadWrite (
Convert LBA to CHS
SectorsPerHead = Private->Sectors + 1;
Retry loop (up to 3 attempts)
Retry = 3;
sub_23E8 -- INT13h Extended Write (function 0x43), Verify (0x44)
EFI_STATUS Int13ExtendedWrite (
Copy data to transfer buffer first for write
CsmMemCopy ((VOID )mInt13TransferBuffer, (VOID )CurrentBuf, TransferBytes);
Disk Info Protocol: Inquiry and Identify
sub_1554 -- EFI_DISK_INFO.inquiry
EFI_STATUS EFAPI
sub_1564 -- EFI_DISK_INFO.Identify
Legacy BIOS Protocol / INT13 Dispatch
sub_4C8 -- Legacy Disk Info handler (first entry point)
Handles the EFI_DISK_INFO_PROTOCOL interface for identifying disk types
and locating the appropriate legacy block I/O region.
EFI_STATUS CsmDiskInfoHandler (
Locate the Legacy Interrupt protocol
Status = gBS->LocateProtocol (
Open the Block I/O protocol on this handle
Status = gBS->OpenProtocol (
Determine if Legacy BIOS Platform protocol is available
Check for Legacy MBR
Read MBR and check for boot signature
LegacyRegion = Private->LegacyRegion;
offset 60, // bytes
count &DeviceType
Check device type
if (DeviceType <= 0x0D) {
Set BBS device type from IPLDT table
Read transfer buffer base
Set transfer buffer flags
preserve bits 8-10
Initialize INT13 handler entry
Get BBS device table
Count active BBS entries
for (Index = 0; Index < 256; Index++) {
Execute INT13 to discover drives
Status = Private->BbsTable->Execute (
Count post-INT13 BBS entries
Allocate BBS entry table in legacy region
if (mIplDtHandleCounter == 0) {
Close protocols and return error
Entry Point
Save global protocol pointers
gImageHandle = ImageHandle;
Initialize HOB list
GetHobList ();
Install three protocol interfaces on the image handle:
return gBS->InstallMultipleProtocolInterfaces (
offf3330 - dispatch table with sub_4C8, sub_6D4, sub_FA8
off_3360 - legacy bios ext table
no interface (protocol-only notification)
sub_6D4 -- Main INT13 handler / CSM Block I/O initialization per device
Called for each disk device that needs CSM legacy support.
a1 - Private context (CSM_BLOCK_IO_PRIVATE *)
a2 - EFI_HANDLE for the block device
EFI_STATUS CsmBlockIoInitDevice (
Initialize state
CsmZeroMem (BbsBitmap, sizeof(BbsBitmap));
Locate Legacy Interrupt protocol
Locate Legacy 8259 protocol
Open Block I/O protocol on this handle
Try Legacy Bios Platform protocol (optional)
Open for Legacy MBR too
Legacy MBR is available read device type via Legacy Region
Get transfer buffer base from legacy region (offset 4)
Configure transfer buffer flags (mask 0x700)
Call BIOS INT13 handler entry
Status = Private->BbsTable->Init (
Get BBS table
Status = Private->BbsTable->GetTable (
Count current BBS entries
sub_FA8 -- Close / Cleanup INT13 for a device
Called when a device handle is removed or when shutting down CSM
block I/O legacy support.
EFI_STATUS CsmBlockIoCloseDevice (
Decrement reference count on IPLDT allocation
if (--mIplDtRefCount == 0) {
Process each device handle
for (Index = 0; Index < DeviceCount; Index++) {
Open Disk Info protocol on the child handle
If Legacy BIOS Platform is available, transfer to it
if (PlatformAvailable) {
Free the INT13 handler's memory
Install the protocol interface on the child handle
Status = gBS->InstallProtocolInterface (
Set legacy region flags
If Platform is not available, close BlockIo
if (!PlatformAvailable) {
Final cleanup
sub_1468 -- Find device in IPLDT (Legacy Device Table)
Searches the IPLDT for a matching bus:device tuple and sets
the device index.
VOID CsmFindInIplDt (
Bus number
IPLDT_ENTRY_SIZE }
sub_1570 -- INT13 handler initialization
Called to set up INT13 handler function table for a device.
BOOLEAN CsmInitInt13Handler (
Initialize the media descriptor pointer and INT13 saved state array
Set signature based on system table revision
if (gST->Hdr.Revision < 0x2001F) {
Identify and set up drive parameters
if (!Int13IdentifyDevice (Private, (UINT8 *)&Private->DeviceInfo)) {
LBA device use extended INT13
Only support 512-byte sectors
if (Private->BlockSize != 512) {
Set up INT13 handler function table
Extended INT13 device use LBA handlers
sub_16B0 -- Identify device parameters via INT13
Issues INT13 function 0x13 to get drive parameters
BOOLEAN Int13IdentifyDevice (
Sectors (UINT16 )&DeviceInfo[28] = (UINT16)(
Heads return TRUE;
Sectors (UINT16 )&DeviceInfo[28] = (UINT16 )&DeviceInfo[11]; // Cylinders
Heads if (DeviceInfo[27]) {
sub_1784 -- Get extended drive parameters (INT13 function 0x48)
For EDD-3.0 compatible devices, retrieves full geometry.
BOOLEAN Int13GetDriveParameters (
parameter packet size (41h)
signature DriveParams[1] = 8;
sector size low
DMA DriveParams[6] = DriveParams[1] & 8; // LBA
removable DriveParams[3] = DriveParams[1] & 1; // extended INT13
Get CHS geometry from INT13 function
sub_1834 -- Get CHS geometry from INT13 (function 0x08 or ATA identify)
BOOLEAN Int13ChsGeometry (
Initialize CMOS parameter table for geometry decode
Set up INT13 function 0x08 parameter block
ParamPacket = 'O'; // 79
72 (UINT16 )(mInt13TransferSegment2 + 32) = 74;
Success -- read geometry from transfer buffer
Heads DriveParams[27] = DriveParams[44]; // Sectors
Decode CHS from function 0x08 response
if (FunctionCode != 10) {
Calculate total sectors
bytes per sector
Set total sectors from CHS
sub_11E4 -- Build BBS device type ID
Parses device path media type string and generates BBS device type ID
for the IPLDT / BBS table.
offset +2 from device path
Default type for unrecognized devices
Validate device path node type
if ((UINT8 )((UINTN)DevicePath + 2) != 0x30) { // MESSAGING_DEVICE_PATH
length too small
no media type
Compare media type strings
ATAPI if (AsciiStrnCmp ((CHAR8 *)MediaType, MEDIA_ATAPI, 5) == 0) {
ATA master
ATA (same as ATAPI)
SCSI if (AsciiStrnCmp ((CHAR8 *)MediaType, MEDIA_SCSI, 4) != 0) {
USB if (AsciiStrnCmp ((CHAR8 *)MediaType, MEDIA_USB, 3) != 0) {
1394 if (AsciiStrnCmp ((CHAR8 *)MediaType, MEDIA_1394, 4) != 0) {
FIBRE if (AsciiStrnCmp ((CHAR8 *)MediaType, MEDIA_FIBRE, 5) != 0) {
FIBRE (UINT64 )&TypeFields[4] = (UINT64 )((UINTN)DevicePath + 88);
USB TypeFields[0] = (UINT8 )((UINTN)DevicePath + 96);
SCSI (UINT32 )&TypeFields[0] = (UINT32 )((UINTN)DevicePath + 88);
default GUID-like type

Generated by HR650X BIOS Decompilation Project