summaryrefslogtreecommitdiff
path: root/Core/EM/CSM/thunk/BlockIo
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/CSM/thunk/BlockIo')
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c260
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c1076
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h277
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl25
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmEdd.h407
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmInt13.c1525
-rw-r--r--Core/EM/CSM/thunk/BlockIo/biosblkio.dxs46
-rw-r--r--Core/EM/CSM/thunk/BlockIo/biosblkio.mak63
-rw-r--r--Core/EM/CSM/thunk/BlockIo/int13thunk.cif15
9 files changed, 3694 insertions, 0 deletions
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c b/Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c
new file mode 100644
index 0000000..6807d3e
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c
@@ -0,0 +1,260 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlkIoComponentName.c 6 12/23/13 3:38p Olegi $
+//
+// $Revision: 6 $
+//
+// $Date: 12/23/13 3:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlkIoComponentName.c $
+//
+// 6 12/23/13 3:38p Olegi
+// EIP128504: implement EFI_COMPONENT2_NAME_PROTOCOL for CsmBlockIo driver
+//
+// 5 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 4 10/03/07 4:41p Yakovlevs
+// Removed Component Name Protocol and its Strings in NO DEBUG mode to
+// save some space.
+//
+// 3 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 2 3/04/05 1:43p Mandal
+//
+// 1 2/15/05 10:59a Olegi
+// Initial VSS check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmBlkIoComponentName.c
+//
+// Description: Set of functions that implement Component Name protocol
+// for the CSM BlockIO driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "CsmBlockIo.h"
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#define LANGUAGE_CODE_ENGLISH "eng"
+#define EFI_COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME_PROTOCOL
+#endif
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+CsmBlockIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+CsmBlockIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+CHAR16 *gCsmBlockIoDriverName = L"AMI CSM Block I/O Driver";
+CHAR16 gCsmBlockIoControllerName[256];
+
+EFI_COMPONENT_NAME2_PROTOCOL gCsmBlockIoComponentName = {
+ CsmBlockIoComponentNameGetDriverName,
+ CsmBlockIoComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: CsmBlockIoComponentNameGetDriverName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// RETURN:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ //
+ //Supports only English
+ //
+ if (!Language || !DriverName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+ *DriverName = gCsmBlockIoDriverName;
+ return EFI_SUCCESS;
+}
+
+//---------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// FUNCTION: CsmBlockIoComponentNameGetControllerName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// RETURNS:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//<AMI_PHDR_END>
+//---------------------------------------------------------------------------
+
+EFI_STATUS
+CsmBlockIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_EXT_PROTOCOL *LegacyBiosExt;
+ UINT8 BbsCount;
+ BBS_TABLE *BbsEntry;
+ UINT32 i;
+ EFI_HANDLE Handle;
+ CHAR8 *Str;
+ UINT8 Index = 0;
+
+ //
+ //Supports only "eng"
+ //
+ if (!Language || !ControllerName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+ if (ChildHandle == NULL) return EFI_UNSUPPORTED;
+
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosExtProtocolGuid, NULL, (VOID**)&LegacyBiosExt);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = LegacyBiosExt->GetBbsTable(&BbsEntry, &BbsCount);
+ if (EFI_ERROR(Status)) return Status;
+
+ ZeroMemory(gCsmBlockIoControllerName, sizeof(gCsmBlockIoControllerName));
+
+ for (i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+ Handle = *(VOID**)(&BbsEntry->IBV1);
+ if (Handle == ChildHandle) {
+ Str = (CHAR8*)(UINTN)((BbsEntry->DescStringSegment<<4) + BbsEntry->DescStringOffset);
+ if (Str == NULL) return EFI_UNSUPPORTED;
+ //
+ // Transfer Ascii code to Unicode
+ //
+ while (Str[Index] != 0) {
+ gCsmBlockIoControllerName[Index] = (CHAR16)Str[Index];
+ Index++;
+ }
+
+ *ControllerName = gCsmBlockIoControllerName;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
new file mode 100644
index 0000000..14438f5
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
@@ -0,0 +1,1076 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.c 49 8/06/14 1:20p Fasihm $
+//
+// $Revision: 49 $
+//
+// $Date: 8/06/14 1:20p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.c $
+//
+// 49 8/06/14 1:20p Fasihm
+// [TAG] EIP180668
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Aptio 4 CSM: CsmBlkIO: Start function might incorrectly
+// initialize IBV fields in BBS table.
+// [Solution] Maintain the number of newly created BBS entries;
+// initialize IBV fields only for those entries created by the Option ROM.
+// [Files]
+// Core\EM\CSM\thunk\BlockIo\CsmBlockIo.c
+//
+// 48 12/23/13 3:38p Olegi
+// EIP128504: implement EFI_COMPONENT_NAME2_PROTOCOL for CsmBlockIo driver
+//
+// 47 12/23/13 3:14p Olegi
+// EIP148138: use AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL instead of
+// EFI_MBR_WRITE_PROTECTION_PROTOCOL
+//
+// 46 12/23/13 10:22a Olegi
+// EIP148123: CSM includes file which name has been changed
+//
+// 45 12/06/13 12:07a Rameshr
+// [TAG] EIP143793
+// [Category] Improvement
+// [Description] For onboard Raid controller, consumed
+// DevicePathProtocol - By driver and as a child controller, instead of
+// the PciIo Protocol. Because PciIo protocol us already consumed by
+// SataController driver.
+// [Files] CsmBlockIo.c
+//
+// 44 7/01/13 5:56a Kapilporwal
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] Please support Boot Sector Virus Protection for CSM
+// Disabled Mode
+// [Files] VirusProtect.c, VirusProtect.dxs, AhciBus.c,
+// AhciController.c, CsmBlockIo.c, CsmInt13.c, Ata.c, IdeBus.c,
+// SdioBlkIo.c, SdioDriver.c, efiusbmass.c
+//
+// 43 3/07/13 10:47p Olegi
+// [TAG] EIP117323
+// [Category] New Feature
+// [Description] Fiber Channel controllers support in CsmBlockIo
+//
+// 42 12/14/12 3:29p Olegi
+//
+// 41 12/23/11 2:12p Olegi
+// [TAG] EIP78921
+// [Category] Improvement
+// [Description] CsmBlockIo should create device handle in BBS table
+// [Files] CsmBlockIo.c
+// CsmBlockIo.h
+//
+// 39 11/10/11 7:15p Olegi
+// Installed thunk driver GUID
+//
+// 38 11/04/11 12:41p Olegi
+//
+// 37 8/15/11 9:45a Olegi
+//
+// 36 8/12/11 3:05p Olegi
+// Correction to the previous check-in: in Supported function some
+// protocols can not be open BY_DRIVER for the onboard RAID. Changed the
+// OpenProtocol attributes.
+//
+// 35 8/10/11 11:48a Olegi
+// GUID and variable names are corrected; Supported function modified to
+// close PciIo protocol right after it is used. EIP49352.
+//
+// 34 7/20/11 12:21p Olegi
+// Added dependency on the HDD security SDL token.
+//
+// 33 6/27/11 4:50p Olegi
+// Cleaning the headers and the comments. Change in Supported function
+// that partially undoing EIP39017 and allows non-Intel RAID option ROMs
+// produce BlkIo.
+//
+// 32 4/27/11 6:47p Olegi
+// [TAG] EIP54911
+// [Category] Improvement
+// [Description] Start function modified to return the proper value.
+// [Files] CsmBlockIo.c
+//
+// 31 1/19/11 10:19a Olegi
+//
+// 29 12/14/10 12:08p Olegi
+// [TAG] EIP48212
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Some controllers are not enabled before executing their
+// Option ROM
+// [RootCause] There is no code that enable a device in CsmBlockIo start
+// function.
+// [Solution] Added a call that enables device to the CsmBlockIo start
+// function.
+// [Files] CsmBlockIo.c, PciInterrupts.c
+//
+// 28 7/29/10 3:20p Olegi
+// EIP39017:: Added code in Supported function to prevent BlockIo from
+// binding prematurely.
+//
+// 27 3/12/10 9:49a Olegi
+// Onboard RAID option ROM related changes. EIP34602.
+//
+// 26 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 25 8/07/09 2:46p Rameshr
+// SD boot support Added.
+//
+// 24 10/04/07 3:04p Olegi
+// Bugfix in CsmBlockIoStart for HW interrupt save/restore in case of
+// multiple drives connected.
+//
+// 23 10/03/07 4:41p Yakovlevs
+// Removed Component Name Protocol and its Strings in NO DEBUG mode to
+// save some space.
+//
+// 22 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 21 4/13/07 9:37a Olegi
+//
+// 20 3/29/07 5:51p Olegi
+//
+// 19 3/29/07 1:37p Felixp
+// Bug fix in BuildDevicePath: properly initialize device path for unknown
+// devices
+//
+// 18 12/07/06 3:13p Olegi
+// Support for embedded OpROMs added.
+//
+// 17 7/31/06 4:11p Olegi
+//
+// 16 5/19/06 11:25p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 15 5/01/06 3:57p Olegi
+// CheckPciRom will be called from LegacyBios.InstallPciRom, no need to
+// call it again.
+//
+// 14 3/13/06 4:15p Felixp
+//
+// 13 3/13/06 2:38p Felixp
+//
+// 12 10/13/05 6:21p Olegi
+// Added HW interrupt handling
+//
+// 11 8/30/05 9:06a Olegi
+// BuildDevicePath correction.
+//
+// 10 7/26/05 2:51p Olegi
+//
+// 9 6/23/05 5:26p Olegi
+//
+// 8 6/22/05 8:34a Olegi
+//
+// 7 4/20/05 4:16p Olegi
+// INT 13 vector maintenance has been moved to the main CSM module.
+//
+// 6 4/12/05 12:21p Olegi
+//
+// 5 3/16/05 11:05a Olegi
+//
+// 4 3/04/05 1:45p Mandal
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmBlockIo.c
+//
+// Description: CSM Block I/O Module. Main module, containing entry,
+// supported, start, and stop functions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "CsmBlockIo.h"
+#include <Protocol\Legacy8259.h>
+#include <Protocol\IdeControllerInit.h>
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+#include <Protocol\AmiBlockIoWriteProtection.h>
+AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL *gBlockIoWriteProtectionProtocol = NULL;
+#endif
+
+// EFI Driver Binding Protocol Instance
+EFI_DRIVER_BINDING_PROTOCOL gCsmBlockIoDriverBinding = {
+ CsmBlockIoSupported,
+ CsmBlockIoStart,
+ CsmBlockIoStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+extern EFI_COMPONENT_NAME_PROTOCOL gCsmBlockIoComponentName;
+#else
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+extern EFI_COMPONENT_NAME2_PROTOCOL gCsmBlockIoComponentName;
+#endif
+
+// Number of current users of this driver
+UINTN mCurrentUsers = 0;
+
+// Real mode buffer to contain the buffers below
+EFI_PHYSICAL_ADDRESS mRealModeBuffer = 0;
+
+// Packet buffer under 1 MB for all version EDD calls
+EDD_DEVICE_ADDRESS_PACKET *mEDDPacketBuffer;
+
+// EDD 1.1 transfer buffer
+VOID *mEDDTransferBuffer;
+
+// This is a buffer for INT 13h func 48 information
+CSM_LEGACY_DRIVE *mDriveParameterBuffer;
+
+// The following variables will track the onboard mass storage controller
+// in RAID mode with the Option ROM that can not handle ATAPI devices:
+//
+// - gOnboardRaidGuid is GUID installed on such controller in SBDXE
+// - gOnboardRaid is the switch indicating the requested controller
+// has gOnboardRaidGuid installed on it
+//
+#define ONBOARD_RAID_GUID \
+ { 0x5d206dd3, 0x516a, 0x47dc, 0xa1, 0xbc, 0x6d, 0xa2, 0x4, 0xaa, 0xbe, 0x8};
+EFI_GUID gOnboardRaidGuid = ONBOARD_RAID_GUID;
+
+// The following GUID is used to ensure the Start function is executed after all
+// individual drives in RAID are unlocked before RAID Option ROM is executed
+//
+#define HDD_UNLOCKED_GUID \
+ { 0x1fd29be6, 0x70d0, 0x42a4, 0xa6, 0xe7, 0xe5, 0xd1, 0xe, 0x6a, 0xc3, 0x76};
+EFI_GUID gHddUnlockedGuid = HDD_UNLOCKED_GUID;
+
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoEntryPoint
+//
+// Description:
+// This is the CsmBlockIo driver entry point. It installs
+// gCsmBlockIoDriverBinding protocol
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ static EFI_GUID gCsmThunkDriverGuid =
+ { 0x2362ea9c, 0x84e5, 0x4dff, 0x83, 0xbc, 0xb5, 0xac, 0xec, 0xb5, 0x7c, 0xbb };
+
+ gCsmBlockIoDriverBinding.DriverBindingHandle = ImageHandle;
+ gCsmBlockIoDriverBinding.ImageHandle = ImageHandle;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ return pBS->InstallMultipleProtocolInterfaces(
+ &gCsmBlockIoDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &gCsmBlockIoDriverBinding,
+ &gComponentNameProtocolGuid, &gCsmBlockIoComponentName,
+ &gCsmThunkDriverGuid, NULL,
+ NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoSupported
+//
+// Description:
+// This is a binding protocol function. It checks whether or not this
+// driver supports the given controller
+//
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_STD_DEVICE Pci;
+ VOID *IdeControllerInterface;
+
+ // See if the Legacy BIOS Protocol is available
+ Status = pBS->LocateProtocol( &gEfiLegacyBiosProtocolGuid,
+ NULL, (VOID**)&LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Check whether DevicePath Protocol has been installed on this controller
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ pBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ // Check whether this is Onboard RAID
+ Status = pBS->OpenProtocol( Controller,
+ &gOnboardRaidGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ // Do the checkings/manipulations with the onboard RAID
+ if(!EFI_ERROR(Status))
+ {
+ // Make sure drives are unlocked
+#if defined SETUP_IDE_SECURITY_SUPPORT && SETUP_IDE_SECURITY_SUPPORT == 1
+ Status = pBS->OpenProtocol( Controller,
+ &gHddUnlockedGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+#endif
+ if(EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Make sure IDE_CONTROLLER_PROTOCOL is installed; this ensures the
+ // controller is initialized
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ (VOID **)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ // Check whether PCI Protocol has been installed on this controller
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID**)&PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ // Read PCI configuration
+ Status = PciIo->Pci.Read (PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+
+ // Status is EFI_SUCCESS here
+
+ if ( Pci.Header.ClassCode[2] != PCI_CL_MASS_STOR && \
+ (Pci.Header.ClassCode[2] != PCI_BASE_CLASS_INTELLIGENT || \
+ Pci.Header.ClassCode[1] != PCI_SUB_CLASS_INTELLIGENT) )
+ {
+ Status = EFI_UNSUPPORTED;
+ }
+ if ( Pci.Header.ClassCode[1] == PCI_CL_SYSTEM_PERIPHERALS_SCL_SD && \
+ Pci.Header.ClassCode[2] == PCI_CL_SYSTEM_PERIPHERALS )
+ {
+ Status = EFI_SUCCESS;
+ }
+ if ( Pci.Header.ClassCode[1] == PCI_CL_SER_BUS_SCL_FIBCHAN &&
+ Pci.Header.ClassCode[2] == PCI_CL_SER_BUS )
+ {
+ Status = EFI_SUCCESS;
+ }
+
+// TRACE((-1, "\nCsmBlockIo.Supported: called for VID/DID: %x %x, CL %x SCL %x; Status = %r\n",
+// Pci.Header.VendorId, Pci.Header.DeviceId, Pci.Header.ClassCode[2], Pci.Header.ClassCode[1], Status));
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoStart
+//
+// Description:
+// Installs BlockIoProtocol using INT13 services produced by Option ROM
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Open PCI and Devicepath protocol
+// 2. Enable the device
+// 3. Post the option rom
+// 4. If first time, allocate buffer for real mode thunk code
+// 5. For each disk...
+// a. Allocate and initialize a private structure
+// b. Install block I/O protocol on a new child device
+// c. Open the child device
+// 6. Increment user counter
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_PCI_IO_PROTOCOL *PciIo = NULL;
+ UINT8 FirstDisk;
+ UINT8 LastDisk;
+ UINT8 x = 0;
+ CSM_BLOCK_IO_DEV *PrivateBlockIoStruc = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *PciDevPath;
+ UINTN i = 0;
+ UINTN Flags;
+ UINTN TempAddress = 0;
+ UINT8 irq = 0;
+ EFI_LEGACY_8259_PROTOCOL *i8259;
+ UINT32 *ivt = (UINT32*)0;
+ UINT32 TempInt;
+ UINT32 HwInterruptHandler;
+ UINT64 Capabilities;
+ UINT8 j = 0;
+ UINT8 BbsCount;
+ BBS_TABLE* BbsEntry = NULL;
+ BBS_TABLE* BbsTable = NULL;
+ BOOLEAN BbsEntryPresent[MAX_BBS_ENTRIES_NO] = {0};
+ UINTN FirstNewBbsEntry = 0;
+ EFI_LEGACY_BIOS_EXT_PROTOCOL *LegacyBiosExt;
+ BOOLEAN OnboardRaidController=FALSE;
+ EFI_DEVICE_PATH_PROTOCOL *ChildPciDevPath;
+ UINT8 NumberOfBbsEntriesBeforeOprom = 0;
+ UINT8 NumberOfBbsEntriesAfterOprom = 0;
+ UINT8 NewBbsEntries;
+
+ // See if the Legacy BIOS Protocol is available
+ Status = pBS->LocateProtocol( &gEfiLegacyBiosProtocolGuid,
+ NULL, (VOID **)&LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // See if the Legacy BIOS Ext Protocol is available
+ Status = pBS->LocateProtocol ( &gEfiLegacyBiosExtProtocolGuid,
+ NULL, (VOID**)&LegacyBiosExt);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ if(gBlockIoWriteProtectionProtocol == NULL)
+ pBS->LocateProtocol(&gAmiBlockIoWriteProtectionProtocolGuid, NULL, &gBlockIoWriteProtectionProtocol);
+#endif
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&PciDevPath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Check whether this is Onboard RAID
+ Status = pBS->OpenProtocol( Controller,
+ &gOnboardRaidGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (!EFI_ERROR (Status)) {
+ OnboardRaidController=TRUE;
+ }
+
+ // Open PCI I/O Protocol
+ if (OnboardRaidController) {
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ } else {
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ }
+
+ if ( EFI_ERROR(Status) ) {
+ return Status;
+ }
+
+ // Get the hardware interrupt vector and its handler pointer
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0x3C, 1, &irq);
+ ASSERT_EFI_ERROR(Status);
+ if (irq > 0 && irq < 0xF) {
+ Status = pBS->LocateProtocol(&gEfiLegacy8259ProtocolGuid, NULL, &i8259);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = i8259->GetVector (i8259, irq, &irq); // irq has INT number
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ // Store HW interrupt vector, to be restored for PnP ROMs
+ TempInt = ivt[irq];
+
+ // Enable the device
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Enable device
+ ASSERT_EFI_ERROR(Status);
+
+ // Check to see if there is a legacy option ROM image associated with this PCI device
+ Status = LegacyBios->CheckPciRom (LegacyBios,
+ Controller,
+ NULL,
+ NULL,
+ &Flags
+ );
+
+ if ( EFI_ERROR(Status) ) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ // Get BBS table
+ Status = LegacyBiosExt->GetBbsTable(
+ &BbsEntry,
+ &BbsCount);
+ ASSERT_EFI_ERROR(Status);
+ BbsTable = BbsEntry;
+
+ // Loop through table and note entries which are populated
+ for (i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+
+ if (BbsEntry->BootPriority == BBS_IGNORE_ENTRY)
+ continue;
+
+ BbsEntryPresent[i] = TRUE;
+ NumberOfBbsEntriesBeforeOprom++;
+ }
+
+ // Post the legacy option ROM if it is available.
+ Status = LegacyBios->InstallPciRom( LegacyBios,
+ Controller,
+ NULL,
+ &Flags,
+ &FirstDisk,
+ &LastDisk,
+ NULL,
+ NULL );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ BbsEntry = BbsTable;
+
+ // Loop through BBS table and find first new entry, added due to OpROM execution
+ for (i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+ if (BbsEntry->BootPriority == BBS_IGNORE_ENTRY)
+ continue;
+ if ((BbsEntryPresent[i] == FALSE) && (FirstNewBbsEntry == 0)) {
+ FirstNewBbsEntry = i;
+ }
+ NumberOfBbsEntriesAfterOprom++;
+ }
+
+ ASSERT(NumberOfBbsEntriesAfterOprom >= NumberOfBbsEntriesBeforeOprom);
+ NewBbsEntries = NumberOfBbsEntriesAfterOprom - NumberOfBbsEntriesBeforeOprom;
+
+ HwInterruptHandler = ivt[irq];
+
+ // All users share a buffer under 1MB to put real mode thunk code in
+ // If it has not been allocated, then we allocate it.
+ if (mRealModeBuffer == 0) {
+ // Allocate below 1MB
+ mRealModeBuffer = 0x00000000000FFFFF;
+ Status = pBS->AllocatePages( AllocateMaxAddress,
+ EfiBootServicesData,
+ BLOCK_IO_BUFFER_PAGE_SIZE,
+ &mRealModeBuffer );
+
+ // Check memory allocation success
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ mRealModeBuffer = 0;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ // Set up real mode memory for Thunk
+ TempAddress = (UINTN)mRealModeBuffer;
+ // Setup the EDD 1.1 transfer buffer
+ TempAddress += AlignAddress(TempAddress);
+ mEDDTransferBuffer = (VOID *)(TempAddress);
+ // Setup the Legacy Drive buffer
+ TempAddress += MAX_EDD11_XFER;
+ TempAddress += AlignAddress(TempAddress);
+ mDriveParameterBuffer = (CSM_LEGACY_DRIVE *)(TempAddress);
+ // Setup the EDD Packet buffer
+ TempAddress += sizeof (CSM_LEGACY_DRIVE);
+ TempAddress += AlignAddress(TempAddress);
+ mEDDPacketBuffer = (EDD_DEVICE_ADDRESS_PACKET *)TempAddress;
+ }
+
+ // Allocate the private device structure for each disk
+ for (i = FirstDisk, j = 0; i < LastDisk; i++, j++) {
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof (CSM_BLOCK_IO_DEV),
+ &PrivateBlockIoStruc );
+
+ if (EFI_ERROR(Status)) {
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+ pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+ if (mRealModeBuffer != 0 && mCurrentUsers == 0) {
+ pBS->FreePages (mRealModeBuffer, BLOCK_IO_BUFFER_PAGE_SIZE);
+ mRealModeBuffer = 0;
+ }
+
+ return Status;
+ }
+
+ // Zero the private device structure
+ ZeroMemory (PrivateBlockIoStruc, sizeof (CSM_BLOCK_IO_DEV));
+
+ // Initialize the private device structure
+ PrivateBlockIoStruc->ControllerHandle = Controller;
+ PrivateBlockIoStruc->LegacyBios = LegacyBios;
+ PrivateBlockIoStruc->PciIo = PciIo;
+
+ PrivateBlockIoStruc->Drive.Floppy = FALSE;
+ x = (i & 0x40)? 0x40 : 0;
+ if (x) {
+ PrivateBlockIoStruc->HwInt = irq;
+ PrivateBlockIoStruc->HwIntHandler = HwInterruptHandler;
+ ivt[irq] = TempInt; // Restore HW interrupt
+ }
+ PrivateBlockIoStruc->Drive.Number = (UINT8) i - x;
+ PrivateBlockIoStruc->Drive.Letter = (UINT8)(i - x - 0x80 + 'C');
+ PrivateBlockIoStruc->BlockMedia.RemovableMedia = FALSE;
+
+ if (InitBlockIo (PrivateBlockIoStruc)) {
+ BuildDevicePath( PciDevPath,
+ &PrivateBlockIoStruc->Drive,
+ &PrivateBlockIoStruc->DevicePath);
+
+ // Install the Block Io Protocol onto a new child handle
+ Status = pBS->InstallMultipleProtocolInterfaces( &PrivateBlockIoStruc->Handle,
+ &gEfiBlockIoProtocolGuid,
+ &PrivateBlockIoStruc->BlockIo,
+ &gEfiDevicePathProtocolGuid,
+ PrivateBlockIoStruc->DevicePath,
+ NULL );
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (PrivateBlockIoStruc);
+ }
+
+ // Set handle to which BlockIO has been installed
+ if (j < NewBbsEntries)
+ {
+ *(UINTN*)(&(BbsTable[FirstNewBbsEntry + j].IBV1)) = (UINTN)(PrivateBlockIoStruc->Handle);
+ }
+ if(OnboardRaidController) {
+ // Open For Child Device
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&ChildPciDevPath,
+ This->DriverBindingHandle,
+ PrivateBlockIoStruc->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+
+ } else {
+
+ // Open For Child Device
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID**)&PrivateBlockIoStruc->PciIo,
+ This->DriverBindingHandle,
+ PrivateBlockIoStruc->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+ }
+ } else {
+ pBS->FreePool (PrivateBlockIoStruc);
+ }
+ } // end for loop
+
+ mCurrentUsers++;
+
+ return Status;
+
+Done:
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+ pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoStop
+//
+// Description: Installs IdeControllerProtocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Decrement user counter
+// 2. Free global buffer
+// 3. Release PCI I/O protocol and Block I/O protocol for each child handle.
+// 4. Shut down the hardware for each child handle.
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN AllChildrenStopped;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ CSM_BLOCK_IO_DEV *PrivateBlockIoStruc;
+ UINTN i;
+ BOOLEAN OnboardRaidController=FALSE;
+
+ // Decrement the number of current users
+ mCurrentUsers--;
+
+ if (mCurrentUsers == 0) {
+ // Free our global buffer
+ Status = pBS->FreePages (mRealModeBuffer, BLOCK_IO_BUFFER_PAGE_SIZE);
+ ASSERT_EFI_ERROR (Status);
+ mRealModeBuffer = 0;
+ }
+
+ // Check whether this is Onboard RAID
+ Status = pBS->OpenProtocol( Controller,
+ &gOnboardRaidGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (!EFI_ERROR (Status)) {
+ OnboardRaidController=TRUE;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ // Close protocols and shut down hardware for each child handle.
+ for (i = 0; i < NumberOfChildren; i++) {
+
+ Status = pBS->OpenProtocol( ChildHandleBuffer[i],
+ &gEfiBlockIoProtocolGuid,
+ (VOID**)&BlockIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PrivateBlockIoStruc = (CSM_BLOCK_IO_DEV *) BlockIo;
+
+ if(OnboardRaidController) {
+ pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[i] );
+ }
+
+ // Release PCI I/O and Block IO Protocols on the clild handle.
+ Status = pBS->UninstallMultipleProtocolInterfaces( ChildHandleBuffer[i],
+ &gEfiBlockIoProtocolGuid,
+ &PrivateBlockIoStruc->BlockIo,
+ &gEfiDevicePathProtocolGuid,
+ PrivateBlockIoStruc->DevicePath,
+ NULL );
+
+ if (EFI_ERROR(Status)) {
+ AllChildrenStopped = FALSE;
+ }
+
+ // Shutdown the hardware
+ PrivateBlockIoStruc->PciIo->Attributes (
+ PrivateBlockIoStruc->PciIo,
+ EfiPciIoAttributeOperationDisable,
+ EFI_PCI_DEVICE_ENABLE,
+ NULL);
+
+
+ if(!OnboardRaidController) {
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[i] );
+ }
+
+ pBS->FreePool (PrivateBlockIoStruc);
+ } // end for loop
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+ if(!OnboardRaidController) {
+ Status = pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+// LOCAL FUNCTIONS
+//**********************************************************************
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: BuildDevicePath
+//
+// Description: Builds device path for this device
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *BaseDevicePath,
+// IN CSM_LEGACY_DRIVE *Drive,
+// OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Decrement user counter
+// 2. Free global buffer
+// 3. Release PCI I/O protocol and Block I/O protocol for each child handle.
+// 4. Shut down the hardware for each child handle.
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+VOID
+BuildDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *BaseDevicePath,
+ IN CSM_LEGACY_DRIVE *Drive,
+ OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+)
+{
+ EFI_GUID UnknownDevGuid = UNKNOWN_DEVICE_GUID; // ditto
+ EFI_DEV_PATH Node;
+ UINT32 Controller;
+
+ Node.DevPath.Type = 0;
+ if (Drive->EddVersion == EDD_VERSION_30 &&
+ Drive->Parameters.StructureSize > 0x1A &&
+ *(UINT32*)Drive->Parameters.InterfaceType != 0) {
+ // Build device path for EDD 3.0 device
+ Controller = (UINT32)Drive->Parameters.InterfacePath.Pci.Controller;
+ if ((MemCmp ("ATAPI", Drive->Parameters.InterfaceType, 5) == 0) ||
+ (MemCmp ("ATA", Drive->Parameters.InterfaceType, 3) == 0)) {
+ // ATA or ATAPI drive found
+ Node.Atapi.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.Atapi.Header.SubType = MSG_ATAPI_DP;
+ SET_NODE_LENGTH(&Node.Atapi.Header,sizeof(ATAPI_DEVICE_PATH));
+ Node.Atapi.SlaveMaster = Drive->Parameters.DevicePath.Atapi.Master;
+ Node.Atapi.Lun = Drive->Parameters.DevicePath.Atapi.Lun;
+ Node.Atapi.PrimarySecondary = (UINT8)Controller;
+ } else {
+ // Not an ATA/ATAPI drive
+ if (Controller != 0) {
+ Node.Controller.Header.Type = HARDWARE_DEVICE_PATH;
+ Node.Controller.Header.SubType = HW_CONTROLLER_DP;
+ SET_NODE_LENGTH(&Node.Controller.Header,sizeof(CONTROLLER_DEVICE_PATH));
+ Node.Controller.Controller = Controller;
+ *DevicePath = DPAddNode (BaseDevicePath, &Node.DevPath);
+ Node.DevPath.Type = 0;
+ }
+ // Since it's not ATA/ATAPI, find out what kind it is
+ if (MemCmp("SCSI", Drive->Parameters.InterfaceType, 4) == 0 ) {
+ // SCSI drive
+ Node.Scsi.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.Scsi.Header.SubType = MSG_SCSI_DP;
+ SET_NODE_LENGTH(&Node.Scsi.Header,sizeof(SCSI_DEVICE_PATH));
+ Node.Scsi.Lun = (UINT16)Drive->Parameters.DevicePath.Scsi.Lun;
+ Node.Scsi.Pun = Drive->Parameters.DevicePath.Scsi.TargetId;
+ } else if (MemCmp("USB", Drive->Parameters.InterfaceType, 3) == 0 ) {
+ // USB drive
+ Node.Usb.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.Usb.Header.SubType = MSG_USB_DP;
+ SET_NODE_LENGTH(&Node.Usb.Header,sizeof(USB_DEVICE_PATH));
+ Node.Usb.ParentPortNumber = (UINT8)Drive->Parameters.DevicePath.Usb.Reserved;
+ } else if (MemCmp("1394", Drive->Parameters.InterfaceType, 4) == 0 ) {
+ // 1394 drive
+ Node.F1394.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.F1394.Header.SubType = MSG_1394_DP;
+ SET_NODE_LENGTH(&Node.F1394.Header,sizeof(F1394_DEVICE_PATH));
+ Node.F1394.Guid = Drive->Parameters.DevicePath.FireWire.Guid;
+ } else if (MemCmp("FIBRE", Drive->Parameters.InterfaceType, 5) == 0 ) {
+ // Fibre Channel drive
+ Node.FibreChannel.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.FibreChannel.Header.SubType = MSG_FIBRECHANNEL_DP;
+ SET_NODE_LENGTH(&Node.FibreChannel.Header,sizeof(FIBRECHANNEL_DEVICE_PATH));
+ Node.FibreChannel.WWN = Drive->Parameters.DevicePath.FibreChannel.Wwn;
+ Node.FibreChannel.Lun = Drive->Parameters.DevicePath.FibreChannel.Lun;
+ }
+ }
+ }
+ // If Device Path Type is still zero, it means this is either EDD 1.1 device
+ // or unreconized EDD 3.0 device. Add vendor HW device node for such devices
+ if (Node.DevPath.Type == 0) {
+ Node.UnknownVendor.DevicePath.Header.Type = HARDWARE_DEVICE_PATH;
+ Node.UnknownVendor.DevicePath.Header.SubType = HW_VENDOR_DP;
+ SET_NODE_LENGTH(&Node.UnknownVendor.DevicePath.Header,sizeof(UNKNOWN_DEVICE_VENDOR_DEVICE_PATH));
+ Node.UnknownVendor.DevicePath.Guid = UnknownDevGuid;
+ Node.UnknownVendor.LegacyDriveLetter = Drive->Number;
+ }
+ *DevicePath = DPAddNode (BaseDevicePath, &Node.DevPath);
+}
+
+// Align address on boundary of UINTN for this compiler
+UINTN AlignAddress (UINTN Address)
+{
+ if((UINTN)Address % sizeof(UINTN)) {
+ return sizeof(UINTN) - ((UINTN)Address % sizeof(UINTN));
+ } else {
+ return 0;
+ }
+}
+
+// Zero memory
+VOID ZeroMemory (
+ VOID *Buffer,
+ UINTN Size
+)
+{
+ UINT8 *Ptr;
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h
new file mode 100644
index 0000000..59ce30b
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h
@@ -0,0 +1,277 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.h 10 12/23/11 2:12p Olegi $
+//
+// $Revision: 10 $
+//
+// $Date: 12/23/11 2:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.h $
+//
+// 10 12/23/11 2:12p Olegi
+// [TAG] EIP78921
+// [Category] Improvement
+// [Description] CsmBlockIo should create device handle in BBS table
+// [Files] CsmBlockIo.c
+// CsmBlockIo.h
+//
+// 9 6/27/11 4:50p Olegi
+//
+// 8 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 7 9/23/09 11:18a Olegi
+//
+// 6 8/07/09 2:46p Rameshr
+// SD boot support Added.
+//
+// 5 10/03/07 4:42p Yakovlevs
+// Removed Component Name Protocol and its Strings in NO DEBUG mode to
+// save some space.
+//
+// 4 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 3 3/13/06 2:38p Felixp
+//
+// 2 3/04/05 1:45p Mandal
+//
+// 1 2/15/05 11:00a Olegi
+// Initial VSS check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmBlockIo.h
+//
+// Description: CSM BlockIO driver header file.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _CsmBlockIo_
+#define _CsmBlockIo_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <PCI.h>
+#include <AmiDxeLib.h>
+#include <Protocol\PciIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\LegacyBios.h>
+#include <Protocol\LegacyBiosExt.h>
+#include <protocol\DriverBinding.h>
+#include <Protocol\ComponentName.h>
+#include <protocol\BlockIo.h>
+
+#include "CsmEdd.h"
+
+
+// Global Variables
+#if EFI_DEBUG
+extern EFI_COMPONENT_NAME_PROTOCOL gBiosBlockIoComponentName;
+#endif
+
+
+// Define the I2O class code
+
+#define PCI_BASE_CLASS_INTELLIGENT 0x0e
+#define PCI_SUB_CLASS_INTELLIGENT 0x00
+
+// SD class/subclass defined in PCI.H in 4.6.3.7
+#ifndef PCI_CL_SYSTEM_PERIPHERALS
+#define PCI_CL_SYSTEM_PERIPHERALS 0x08
+#endif
+#ifndef PCI_CL_SYSTEM_PERIPHERALS_SCL_SD
+#define PCI_CL_SYSTEM_PERIPHERALS_SCL_SD 0x05
+#endif
+
+
+// Number of pages needed for our buffer under 1MB
+
+#define BLOCK_IO_BUFFER_PAGE_SIZE (((sizeof (EDD_DEVICE_ADDRESS_PACKET) + sizeof (CSM_LEGACY_DRIVE) + MAX_EDD11_XFER) / EFI_PAGE_SIZE) + 1)
+
+
+// PROTOTYPES
+
+// Driver Binding Protocol functions
+
+EFI_STATUS
+CsmBlockIoSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+CsmBlockIoStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+CsmBlockIoStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+// Block I/O functions
+
+EFI_STATUS
+CsmBlockIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ );
+
+EFI_STATUS
+CsmBlockIoReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+// These prototypes aren't actually used -- they are the generic for the specific
+// functions below
+EFI_STATUS
+CsmBlockIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+CsmBlockIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+// Specific read/write function prototypes
+EFI_STATUS
+Edd30CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+Edd30CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+Edd11CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+Edd11CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+LegacyCsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+LegacyCsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+// Local support function prototypes
+BOOLEAN
+InitBlockIo (
+ IN CSM_BLOCK_IO_DEV *Dev
+ );
+
+// Local function prototypes
+VOID
+BuildDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *BaseDevicePath,
+ IN CSM_LEGACY_DRIVE *Drive,
+ IN EFI_DEVICE_PATH_PROTOCOL **DevPath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath,
+ IN EFI_DEVICE_PATH_PROTOCOL *Node
+ );
+
+UINTN AlignAddress (
+ UINTN Address
+ );
+
+VOID ZeroMemory (
+ VOID *Buffer,
+ UINTN Size
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl
new file mode 100644
index 0000000..ac17f94
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "CsmBlockIo_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CsmBlockIo support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "CSMBLOCKIO_DIR"
+ Help = "CSM BLOCK I/O source directory"
+End
+
+MODULE
+ Help = "Includes CsmBlockIo.mak to Project"
+ File = "biosblkio.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\biosblkio.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmEdd.h b/Core/EM/CSM/thunk/BlockIo/CsmEdd.h
new file mode 100644
index 0000000..0c9ff4c
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmEdd.h
@@ -0,0 +1,407 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmEdd.h 7 1/12/10 11:50a Olegi $
+//
+// $Revision: 7 $
+//
+// $Date: 1/12/10 11:50a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmEdd.h $
+//
+// 7 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 6 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 5 3/13/06 2:38p Felixp
+//
+// 4 10/13/05 6:21p Olegi
+//
+// 3 4/20/05 4:54p Andriyn
+// USB_DEVICE_PATH is in core now
+//
+// 2 3/04/05 1:45p Mandal
+//
+// 1 2/15/05 11:00a Olegi
+// Initial VSS check-in.
+//
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmEdd.h
+//
+// Description: EDD support definitions file
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _CSM_EDD_H_
+#define _CSM_EDD_H_
+
+#pragma pack(1)
+
+typedef struct {
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 Controller;
+ UINT32 Reserved;
+} EDD_PCI;
+
+typedef struct {
+ UINT16 Base;
+ UINT16 Reserved;
+ UINT32 Reserved2;
+} EDD_LEGACY;
+
+typedef union {
+ EDD_PCI Pci;
+ EDD_LEGACY Legacy;
+} EDD_INTERFACE_PATH;
+
+typedef struct {
+ UINT8 Master;
+ UINT8 Reserved[15];
+} EDD_ATA;
+
+typedef struct {
+ UINT8 Master;
+ UINT8 Lun;
+ UINT8 Reserved[14];
+} EDD_ATAPI;
+
+typedef struct {
+ UINT16 TargetId;
+ UINT64 Lun;
+ UINT8 Reserved[6];
+} EDD_SCSI;
+
+typedef struct {
+ UINT64 SerialNumber;
+ UINT64 Reserved;
+} EDD_USB;
+
+typedef struct {
+ UINT64 Guid;
+ UINT64 Reserved;
+} EDD_1394;
+
+typedef struct {
+ UINT64 Wwn;
+ UINT64 Lun;
+} EDD_FIBRE;
+
+typedef union {
+ EDD_ATA Ata;
+ EDD_ATAPI Atapi;
+ EDD_SCSI Scsi;
+ EDD_USB Usb;
+ EDD_1394 FireWire;
+ EDD_FIBRE FibreChannel;
+} EDD_DEVICE_PATH;
+
+typedef struct _UNKNOWN_VENDOR_DEVICE_PATH {
+ VENDOR_DEVICE_PATH DevicePath;
+ UINT8 LegacyDriveLetter;
+} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH;
+
+//typedef struct _CONTROLLER_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT32 Controller;
+//} CONTROLLER_DEVICE_PATH;
+
+//typedef struct _ATAPI_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT8 Channel;
+// UINT8 Device;
+// UINT16 Lun;
+//} ATAPI_DEVICE_PATH;
+
+//typedef struct _SCSI_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT16 TargetId;
+// UINT16 Lun;
+//} SCSI_DEVICE_PATH;
+
+//typedef struct _FIBRE_CHANNEL_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT32 Reserved;
+// UINT64 WorldWideNumber;
+// UINT64 Lun;
+//} FIBRECHANNEL_DEVICE_PATH;
+
+//typedef struct _F1394_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT32 Reserved;
+// UINT64 _1394Guid;
+//} F1394_DEVICE_PATH;
+/* AndriyN : must belong to DevicePath.h
+typedef struct _USB_DEVICE_PATH {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 ParentPortNumber;
+ UINT8 InterfaceNumber;
+} USB_DEVICE_PATH;
+*/
+
+// Union of all possible device paths
+typedef union {
+ EFI_DEVICE_PATH_PROTOCOL DevPath;
+ PCI_DEVICE_PATH Pci;
+// PCCARD_DEVICE_PATH PcCard;
+// MEMMAP_DEVICE_PATH MemMap;
+ VENDOR_DEVICE_PATH Vendor;
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor;
+ CONTROLLER_DEVICE_PATH Controller;
+// ACPI_HID_DEVICE_PATH Acpi;
+ ACPI_HID_DEVICE_PATH Acpi;
+ ATAPI_DEVICE_PATH Atapi;
+ SCSI_DEVICE_PATH Scsi;
+ FIBRECHANNEL_DEVICE_PATH FibreChannel;
+ F1394_DEVICE_PATH F1394;
+ USB_DEVICE_PATH Usb;
+ USB_CLASS_DEVICE_PATH UsbClass;
+ I20_DEVICE_PATH I20;
+// MAC_ADDR_DEVICE_PATH MacAddr;
+ IPv4_DEVICE_PATH Ipv4;
+ IPv6_DEVICE_PATH Ipv6;
+ INFINIBAND_DEVICE_PATH InfiniBand;
+ UART_DEVICE_PATH Uart;
+ HARDDRIVE_DEVICE_PATH HardDrive;
+ CDROM_DEVICE_PATH CD;
+// FILEPATH_DEVICE_PATH FilePath;
+// MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
+// BBS_BBS_DEVICE_PATH Bbs;
+} EFI_DEV_PATH;
+
+#define HARDWARE_DEVICE_PATH 0x01
+#define HW_VENDOR_DP 0x04
+#define MESSAGING_DEVICE_PATH 0x03
+#define MSG_ATAPI_DP 0x01
+#define HW_CONTROLLER_DP 0x05
+#define MSG_SCSI_DP 0x02
+#define MSG_1394_DP 0x04
+#define MSG_FIBRECHANNEL_DP 0x03
+
+typedef struct {
+ UINT16 StructureSize;
+ UINT16 Flags;
+ UINT32 MaxCylinders;
+ UINT32 MaxHeads;
+ UINT32 SectorsPerTrack;
+ UINT64 PhysicalSectors;
+ UINT16 BytesPerSector;
+ UINT32 FDPT;
+ UINT16 Key;
+ UINT8 DevicePathLength;
+ UINT8 Reserved1;
+ UINT16 Reserved2;
+ CHAR8 HostBusType[4];
+ CHAR8 InterfaceType[8];
+ EDD_INTERFACE_PATH InterfacePath;
+ EDD_DEVICE_PATH DevicePath;
+ UINT8 Reserved3;
+ UINT8 Checksum;
+} EDD_DRIVE_PARAMETERS;
+
+// Flag definitions for above
+#define EDD_GEOMETRY_VALID 0x02
+#define EDD_DEVICE_REMOVABLE 0x04
+#define EDD_WRITE_VERIFY_SUPPORTED 0x08
+#define EDD_DEVICE_CHANGE 0x10
+#define EDD_DEVICE_LOCKABLE 0x20
+
+// For WIN98 limitation
+#define EDD_DEVICE_GEOMETRY_MAX 0x40
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EDD_DEVICE_ADDRESS_PACKET
+//
+// Description: Device address packet used during EDD data transfers
+//
+// Fields:
+// PacketSizeInBytes UINT8 Packet size in bytes
+// Zero UINT8
+// NumberOfBlocks UINT8 # of blocks to transfer
+// Zero2 UINT8
+// SegOffset UINT32 Data address below 1MB
+// LBA UINT64 Device Logical Block Address
+// TransferBuffer UINT64 Transfer Buffer
+// ExtendedBlockCount UINT32 Transferred blocks counter
+// Zero3 UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT8 PacketSizeInBytes; // 0x18
+ UINT8 Zero;
+ UINT8 NumberOfBlocks; // Max 0x7f
+ UINT8 Zero2;
+ UINT32 SegOffset;
+ UINT64 LBA;
+ UINT64 TransferBuffer;
+ UINT32 ExtendedBlockCount; // Max 0xffffffff
+ UINT32 Zero3;
+} EDD_DEVICE_ADDRESS_PACKET;
+
+#define UNKNOWN_DEVICE_GUID \
+ { 0xcf31fac5, 0xc24e, 0x11d2, 0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b }
+
+#define EDD_VERSION_30 0x30
+
+// Int 13 Error Messages
+#define ERR_PASS 0x00
+#define ERR_WRITE_PROTECTED 0x03
+#define ERR_SECTOR_NOT_FOUND 0x04
+#define ERR_RESET_FAILED 0x05
+#define ERR_DISK_CHANGED 0x06
+#define ERR_DRIVE_DOES_NOT_EXIST 0x07
+#define ERR_DMA_ERROR 0x08
+#define ERR_DATA_BOUNADRY_ERROR 0x09
+#define ERR_BAD_SECTOR 0x0a
+#define ERR_BAD_TRACK 0x0b
+#define ERR_MEDIA_TYPE_NOT_FOUND 0x0c
+#define ERR_INVALID_FORMAT 0x0d
+#define ERR_ECC_ERROR 0x10
+#define ERR_ECC_CORRECTED_ERROR 0x11
+#define ERR_HARD_DRIVE_FAILURE 0x20
+#define ERR_SEEK_FAILED 0x40
+#define ERR_DRIVE_TIMEOUT 0x80
+#define ERR_DRIVE_NOT_READY 0xaa
+#define ERR_UNDEFINED_ERROR 0xbb
+#define ERR_WRITE_FAULT 0xcc
+#define ERR_SENSE_FAILED 0xff
+
+#define MAX_EDD11_XFER 0xfe00
+
+// PCI classes not defined in PCI.h
+#define PCI_BASE_CLASS_INTELLIGENT 0x0e
+#define PCI_SUB_CLASS_INTELLIGENT 0x00
+
+#define EFI_SEGMENT(_Adr) (UINT16)((UINT16) (((UINTN)(_Adr)) >> 4) & 0xf000)
+#define EFI_OFFSET(_Adr) (UINT16)(((UINT16)((UINTN)_Adr)) & 0xffff)
+
+#pragma pack()
+
+// Local data structures
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CSM_LEGACY_DRIVE
+//
+// Description: Hard drive data structure
+//
+// Fields:
+// Letter CHAR8 Drive letter
+// Number UINT8 INT13 drive handle
+// EddVersion UINT8 EDD version supported by the drive
+// ExtendedInt13 BOOLEAN Extended INT13 support status
+// DriveLockingAndEjecting BOOLEAN Locking/Ejecting support
+// Edd BOOLEAN EDD support status
+// Extensions64Bit BOOLEAN 64 bit extension support
+// ParametersValid BOOLEAN Valid parameters (Parameters field) indicator
+// ErrorCode UINT8 Error code field
+// FdptPointer VOID* Pointer to FDPT
+// Floppy BOOLEAN Device-is-a-floppy indicator
+// AtapiFloppy BOOLEAN Device-is-an-ATAPI-floppy indicator
+// MaxHead UINT8 Number of heads
+// MaxSector UINT8 Number of sectors
+// MaxCylinder UINT16 Number of cylinders
+// Pad UINT16
+// Parameters EDD_DRIVE_PARAMETERS EDD drive parameters
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ CHAR8 Letter;
+ UINT8 Number;
+ UINT8 EddVersion;
+ BOOLEAN ExtendedInt13;
+ BOOLEAN DriveLockingAndEjecting;
+ BOOLEAN Edd;
+ BOOLEAN Extensions64Bit;
+ BOOLEAN ParametersValid;
+ UINT8 ErrorCode;
+ VOID *FdptPointer;
+ BOOLEAN Floppy;
+ BOOLEAN AtapiFloppy;
+ UINT8 MaxHead;
+ UINT8 MaxSector;
+ UINT16 MaxCylinder;
+ UINT16 Pad;
+ EDD_DRIVE_PARAMETERS Parameters;
+} CSM_LEGACY_DRIVE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CSM_BLOCK_IO_DEV
+//
+// Description: CSM BlockIo device properies
+//
+// Fields:
+// BlockIo EFI_BLOCK_IO_PROTOCOL BlockIo protocol instance
+// Handle EFI_HANDLE EFI device handle
+// ControllerHandle EFI_HANDLE EFI controller handle
+// BlockMedia EFI_BLOCK_IO_MEDIA BlockIo device media
+// DevicePath EFI_DEVICE_PATH_PROTOCOL* Device path
+// PciIo EFI_PCI_IO_PROTOCOL* Device PciIo
+// LegacyBios EFI_LEGACY_BIOS_PROTOCOL* Legacy Bios instance pointer
+// Drive CSM_LEGACY_DRIVE Drive data pointer
+// HwInt UINT8 Hardware interrupt used by this device
+// HwIntHandler UINT32 Storage for the original HW interrupt
+//
+// Referrals: CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ EFI_BLOCK_IO_PROTOCOL BlockIo;
+ EFI_HANDLE Handle;
+ EFI_HANDLE ControllerHandle;
+ EFI_BLOCK_IO_MEDIA BlockMedia;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ CSM_LEGACY_DRIVE Drive;
+ UINT8 HwInt;
+ UINT32 HwIntHandler;
+} CSM_BLOCK_IO_DEV;
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmInt13.c b/Core/EM/CSM/thunk/BlockIo/CsmInt13.c
new file mode 100644
index 0000000..8e3195e
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmInt13.c
@@ -0,0 +1,1525 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmInt13.c 17 12/23/13 3:14p Olegi $
+//
+// $Revision: 17 $
+//
+// $Date: 12/23/13 3:14p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmInt13.c $
+//
+// 17 12/23/13 3:14p Olegi
+// EIP148138: use AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL instead of
+// EFI_MBR_WRITE_PROTECTION_PROTOCOL
+//
+// 16 12/23/13 10:22a Olegi
+// EIP148123: CSM includes file which name has been changed
+//
+// 15 7/01/13 5:56a Kapilporwal
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] Please support Boot Sector Virus Protection for CSM
+// Disabled Mode
+// [Files] VirusProtect.c, VirusProtect.dxs, AhciBus.c,
+// AhciController.c, CsmBlockIo.c, CsmInt13.c, Ata.c, IdeBus.c,
+// SdioBlkIo.c, SdioDriver.c, efiusbmass.c
+//
+// 14 3/09/12 3:22a Deepthins
+// [TAG] EIP73940
+// [Category] Improvement
+// [Description] CSM BlockIo functions, ReadBlock and WriteBlock should
+// return EFI_INVALID_PARAMETER if alignment is not proper.
+// [Files] CsmInt13.c
+//
+// 13 5/27/11 5:47a Rameshr
+// [TAG]- EIP 58687
+// [Category]-IMPROVEMENT
+// [Description]- Update implementation of EFI_BLOCK_IO_PROTOCOL as
+// described in UEFI specification v 2.3.1, page 12.8
+// [Files]- CsmInt13.c
+//
+// 12 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 11 5/09/08 10:37a Olegi
+// Low memory segment is normalized before INT13 execution.
+//
+// 10 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 9 12/07/06 4:00p Olegi
+//
+// 8 3/13/06 2:38p Felixp
+//
+// 7 10/13/05 6:20p Olegi
+// Added HW interrupt handling.
+//
+// 6 9/06/05 11:55a Olegi
+//
+// 5 6/26/05 7:19a Olegi
+// Actual drive parameters size is used while copying extended drive
+// parameters data.
+//
+// 4 3/04/05 1:43p Mandal
+//
+// 3 3/02/05 8:24a Olegi
+//
+// 2 2/21/05 9:33a Olegi
+//
+// 1 2/15/05 10:59a Olegi
+// Initial VSS check-in.
+//
+//
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmInt13.c
+//
+// Description: CSM Block I/O module. Support module containing reset,
+// flush, read and write functions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "CsmBlockIo.h"
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+#include <Protocol\AmiBlockIoWriteProtection.h>
+extern AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL *gBlockIoWriteProtectionProtocol;
+#endif
+
+//extern EFI_BOOT_SERVICES *pBS;
+extern EFI_GUID gEfiBlockIoProtocolGuid;
+
+// Global variables
+
+// Packet buffer under 1 MB for all version EDD calls
+extern EDD_DEVICE_ADDRESS_PACKET *mEDDPacketBuffer;
+
+// This is a buffer for INT 13h func 48 information
+extern CSM_LEGACY_DRIVE *mDriveParameterBuffer;
+
+// EDD 1.1 transfer buffer
+extern VOID *mEDDTransferBuffer;
+
+// Local function prototypes
+BOOLEAN
+GetInt13DeviceParameters (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+);
+
+BOOLEAN
+GetInt13Extensions (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+);
+
+BOOLEAN
+GetDriveParameters (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+);
+
+VOID
+PatchHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+);
+
+VOID
+RestoreHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+);
+
+UINT32 gTempHwIntSav;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InitBlockIo
+//
+// Description: Initializes BlockIo protocol for a given device
+//
+// Input: Device to initialize
+//
+// Output: TRUE initialization succeeded, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, GetInt13DeviceParameters, GetInt13Extensions
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+InitBlockIo (
+ IN CSM_BLOCK_IO_DEV *Dev
+)
+{
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_BLOCK_IO_MEDIA *BlockMedia;
+ CSM_LEGACY_DRIVE *Drive;
+
+ BlockIo = &Dev->BlockIo;
+ BlockIo->Media = &Dev->BlockMedia;
+ BlockMedia = BlockIo->Media;
+ Drive = &Dev->Drive;
+
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ BlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ } else {
+ BlockIo->Revision = 1;
+ }
+#else
+ BlockIo->Revision = 1;
+#endif
+
+ if (GetInt13DeviceParameters (Dev, Drive)) {
+ if (GetInt13Extensions (Dev, Drive)) {
+ BlockMedia->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ BlockMedia->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+
+ if ((Drive->Parameters.Flags & EDD_DEVICE_REMOVABLE) == EDD_DEVICE_REMOVABLE) {
+ BlockMedia->RemovableMedia = TRUE;
+ }
+
+ } else {
+ // No extensions, use Legacy parameters.
+ BlockMedia->BlockSize = 512;
+ BlockMedia->LastBlock = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1) - 1;
+ }
+
+// TRACE((-1," BlockSize = %d LastBlock = %d\n", BlockMedia->BlockSize, BlockMedia->LastBlock));
+
+ BlockMedia->LogicalPartition = FALSE;
+ BlockMedia->WriteCaching = FALSE;
+
+ BlockMedia->ReadOnly = FALSE; // Set for removable media in case no media present
+ BlockMedia->MediaPresent = TRUE; // ditto
+
+ BlockIo->Reset = CsmBlockIoReset;
+ BlockIo->FlushBlocks = CsmBlockIoFlushBlocks;
+
+ // Need logic here to test for EDD and set read/write functions if so
+ if (!Drive->ExtendedInt13) {
+ // No Int 13 extensions, use Legacy functions
+ BlockIo->ReadBlocks = LegacyCsmReadBlocks;
+ BlockIo->WriteBlocks = LegacyCsmWriteBlocks;
+/* } else if ((Drive->EddVersion == EDD_VERSION_30) && (Drive->Extensions64Bit)) {
+ // Use EDD 3.0 functions
+ BlockIo->ReadBlocks = Edd30CsmReadBlocks;
+ BlockIo->WriteBlocks = Edd30CsmWriteBlocks;
+*/
+ } else {
+ // Assume EDD 1.1 Read and Write functions.
+ BlockIo->ReadBlocks = Edd11CsmReadBlocks;
+ BlockIo->WriteBlocks = Edd11CsmWriteBlocks;
+ }
+
+ BlockMedia->LogicalPartition = FALSE;
+ BlockMedia->WriteCaching = FALSE;
+
+ //
+ // Check for Core Version > 4.6.5.0
+ //
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ //
+ // Default value set to 1 logical blocks per PhysicalBlock
+ //
+ BlockMedia->LogicalBlocksPerPhysicalBlock=1;
+
+ //
+ // Default value set to 0 for Lowest Aligned LBA
+ //
+ BlockMedia->LowestAlignedLba=0;
+
+ BlockMedia->OptimalTransferLengthGranularity=BlockMedia->BlockSize;
+ }
+
+#endif
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetInt13DeviceParameters
+//
+// Description: Get hard drive parameters using INT13 function 8
+//
+// Input: BlockIo device, Drive
+//
+// Output: TRUE if operation is successful, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetInt13DeviceParameters (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+)
+{
+ BOOLEAN CarryFlag;
+ UINT16 Cylinder;
+ EFI_IA32_REGISTER_SET Regs;
+
+ Regs.H.AH = 0x08;
+ Regs.H.DL = Drive->Number;
+ PatchHwInterrupt(CsmBlockIoDev);
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ RestoreHwInterrupt(CsmBlockIoDev);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+// TRACE((-1," GetInt13DeviceParameters: 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->AtapiFloppy = TRUE;
+ } else {
+ Drive->MaxHead = Regs.H.DH;
+ Drive->MaxSector = Regs.H.CL;
+ Drive->MaxCylinder = Regs.H.CH;
+ if (Drive->MaxSector == 0) {
+ return FALSE;
+ }
+ }
+ } else {
+ Drive->MaxHead = (UINT8)(Regs.H.DH & 0x3f);
+ Cylinder = (UINT16)(((UINT16)Regs.H.DH & 0xc0) << 4);
+ Cylinder |= (UINT16)(((UINT16)Regs.H.CL & 0xc0) << 2);
+ Drive->MaxCylinder = (UINT16)(Cylinder + Regs.H.CH);
+ Drive->MaxSector = (UINT8)(Regs.H.CL & 0x3f);
+ }
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetInt13Extensions
+//
+// Description: Executes INT13 func 41 to check EDD extensions
+//
+// Input: BlockIo device, Drive
+//
+// Output: TRUE if operation is successful, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetInt13Extensions(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+)
+{
+ BOOLEAN CarryFlag;
+ EFI_IA32_REGISTER_SET Regs;
+
+ Regs.H.AH = 0x41;
+ Regs.X.BX = 0x55aa;
+ Regs.H.DL = Drive->Number;
+ PatchHwInterrupt(CsmBlockIoDev);
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ RestoreHwInterrupt(CsmBlockIoDev);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+// TRACE((-1, " GetInt13Extensions: 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(CsmBlockIoDev, Drive);
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetDriveParameters
+//
+// Description: Executes INT13 function 48 to get hard disk parameters
+//
+// Input: BlockIo device, Drive
+//
+// Output: TRUE if operation is successful, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetDriveParameters(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+)
+{
+ BOOLEAN CarryFlag;
+ EFI_IA32_REGISTER_SET Regs;
+ UINTN PointerMath;
+ UINT8 Temp;
+ UINT8 FloppyTable [] = {
+ 1, 9, 79, // Type 3 -- 720 Kb
+ 1, 18, 79, // Type 4 -- 1.44 Mb
+ 0, 1, 0, // No type 5
+ 1, 36, 79, // Type 6 -- 2.88 Mb
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 9, 39, // Type C -- 360 Kb
+ 1, 15, 79 // Type D -- 1.2 Mb
+ };
+
+ Regs.H.AH = 0x48;
+ Regs.H.DL = Drive->Number;
+
+ // Get Int13 Parameters
+ mDriveParameterBuffer->Parameters.StructureSize = sizeof(EDD_DRIVE_PARAMETERS);
+ Regs.X.DS = EFI_SEGMENT(&mDriveParameterBuffer->Parameters);
+ Regs.X.SI = EFI_OFFSET(&mDriveParameterBuffer->Parameters);
+
+ PatchHwInterrupt(CsmBlockIoDev);
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+ if (CarryFlag || Regs.H.AH != 0x00) {
+ RestoreHwInterrupt(CsmBlockIoDev);
+ Drive->ErrorCode = Regs.H.AH;
+ pBS->SetMem(&Drive->Parameters, sizeof(Drive->Parameters), 0xaf);
+ return FALSE;
+ }
+
+// Copy parameters into real mode buffer
+ pBS->SetMem (&Drive->Parameters, sizeof(Drive->Parameters), 0);
+ pBS->CopyMem (
+ &Drive->Parameters,
+ &mDriveParameterBuffer->Parameters,
+ mDriveParameterBuffer->Parameters.StructureSize // updated by int 13 call
+ );
+
+ if (Drive->AtapiFloppy) {
+
+ // Get Media type
+ Regs.H.AH = 0x20;
+ Regs.H.DL = Drive->Number;
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+ if (CarryFlag) {
+
+ // Unknown or no media present
+ if ((Drive->Parameters.Flags & EDD_GEOMETRY_VALID) == EDD_GEOMETRY_VALID) {
+ Drive->MaxHead = (UINT8)(Drive->Parameters.MaxHeads - 1);
+ Drive->MaxSector = (UINT8)Drive->Parameters.SectorsPerTrack;
+ ASSERT(Drive->MaxSector != 0);
+ Drive->MaxCylinder = (UINT16)(Drive->Parameters.MaxCylinders - 1);
+ } else {
+ Drive->MaxHead = 0;
+ Drive->MaxSector = 1;
+ Drive->MaxCylinder = 0;
+ }
+
+ } else {
+
+ // Media present -- get parameters
+ Drive->MaxHead = 0;
+ Drive->MaxSector = 1;
+ Drive->MaxCylinder = 0; // Assume unknown media
+ if(Regs.H.AL != 10) {
+ if((Regs.H.AL >= 3) && (Regs.H.AL <= 0xd)) {
+ Temp = (Regs.H.AL - 3) * 3; // First drive type is 3
+ Drive->MaxHead = FloppyTable[Temp];
+ Drive->MaxSector = FloppyTable[Temp+1];
+ Drive->MaxCylinder = FloppyTable[Temp+2];
+ }
+ } else {
+ if ((Drive->Parameters.Flags & EDD_GEOMETRY_VALID) == EDD_GEOMETRY_VALID) {
+ Drive->MaxHead = (UINT8)(Drive->Parameters.MaxHeads - 1);
+ Drive->MaxSector = (UINT8)Drive->Parameters.SectorsPerTrack;
+ ASSERT(Drive->MaxSector != 0);
+ Drive->MaxCylinder = (UINT16)(Drive->Parameters.MaxCylinders - 1);
+ } else {
+ Drive->MaxHead = 0;
+ Drive->MaxSector = 1;
+ Drive->MaxCylinder = 0;
+ }
+ }
+ }
+ Drive->Parameters.PhysicalSectors = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1);
+ Drive->Parameters.BytesPerSector = 512;
+ }
+
+ // This data comes from the BIOS so it may not allways be valid
+ // since the BIOS may reuse this buffer for future accesses
+ PointerMath = EFI_SEGMENT(Drive->Parameters.FDPT) << 4;
+ PointerMath += EFI_OFFSET(Drive->Parameters.FDPT);
+ Drive->FdptPointer = (VOID *)PointerMath;
+
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return TRUE;
+}
+
+// BLOCK I/O FUNCTIONS
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CsmBlockIoFlushBlocks
+//
+// Description: BlockIo protocol function that flushes data onto the device
+//
+// Input: Instance of the EFI_BLOCK_IO_PROTOCOL
+//
+// Output: Status of the operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CsmBlockIoFlushBlocks
+//
+// Description: BlockIo protocol function that resets the device
+//
+// Input:
+// Instance of the EFI_BLOCK_IO_PROTOCOL
+// ExtendedVerification request
+//
+// Output: Status of the operation
+//
+// Referrals: CSM_BLOCK_IO_DEV, EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EFI_IA32_REGISTER_SET Regs;
+ BOOLEAN CarryFlag;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ Regs.H.AH = 0x00;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, " CsmBlockIoReset: INT 13 00 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ if (CarryFlag) {
+ if (Regs.H.AL == ERR_RESET_FAILED) {
+ Regs.H.AH = 0x00;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "CsmBlockIoReset: INT 13 00 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ if (CarryFlag) {
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+ }
+
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd30CsmReadBlocks
+//
+// Description: Read device using EDD3.0 read function
+//
+// Input: BlockIo protocol instance, Media ID, read data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd30CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket; // I exist only for readability
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+// Check for error conditions
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+ if (BufferSize == 0) return EFI_SUCCESS;
+
+// CsmBlockIoDev = ((CSM_BLOCK_IO_DEV *) ((CHAR8 *)(This) - (CHAR8 *) &(((CSM_BLOCK_IO_DEV *) 0)->BlockIo)));
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ TransferBuffer = (UINT64)Buffer;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize/BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+ AddressPacket->SegOffset = 0xffffffff;
+ AddressPacket->LBA = (UINT64)LBA;
+ AddressPacket->TransferBuffer = TransferBuffer;
+
+ Regs.H.AH = 0x42;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, " Edd30CsmReadBlocks: INT 13 42 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ BufferSize = BufferSize - TransferByteSize;
+ TransferBuffer += TransferByteSize;
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd30CsmWriteBlocks
+//
+// Description: Write device using EDD3.0 write function
+//
+// Input: BlockIo protocol instance, Media ID, write data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd30CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+ if (BufferSize == 0) return EFI_SUCCESS;
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ TransferBuffer = (UINT64)Buffer;
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize/BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+ AddressPacket->SegOffset = 0xffffffff;
+ AddressPacket->LBA = (UINT64)LBA;
+ AddressPacket->TransferBuffer = TransferBuffer;
+
+ Regs.H.AH = 0x43;
+ Regs.H.AL = 0x00; // Write Verify Off
+ Regs.H.DL = (UINT8)(CsmBlockIoDev->Drive.Number);
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, " Edd30CsmWriteBlocks: INT 13 43 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ } else if (CsmBlockIoDev->Drive.ErrorCode == ERR_WRITE_PROTECTED) {
+ Media->ReadOnly = TRUE;
+ return EFI_WRITE_PROTECTED;
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Media->ReadOnly = FALSE;
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ BufferSize = BufferSize - TransferByteSize;
+ TransferBuffer += TransferByteSize;
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+// Older read/write methods
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd11CsmReadBlocks
+//
+// Description: Read device using EDD1.1 read function
+//
+// Input: BlockIo protocol instance, Media ID, read data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd11CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 AlignedOffset;
+ UINT16 AlignedSegment;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ TransferBuffer = (UINT64)mEDDTransferBuffer;
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize / BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+
+ //
+ // Normalize TransferBuffer address if needed
+ //
+ AlignedOffset = EFI_OFFSET(TransferBuffer);
+ AlignedSegment = EFI_SEGMENT(TransferBuffer);
+ if(AlignedOffset != 0) {
+ AlignedSegment = AlignedSegment + (AlignedOffset >> 4);
+ AlignedOffset = 0;
+ }
+
+ AddressPacket->SegOffset = AlignedSegment << 16;
+ AddressPacket->SegOffset |= AlignedOffset;
+
+ AddressPacket->LBA = (UINT64)LBA;
+
+ Regs.H.AH = 0x42;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "Edd11CsmReadBlocks: INT 13 42 DL=%02x : CF=%d AH=%02x : LBA 0x%lx Block(s) %0d \n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH, LBA, NumberOfBlocks));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ // The media has changed.
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem (Buffer, (VOID *)(UINTN)TransferBuffer, TransferByteSize);
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd11CsmWriteBlocks
+//
+// Description: Write device using EDD1.1 write function
+//
+// Input: BlockIo protocol instance, Media ID, write data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd11CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket; // I exist only for readability
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 AlignedOffset;
+ UINT16 AlignedSegment;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ TransferBuffer = (UINT64)mEDDTransferBuffer;
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize/BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+
+ //
+ // Normalize TransferBuffer address if needed
+ //
+ AlignedOffset = EFI_OFFSET(TransferBuffer);
+ AlignedSegment = EFI_SEGMENT(TransferBuffer);
+
+ if (AlignedOffset != 0) {
+ AlignedSegment = AlignedSegment + (AlignedOffset >> 4);
+ AlignedOffset = 0;
+ }
+
+ AddressPacket->SegOffset = AlignedSegment << 16;
+ AddressPacket->SegOffset |= AlignedOffset;
+
+ AddressPacket->LBA = (UINT64)LBA;
+
+ Regs.H.AH = 0x43;
+ Regs.H.AL = 0x00; // Write Verify disable
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem ((VOID *)(UINTN)TransferBuffer, Buffer, TransferByteSize);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "Edd11CsmWriteBlocks: INT 13 43 DL=%02x : CF=%d AH=%02x\n: LBA 0x%lx Block(s) %0d \n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH, LBA, NumberOfBlocks));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ // The media has changed.
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ } else if (CsmBlockIoDev->Drive.ErrorCode == ERR_WRITE_PROTECTED) {
+ Media->ReadOnly = TRUE;
+ Status = EFI_WRITE_PROTECTED;
+ goto Exit;
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Media->ReadOnly = FALSE;
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: LegacyCsmReadBlocks
+//
+// Description: Read device using INT13 function 2
+//
+// Input: BlockIo protocol instance, Media ID, read data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacyCsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EFI_IA32_REGISTER_SET Regs;
+ UINTN UpperCylinder, Temp;
+ UINTN Cylinder, Head, Sector;
+ UINTN NumberOfBlocks, TransferByteSize;
+ UINTN ShortLba, CheckLba;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN Retry;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ ShortLba = (UINTN) LBA;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ while (BufferSize) {
+ // Convert LBA to CHS.
+ Sector = (ShortLba % CsmBlockIoDev->Drive.MaxSector) + 1;
+ Temp = ShortLba / CsmBlockIoDev->Drive.MaxSector;
+ Head = Temp % (CsmBlockIoDev->Drive.MaxHead + 1);
+ Cylinder = Temp / (CsmBlockIoDev->Drive.MaxHead + 1);
+ // Limit number of blocks to one head and cylindar
+ NumberOfBlocks = BufferSize/BlockSize;
+ Temp = CsmBlockIoDev->Drive.MaxSector - Sector + 1;
+ NumberOfBlocks = NumberOfBlocks > Temp ? Temp : NumberOfBlocks;
+
+ Retry = 3;
+ // Loop to perform the read
+ do {
+ Regs.H.AH = 2;
+ Regs.H.AL = (UINT8) NumberOfBlocks;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+
+ UpperCylinder = (Cylinder & 0x0f00) >> 2;
+
+ CheckLba = Cylinder*(CsmBlockIoDev->Drive.MaxHead + 1) + Head;
+ CheckLba = CheckLba*CsmBlockIoDev->Drive.MaxSector + Sector - 1;
+
+// ASSERT(CheckLba == ShortLba);
+
+ Regs.H.CL = (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff));
+ Regs.H.DH = (UINT8) (Head & 0x3f);
+ Regs.H.CH = (UINT8) (Cylinder & 0xff);
+
+ Regs.X.BX = EFI_OFFSET(mEDDTransferBuffer);
+ Regs.X.ES = EFI_SEGMENT(mEDDTransferBuffer);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "LegacyCsmReadBlocks: INT 13 02 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Retry--;
+ } while (CarryFlag && Retry !=0 && Regs.H.AH != ERR_DISK_CHANGED);
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ // The media has changed
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ Media->LastBlock = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1) - 1;
+ Media->BlockSize = 512;
+ }
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem (Buffer, mEDDTransferBuffer, TransferByteSize);
+
+ ShortLba = ShortLba + NumberOfBlocks;
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: LegacyCsmWriteBlocks
+//
+// Description: Write device using INT13 function 3
+//
+// Input: BlockIo protocol instance, Media ID, write data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacyCsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EFI_IA32_REGISTER_SET Regs;
+ UINTN UpperCylinder, Temp;
+ UINTN Cylinder, Head, Sector;
+ UINTN NumberOfBlocks, TransferByteSize;
+ UINTN ShortLba, CheckLba;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN Retry;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ // Verify if write is allowed
+ if(gBlockIoWriteProtectionProtocol != NULL) {
+ Status = gBlockIoWriteProtectionProtocol->BlockIoWriteProtectionCheck(
+ gBlockIoWriteProtectionProtocol,
+ This,
+ LBA,
+ BufferSize
+ );
+
+ // Abort operation if denied
+ if(Status == EFI_ACCESS_DENIED) {
+ return Status;
+ }
+ }
+#endif
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ ShortLba = (UINTN) LBA;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ while(BufferSize) {
+ // Convert LBA to CHS
+ Sector = (ShortLba % CsmBlockIoDev->Drive.MaxSector) + 1;
+ Temp = ShortLba / CsmBlockIoDev->Drive.MaxSector;
+ Head = Temp % (CsmBlockIoDev->Drive.MaxHead + 1);
+ Cylinder = Temp / (CsmBlockIoDev->Drive.MaxHead + 1);
+
+ // Limit number of blocks to one head and cylindar
+ NumberOfBlocks = BufferSize/BlockSize;
+ Temp = CsmBlockIoDev->Drive.MaxSector - Sector + 1;
+ NumberOfBlocks = NumberOfBlocks > Temp ? Temp : NumberOfBlocks;
+
+
+ Retry = 3;
+ // Loop to perform the write.
+ do {
+ Regs.H.AH = 3;
+ Regs.H.AL = (UINT8) NumberOfBlocks;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+
+ UpperCylinder = (Cylinder & 0x0f00) >> 2;
+
+ CheckLba = Cylinder*(CsmBlockIoDev->Drive.MaxHead + 1) + Head;
+ CheckLba = CheckLba*CsmBlockIoDev->Drive.MaxSector + Sector - 1;
+
+// ASSERT(CheckLba == ShortLba);
+
+ Regs.H.CL = (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff));
+ Regs.H.DH = (UINT8) (Head & 0x3f);
+ Regs.H.CH = (UINT8) (Cylinder & 0xff);
+
+ Regs.X.BX = EFI_OFFSET(mEDDTransferBuffer);
+ Regs.X.ES = EFI_SEGMENT(mEDDTransferBuffer);
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem (mEDDTransferBuffer, Buffer, TransferByteSize);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "LegacyCsmWriteBlocks: INT 13 03 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Retry--;
+ } while (CarryFlag && Retry !=0 && Regs.H.AH != ERR_DISK_CHANGED);
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ Media->LastBlock = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1) - 1;
+ Media->BlockSize = 512;
+ }
+ // The media has changed.
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ } else if (CsmBlockIoDev->Drive.ErrorCode == ERR_WRITE_PROTECTED) {
+ Media->ReadOnly = TRUE;
+ Status = EFI_WRITE_PROTECTED;
+ goto Exit;
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ Media->ReadOnly = FALSE;
+ ShortLba = ShortLba + NumberOfBlocks;
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ }
+
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: PatchHwInterrupt
+//
+// Description: Saves HW interrupt vector used by this device
+//
+// Input: BlockIo device
+//
+// Output: None
+//
+// Referrals: CSM_BLOCK_IO_DEV
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+PatchHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+)
+{
+ UINT32 *ivt = (UINT32*)0;
+ if (CsmBlockIoDev->HwInt) {
+ gTempHwIntSav = ivt[CsmBlockIoDev->HwInt];
+ ivt[CsmBlockIoDev->HwInt] = CsmBlockIoDev->HwIntHandler;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: RestoreHwInterrupt
+//
+// Description: Restores HW interrupt saved by PatchHwInterrupt
+//
+// Input: BlockIo device
+//
+// Output: None
+//
+// Referrals: CSM_BLOCK_IO_DEV, PatchHwInterrupt
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+RestoreHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+)
+{
+ UINT32 *ivt = (UINT32*)0;
+ if (CsmBlockIoDev->HwInt) {
+ ivt[CsmBlockIoDev->HwInt] = gTempHwIntSav;
+ }
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/biosblkio.dxs b/Core/EM/CSM/thunk/BlockIo/biosblkio.dxs
new file mode 100644
index 0000000..8a863fa
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/biosblkio.dxs
@@ -0,0 +1,46 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.dxs 1 10/03/11 3:38p Olegi $
+//
+// $Revision: 1 $
+//
+// $Date: 10/03/11 3:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.dxs $
+//
+// 1 10/03/11 3:38p Olegi
+//
+//**********************************************************************
+
+#include <Protocol\LegacyBios.h>
+
+DEPENDENCY_START
+ EFI_LEGACY_BIOS_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/biosblkio.mak b/Core/EM/CSM/thunk/BlockIo/biosblkio.mak
new file mode 100644
index 0000000..879933f
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/biosblkio.mak
@@ -0,0 +1,63 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.mak 3 1/12/10 11:50a Olegi $
+#
+# $Revision: 3 $
+#
+# $Date: 1/12/10 11:50a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.mak $
+#
+# 3 1/12/10 11:50a Olegi
+# Copyright message updated.
+#
+# 2 12/02/05 11:44a Felixp
+#
+# 1 2/15/05 11:00a Olegi
+# Initial VSS check-in.
+#
+#
+#************************************************************************//
+all : CsmBlockIo
+
+CsmBlockIo : $(BUILD_DIR)\biosblkio.mak CsmBlockIoBin
+
+$(BUILD_DIR)\biosblkio.mak : $(CSMBLOCKIO_DIR)\int13thunk.cif $(CSMBLOCKIO_DIR)\biosblkio.mak $(BUILD_RULES)
+ $(CIF2MAK) $(CSMBLOCKIO_DIR)\int13thunk.cif $(CIF2MAK_DEFAULTS)
+
+CsmBlockIoBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\biosblkio.mak all\
+ GUID=25ACF158-DD61-4e64-9A49-55851E9A26C7\
+ ENTRY_POINT=CsmBlockIoEntryPoint \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CSM/thunk/BlockIo/int13thunk.cif b/Core/EM/CSM/thunk/BlockIo/int13thunk.cif
new file mode 100644
index 0000000..24c82f3
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/int13thunk.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "INT13"
+ category = ModulePart
+ LocalRoot = "core\em\csm\thunk\BlockIo"
+ RefName = "BIOSBLKIO"
+[files]
+"CsmInt13.c"
+"CsmBlkIoComponentName.c"
+"CsmBlockIo.c"
+"CsmBlockIo.h"
+"CsmBlockIo.sdl"
+"CsmEdd.h"
+"biosblkio.mak"
+"biosblkio.dxs"
+<endComponent>