diff options
Diffstat (limited to 'MiscFramework/Library/Smm/EfiSmmDriverLib/SmmDriverLib.c')
-rw-r--r-- | MiscFramework/Library/Smm/EfiSmmDriverLib/SmmDriverLib.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/MiscFramework/Library/Smm/EfiSmmDriverLib/SmmDriverLib.c b/MiscFramework/Library/Smm/EfiSmmDriverLib/SmmDriverLib.c new file mode 100644 index 0000000..bb3d8de --- /dev/null +++ b/MiscFramework/Library/Smm/EfiSmmDriverLib/SmmDriverLib.c @@ -0,0 +1,244 @@ +/*++ + This file contains 'Framework Code' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may not be modified, except as allowed by + additional terms of your license agreement. +--*/ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + + +Module Name: + + MgmtModeRuntimeUtils.c + +Abstract: + + Light weight lib to support EFI 2.0 SMM based drivers. + +--*/ + +// GC_TODO: fix comment to set correct module name: SmmDriverLib.c +#include "Tiano.h" +#include "EfiCommonLib.h" +#include "EfiSmmDriverLib.h" +#include EFI_PROTOCOL_DEFINITION (LoadedImage) + +EFI_DEVICE_PATH_PROTOCOL * +EfiAppendDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *Src1, + IN EFI_DEVICE_PATH_PROTOCOL *Src2 + ); + +EFI_STATUS +EfiInitializeSmmDriverLib ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable, + IN OUT BOOLEAN *InSmm + ) +/*++ + +Routine Description: + + Intialize runtime Driver Lib if it has not yet been initialized. + +Arguments: + + (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) + + GoVirtualChildEvent - Caller can register a virtual notification event. + +Returns: + + EFI_STATUS always returns EFI_SUCCESS + +--*/ +// GC_TODO: ImageHandle - add argument and description to function comment +// GC_TODO: SystemTable - add argument and description to function comment +// GC_TODO: InSmm - add argument and description to function comment +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *CompleteFilePath; + EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; + + gSMM = NULL; + mSmmDebug = NULL; + + if ((SystemTable != NULL) && (SystemTable->BootServices != NULL)) { + + gST = SystemTable; + gBS = SystemTable->BootServices; + gRT = SystemTable->RuntimeServices; + + // + // It is OK if the SmmStatusCode Protocol is not found, don't check the status. + // + Status = gBS->LocateProtocol (&gEfiSmmStatusCodeProtocolGuid, NULL, &mSmmDebug); + + Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, &gSMM); + if (EFI_ERROR (Status)) { + return Status; + } + + gSMM->InSmm (gSMM, InSmm); + + if (!(*InSmm)) { + // + // Not in SMM, initialization code is running under DXE environment + // + // + // Load this driver's image to memory + // + if (ImageHandle != NULL) { + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID *) &LoadedImage + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->HandleProtocol ( + LoadedImage->DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID *) &ImageDevicePath + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + CompleteFilePath = EfiAppendDevicePath ( + ImageDevicePath, + LoadedImage->FilePath + ); + // + // Load the image in memory to SMRAM; it will automatically generate the + // SMI. + // + Status = gSMM->Register (gSMM, CompleteFilePath, NULL, 0, &Handle, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + } + } + } + + return EFI_SUCCESS; + +} + +UINTN +EfiDevicePathSize ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +/*++ + +Routine Description: + + GC_TODO: Add function description + +Arguments: + + DevicePath - GC_TODO: add argument description + +Returns: + + GC_TODO: add return values + +--*/ +{ + EFI_DEVICE_PATH_PROTOCOL *Start; + + if (NULL == DevicePath) { + return 0; + } + // + // Search for the end of the device path structure + // + Start = DevicePath; + while (!EfiIsDevicePathEnd (DevicePath)) { + DevicePath = EfiNextDevicePathNode (DevicePath); + } + // + // Compute the size and add back in the size of the end device path structure + // + return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL); +} + +EFI_DEVICE_PATH_PROTOCOL * +EfiAppendDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *Src1, + IN EFI_DEVICE_PATH_PROTOCOL *Src2 + ) +/*++ + +Routine Description: + Function is used to append a Src1 and Src2 together. + +Arguments: + Src1 - A pointer to a device path data structure. + + Src2 - A pointer to a device path data structure. + +Returns: + + A pointer to the new device path is returned. + NULL is returned if space for the new device path could not be allocated from pool. + It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed. + +--*/ +{ + EFI_STATUS Status; + UINTN Size; + UINTN Size1; + UINTN Size2; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath; + + // + // Allocate space for the combined device path. It only has one end node of + // length EFI_DEVICE_PATH_PROTOCOL + // + Size1 = EfiDevicePathSize (Src1); + Size2 = EfiDevicePathSize (Src2); + Size = Size1 + Size2; + + if (Size1 != 0 && Size2 != 0) { + Size -= sizeof (EFI_DEVICE_PATH_PROTOCOL); + } + + Status = gBS->AllocatePool (EfiBootServicesData, Size, (VOID **) &NewDevicePath); + + if (EFI_ERROR (Status)) { + return NULL; + } + + gBS->CopyMem (NewDevicePath, Src1, Size1); + + // + // Over write Src1 EndNode and do the copy + // + if (Size1 != 0) { + SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL))); + } else { + SecondDevicePath = NewDevicePath; + + } + + gBS->CopyMem (SecondDevicePath, Src2, Size2); + + return NewDevicePath; +} |