# 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*