summaryrefslogtreecommitdiff
path: root/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c')
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c105
1 files changed, 90 insertions, 15 deletions
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
index 14438f5..91d5191 100644
--- a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
@@ -13,16 +13,23 @@
//**********************************************************************
//**********************************************************************
-// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.c 49 8/06/14 1:20p Fasihm $
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.c 51 9/09/15 11:46a Olegi $
//
-// $Revision: 49 $
+// $Revision: 51 $
//
-// $Date: 8/06/14 1:20p $
+// $Date: 9/09/15 11:46a $
//**********************************************************************
// Revision History
// ----------------
// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.c $
//
+// 51 9/09/15 11:46a Olegi
+// [TAG] EIP237391
+// [Description] Aptio4 CSM: CsmBlockIo drive handle is lost
+//
+// 50 9/09/15 11:26a Olegi
+// cleanup
+//
// 49 8/06/14 1:20p Fasihm
// [TAG] EIP180668
// [Category] Bug Fix
@@ -251,16 +258,23 @@ CSM_LEGACY_DRIVE *mDriveParameterBuffer;
// has gOnboardRaidGuid installed on it
//
#define ONBOARD_RAID_GUID \
- { 0x5d206dd3, 0x516a, 0x47dc, 0xa1, 0xbc, 0x6d, 0xa2, 0x4, 0xaa, 0xbe, 0x8};
+ { 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};
+ { 0x1fd29be6, 0x70d0, 0x42a4, {0xa6, 0xe7, 0xe5, 0xd1, 0xe, 0x6a, 0xc3, 0x76}};
EFI_GUID gHddUnlockedGuid = HDD_UNLOCKED_GUID;
+#define LTEB_GUID \
+ {0xC8BCA618, 0xBFC6, 0x46B7, 0x8D, 0x19, 0x83, 0x14, 0xE2, 0xE5, 0x6E, 0xC1}
+
+EFI_GUID gLTEBGuid = LTEB_GUID;
+
+VOID CsmBlockIoComebackFromLegacyBoot(EFI_EVENT, VOID*);
+
//<AMI_PHDR_START>
//**********************************************************************
@@ -720,7 +734,7 @@ CsmBlockIoStart (
}
// Zero the private device structure
- ZeroMemory (PrivateBlockIoStruc, sizeof (CSM_BLOCK_IO_DEV));
+ pBS->SetMem (PrivateBlockIoStruc, sizeof (CSM_BLOCK_IO_DEV), 0);
// Initialize the private device structure
PrivateBlockIoStruc->ControllerHandle = Controller;
@@ -754,11 +768,17 @@ CsmBlockIoStart (
pBS->FreePool (PrivateBlockIoStruc);
}
- // Set handle to which BlockIO has been installed
+ // Set handle and BCV information to which BlockIO has been installed
if (j < NewBbsEntries)
{
*(UINTN*)(&(BbsTable[FirstNewBbsEntry + j].IBV1)) = (UINTN)(PrivateBlockIoStruc->Handle);
+ PrivateBlockIoStruc->BcvSegment = BbsTable[FirstNewBbsEntry + j].BootHandlerSegment;
+ PrivateBlockIoStruc->BcvOffset = BbsTable[FirstNewBbsEntry + j].BootHandlerOffset;
}
+
+ // For Onboard Raid controller use device path protocol
+ // and other Raid controller uses the PciIO protocol.
+
if(OnboardRaidController) {
// Open For Child Device
Status = pBS->OpenProtocol( Controller,
@@ -778,6 +798,18 @@ CsmBlockIoStart (
PrivateBlockIoStruc->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
}
+
+ // Register callback notification on Legacy2Efi. Use PrivateBlockInfoStruc as Context
+
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CsmBlockIoComebackFromLegacyBoot,
+ PrivateBlockIoStruc,
+ &gLTEBGuid,
+ &PrivateBlockIoStruc->Legacy2EfiEvent);
+ ASSERT_EFI_ERROR(Status);
+
} else {
pBS->FreePool (PrivateBlockIoStruc);
}
@@ -884,6 +916,8 @@ CsmBlockIoStop (
This->DriverBindingHandle,
ChildHandleBuffer[i] );
}
+
+ pBS->CloseEvent(PrivateBlockIoStruc->Legacy2EfiEvent);
// Release PCI I/O and Block IO Protocols on the clild handle.
Status = pBS->UninstallMultipleProtocolInterfaces( ChildHandleBuffer[i],
@@ -1048,19 +1082,60 @@ UINTN AlignAddress (UINTN Address)
}
}
-// Zero memory
-VOID ZeroMemory (
- VOID *Buffer,
- UINTN Size
+/**
+ Callback notification on legacy boot return. This function adjusts the INT13 handles
+ that might have been changed during legacy boot.
+
+ @note
+ Control flow:
+ - locate CSM_BLOCK_IO_DEV device
+ - look in IPLDT for this device using BCV Segment/Offset
+ - get the handle index from IPLDT ipld_table_entry.VectorIndex
+ - get the handle from dimVectorMap[32 max]
+ - updates BlockIoDev->Drive->Number with the new handle
+
+**/
+
+#define EFI_CSM_BLOCKIO_MAX_IPLDT_ENTRIES 32
+
+VOID
+CsmBlockIoComebackFromLegacyBoot(
+ EFI_EVENT Event,
+ VOID *Context
)
{
- UINT8 *Ptr;
- Ptr = Buffer;
- while (Size--) {
- *(Ptr++) = 0;
+ CSM_BLOCK_IO_DEV *Device = Context;
+ UINT16 EbdaSeg = *(UINT16*)0x40e;
+ UINT8 *Ebda = (UINT8*)((UINTN)EbdaSeg<<4);
+ UINT8 i;
+ UINT8 *Int13Handles = Ebda + 0x3e0;
+ UINT8 *Ipldt = Ebda + 0x440;
+ UINT8 VectorIndex;
+ UINT8 Handle;
+
+ TRACE((TRACE_ALWAYS, "CsmBlockIo L2E: BCV at %x:%x\n", Device->BcvSegment, Device->BcvOffset));
+ for (i = 0; i < EFI_CSM_BLOCKIO_MAX_IPLDT_ENTRIES; i++)
+ {
+ if (*((UINT16*)(Ipldt+0xe)) == Device->BcvOffset &&
+ (*((UINT16*)(Ipldt + 0x10)) == Device->BcvSegment)) break;
+ Ipldt += 0x40;
+ }
+ if (i == EFI_CSM_BLOCKIO_MAX_IPLDT_ENTRIES)
+ {
+ TRACE((TRACE_ALWAYS, "Entry is not found in IPLDT\n"));
+ return;
}
+
+ VectorIndex = Ipldt[2];
+ Handle = Int13Handles[VectorIndex];
+
+ TRACE((TRACE_ALWAYS, "IPLDT[%x], index %x, handle %x\n", i, VectorIndex, Handle));
+ ASSERT(Handle > 0x7f);
+
+ Device->Drive.Number = Handle;
}
+
//**********************************************************************
//**********************************************************************
//** **