summaryrefslogtreecommitdiff
path: root/Core/EM/CsmOptOut
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/CsmOptOut
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/CsmOptOut')
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.c1039
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.chmbin0 -> 45928 bytes
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.cif15
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.mak106
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.sd252
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.sdl124
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.unibin0 -> 10770 bytes
-rw-r--r--Core/EM/CsmOptOut/CsmOptOutRuntime.c168
-rw-r--r--Core/EM/CsmOptOut/CsmOptOutSetup.c430
9 files changed, 2134 insertions, 0 deletions
diff --git a/Core/EM/CsmOptOut/CsmOptOut.c b/Core/EM/CsmOptOut/CsmOptOut.c
new file mode 100644
index 0000000..b5056cd
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.c
@@ -0,0 +1,1039 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.c 15 11/01/13 9:25p Artems $
+//
+// $Revision: 15 $
+//
+// $Date: 11/01/13 9:25p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.c $
+//
+// 15 11/01/13 9:25p Artems
+// [TAG] EIP126445
+// [Category] Improvement
+// [Description] Added UEFI Only option for OpROMS of unknown types
+// [Files] CsmOptOut.c CsmOptOut.sd CsmOptOut.sdl CsmOptOut.uni
+//
+// 14 7/30/12 10:22a Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Can't disable legacy OpROM execution
+// [RootCause] CsmOptOut didn't check if anybody already disabled OpROM
+// executio
+// [Solution] Added check of ExecuteThisOpROM flag
+// [Files] CsmOptOut.c
+//
+// 13 6/20/12 6:05p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 12 5/21/12 4:46p Artems
+// [TAG] EIP86097
+// [Category] Improvement
+// [Description] Separate control for loading UEFI Oprom Driver
+// [Files] CsmOptOut.c CsmOptOut.mak PciBus.c
+// CsmOptOut.sdl
+//
+// 11 5/10/12 5:42p Artems
+// [TAG] EIP87316
+// [Category] Improvement
+// [Description] Revert previous changes, as the improvement were made
+// in FixedBootOrder module
+// [Files] CsmOptOut.c
+//
+// 10 4/18/12 4:41p Artems
+// [TAG] EIP87316
+// [Category] Improvement
+// [Description] If legacy boot device is filtered it still appears in
+// boot order maintained by FixedBootOrder module
+// [Files] CsmOptOut.c
+//
+// 9 4/05/12 5:14p Artems
+// Removed eLinks to ConnectVga and ConnectEverything. Implemented
+// Platform specific override protocol instead to control OpROM execution
+// sequence
+//
+// 8 3/16/12 6:06p Artems
+// Fixed bug in CsmOptOutConnectEverything function - not all handles were
+// connected
+//
+// 7 3/16/12 5:15p Artems
+// EIP 82586: CSM must not be loaded if Secure Boot is enabled
+//
+// 6 1/27/12 4:34p Artems
+// Restored change killed by previous check-in
+//
+// 5 1/23/12 7:02p Artems
+// Added OpROM handling for PCI devices other than Network, Mass storage
+// or Video
+// Behavior is same as in previous Core versions
+//
+// 3 11/28/11 1:42p Artems
+// EIP 75876: Trying to use Setup variable before NVRAM driver is
+// available
+//
+// 2 11/14/11 3:37p Artems
+// Removed unnecessary Trace
+//
+// 1 11/12/11 2:57p Artems
+// Initial check-in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOut.c
+//
+// Description: This is main file of the CsmOptOut module
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+//----------------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <BootOptions.h>
+#include <AmiLoadCsmPolicy.h>
+#include <Protocol\CsmPlatform.h>
+#include <Protocol\PciIo.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\PlatformDriverOverride.h>
+#include <Protocol\BusSpecificDriverOverride.h>
+#include <Protocol\GraphicsOutput.h>
+
+#define DEFAULT_HANDLE_BUFFER_SIZE 0x40
+typedef struct {
+ UINTN TotalSize;
+ UINTN CurrentSize;
+ EFI_HANDLE *Array;
+} HANDLE_BUFFER;
+
+HANDLE_BUFFER ThunkHandles;
+HANDLE_BUFFER NonThunkHandles;
+static EFI_HANDLE SharedGopHandle = 0;
+static BOOLEAN UefiGopDisconnected = FALSE;
+static BOOLEAN ProceedToBoot = FALSE;
+
+
+EFI_STATUS CsmOptOutGetDriver(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+);
+
+EFI_STATUS CsmOptOutGetDriverWorker(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+);
+
+EFI_STATUS CsmOptOutGetDriverPath(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath
+) { return EFI_UNSUPPORTED; }
+
+EFI_STATUS CsmOptOutDriverLoaded(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath,
+ IN EFI_HANDLE DriverImageHandle
+) { return EFI_UNSUPPORTED; }
+
+static EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL CsmOptOutPlatformDriverOverride = {
+ CsmOptOutGetDriver,
+ CsmOptOutGetDriverPath,
+ CsmOptOutDriverLoaded
+};
+
+
+//----------------------------------------------------------------------------
+
+static EFI_GUID SetupGuid = SETUP_GUID;
+static EFI_GUID AmiLoadCsmGuid = AMI_LOAD_CSM_GUID;
+static EFI_GUID OpRomStartEndProtocolGuid = OPROM_START_END_PROTOCOL_GUID;
+static EFI_GUID AmiCsmThunkProtocolGuid = AMI_CSM_THUNK_PROTOCOL_GUID;
+static EFI_GUID AmiOpromPolicyProtocolGuid = AMI_OPROM_POLICY_PROTOCOL_GUID;
+extern EFI_GUID BdsAllDriversConnectedProtocolGuid;
+
+UINT8 CurrentCsmState;
+VOID *ProcessOpRomRegistration;
+VOID *DriverBindingRegistration;
+static UINTN CurrentCount = 0;
+static EFI_HANDLE CurrentHandle = 0;
+static EFI_HANDLE LastReturnedImageHandle = 0;
+static BOOLEAN TransactionInProgress;
+static BOOLEAN ThunkFirst;
+
+typedef EFI_STATUS (OEM_CHECK_UEFI_OPROM_POLICY) (EFI_HANDLE PciHandle);
+extern OEM_CHECK_UEFI_OPROM_POLICY OEM_CHECK_UEFI_OPROM_POLICY_LIST EndOfList;
+OEM_CHECK_UEFI_OPROM_POLICY* OemCheckUefiOpromPolicyList[] = { OEM_CHECK_UEFI_OPROM_POLICY_LIST NULL };
+
+EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecific = NULL;
+
+typedef struct CSM_OPTOUT_SETUP_DATA {
+ UINT8 CsmLaunchPolicy;
+ UINT8 BootOptionFilter;
+ UINT8 PxeOpRom;
+ UINT8 MassStorageOpRom;
+ UINT8 VideoOpRom;
+/*
+ We added the following field to preserve functionality existed in previous
+ PciBus versions. For PCI devices other than Network,Mass Storage or Video
+ value of following field will determine OpROM behavior as before.
+*/
+ UINT8 OldOpRom;
+} CSM_OPTOUT_SETUP_DATA;
+
+CSM_OPTOUT_SETUP_DATA CsmOptOutSetupData = {
+ DEFAULT_CSM_LAUNCH_POLICY,
+ DEFAULT_BOOT_OPTION_FILTERING_POLICY,
+ DEFAULT_PXE_OPROM_POLICY,
+ DEFAULT_MASS_STORAGE_OPROM_POLICY,
+ DEFAULT_VIDEO_OPROM_POLICY,
+ 1
+};
+
+EFI_STATUS CheckUefiOpRomPolicy(
+ IN AMI_OPROM_POLICY_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle
+);
+
+AMI_OPROM_POLICY_PROTOCOL AmiOpRomPolicyProtocol = {
+ CheckUefiOpRomPolicy
+};
+
+EFI_STATUS AddHandle(
+ IN OUT HANDLE_BUFFER *Target,
+ EFI_HANDLE Handle
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CsmOptOutFilter
+//
+// Description: This function filters available boot options based on Setup
+// control value
+//
+// Input:
+// IN BOOT_DEVICE *Device - pointer to boot device
+//
+// Output:
+// TRUE - boot option will be removed from boot list
+// FALSE - boot option won't be removed from boot list
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CsmOptOutFilter(
+ IN BOOT_DEVICE *Device
+)
+{
+ BOOLEAN Result = FALSE;
+
+ if(CurrentCsmState == 0) //CSM is disabled on current boot - no need to filter boot options
+ return Result;
+
+ switch (CsmOptOutSetupData.BootOptionFilter) {
+ case 0: // Enable all boot options
+ break;
+
+ case 1: // Disable UEFI boot options
+ Result = (Device->BbsEntry == NULL);
+ break;
+
+ case 2: // Disable Legacy boot options
+ Result = (Device->BbsEntry != NULL);
+ break;
+
+ default:
+ break;
+ }
+ return Result;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetOpRomPolicy
+//
+// Description: This function returns OpROM policy for given PCI class of the device
+//
+// Input:
+// UINT8 PciClass - class of PCI device to check
+//
+// Output:
+// UINT8 - policy (0-disable all, 1-disable Legacy, 2-disable UEFI, 3-Legacy before UEFI
+// 4-UEFI before Legacy)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetOpRomPolicy(
+ IN UINT8 PciClass
+)
+{
+ UINT8 Policy = 0xff;
+
+ switch(PciClass) {
+ case PCI_CL_NETWORK:
+ Policy = CsmOptOutSetupData.PxeOpRom;
+ break;
+
+ case PCI_CL_MASS_STOR:
+ Policy = CsmOptOutSetupData.MassStorageOpRom;
+ break;
+
+ case PCI_CL_DISPLAY:
+ Policy = CsmOptOutSetupData.VideoOpRom;
+ break;
+
+ default:
+/*
+ For PCI devices with PCI class different from Network, Mass Storage or Video
+ behavior will be as in previous versions of PciBus driver - UEFI OpROM will
+ be executed first or not executed at all
+*/
+#if OLD_OPROM_POLICY_SUPPORT
+ Policy = (CsmOptOutSetupData.OldOpRom == 1) ? 4 : 2;
+#else
+ Policy = CsmOptOutSetupData.OldOpRom;
+#endif
+ break;
+ }
+ return Policy;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckOpRomExecution
+//
+// Description: This function determines should OpROM be executed
+//
+// Input:
+// UINT8 PciClass - class of PCI device to check
+// BOOLEAN UefiOprom - TRUE if verifying UEFI OpROM, FALSE for Legacy OpROM
+//
+// Output:
+// EFI_SUCCESS - OpROM should be executed
+// EFI_UNSUPPORTED - OpROM should not be executed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckOpRomExecution(
+ IN UINT8 PciClass,
+ IN BOOLEAN UefiOprom
+)
+{
+ UINT8 Policy;
+ BOOLEAN Result = TRUE;
+
+ Policy = GetOpRomPolicy(PciClass);
+
+ switch(Policy) {
+ case 0: //all OpROMs are disabled
+ Result = FALSE;
+ break;
+
+ case 1: //only UEFI OpROMs are enabled
+ Result = (UefiOprom) ? TRUE : FALSE;
+ break;
+
+ case 2: //only Legacy OpROMs are enabled
+ Result = (UefiOprom) ? FALSE : TRUE;
+ break;
+
+ default: //all OpROMs are enabled
+ break;
+ }
+ return (Result) ? EFI_SUCCESS : EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisconnectUefiGop
+//
+// Description: This function disconnects native UEFI GOP driver before
+// executing legacy video BIOS
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIo - instance of PciIo protocol on handle,
+// that have to be disconnected
+//
+// Output:
+// EFI_SUCCESS - driver was disconnected
+// EFI_UNSUPPORTED - driver can't be disconnected
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisconnectUefiGop(
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handles;
+ EFI_HANDLE TmpHandle;
+ UINTN Count;
+ UINTN i;
+ VOID *Interface;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Entries;
+ UINT64 Capabilities;
+
+/* first find corresponding handle */
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiPciIoProtocolGuid, NULL, &Count, &Handles);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < Count; i++) {
+ Status = pBS->HandleProtocol(Handles[i], &gEfiPciIoProtocolGuid, &Interface);
+ if(EFI_ERROR(Status))
+ continue;
+
+ if((VOID *)PciIo == Interface) {
+ SharedGopHandle = Handles[i];
+ break;
+ }
+ }
+ pBS->FreePool(Handles);
+
+ if(i == Count) //no matches
+ return EFI_NOT_FOUND;
+
+/* now find child handle where Gop is installed */
+ Status = pBS->OpenProtocolInformation(SharedGopHandle, &gEfiPciIoProtocolGuid, &Entries, &Count);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < Count; i++) {
+ if(!(Entries[i].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER))
+ continue;
+
+ Status = pBS->HandleProtocol(Entries[i].ControllerHandle, &gEfiGraphicsOutputProtocolGuid, &Interface);
+ if(!EFI_ERROR(Status)) {
+ TmpHandle = Entries[i].AgentHandle;
+ break;
+ }
+ }
+ pBS->FreePool(Entries);
+
+ if(i == Count) //no matches
+ return EFI_NOT_FOUND;
+
+/* now check if AgentHandle is our CSM thunk */
+ Status = pBS->HandleProtocol(TmpHandle, &AmiCsmThunkProtocolGuid, &Interface);
+ if(!EFI_ERROR(Status))
+ return EFI_SUCCESS;
+
+ Status = pBS->DisconnectController(SharedGopHandle, NULL, NULL);
+/* we have to restore PCI attributes so video BIOS can be executed */
+ Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSupported,
+ 0, &Capabilities);
+ Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE, NULL);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessOpRomCallback
+//
+// Description: This callback will be called before and after installing legacy OpROM
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessOpRomCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINTN Size = sizeof(EFI_HANDLE);
+ CSM_PLATFORM_POLICY_DATA *OpRomStartEndProtocol;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClassCode;
+
+ Status = pBS->LocateHandle(ByRegisterNotify, NULL, ProcessOpRomRegistration, &Size, &Handle);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return;
+
+ Status = pBS->HandleProtocol(Handle, &OpRomStartEndProtocolGuid, &OpRomStartEndProtocol);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return;
+
+ if(OpRomStartEndProtocol == NULL) { //post-process OpROM callback
+ if(UefiGopDisconnected && !ProceedToBoot)
+/* if this is last OpROM, and Gop was disconnected and we're not on legacy boot path */
+ pBS->ConnectController(SharedGopHandle, NULL, NULL, TRUE);
+ return;
+ }
+
+//check if someone already disabled execution of this OpROM
+ if(OpRomStartEndProtocol->PciIo == NULL || OpRomStartEndProtocol->ExecuteThisRom == FALSE)
+ return;
+
+ PciIo = OpRomStartEndProtocol->PciIo;
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClassCode);
+ if (EFI_ERROR(Status))
+ return;
+
+ Status = CheckOpRomExecution(PciClassCode, FALSE);
+ if(EFI_ERROR(Status)) {
+ OpRomStartEndProtocol->ExecuteThisRom = FALSE;
+ return;
+ }
+
+/* OK, we're decided to execute OpROM */
+ OpRomStartEndProtocol->ExecuteThisRom = TRUE;
+
+ if(PciClassCode == PCI_CL_DISPLAY) {
+ Status = DisconnectUefiGop(PciIo);
+ /*
+ we are executing video OpROM even if we can't disconnect
+ native UEFI driver - possible bug
+ */
+ if(!EFI_ERROR(Status))
+ UefiGopDisconnected = TRUE;
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateHandlesCallback
+//
+// Description: This callback executed every time DriverBinding is installed
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LocateHandlesCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ UINTN Count = sizeof(EFI_HANDLE);
+ EFI_HANDLE Handle;
+ VOID *DummyInterface;
+
+ do {
+ Status = pBS->LocateHandle(ByRegisterNotify,
+ NULL,
+ DriverBindingRegistration,
+ &Count,
+ &Handle);
+ if(!EFI_ERROR(Status)) {
+ Status1 = pBS->HandleProtocol(Handle,
+ &AmiCsmThunkProtocolGuid,
+ &DummyInterface);
+ if(EFI_ERROR(Status1)) {
+ Status = AddHandle(&NonThunkHandles, Handle);
+ } else {
+ Status = AddHandle(&ThunkHandles, Handle);
+ }
+ }
+ } while (!EFI_ERROR(Status));
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitHandleBuffer
+//
+// Description: This function allocates buffer to store DriverBinding handles
+//
+// Input:
+// IN OUT HANDLE_BUFFER *Target - pointer to buffer to be initialized
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitHandleBuffer(
+ IN OUT HANDLE_BUFFER *Target
+)
+{
+ EFI_STATUS Status;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_HANDLE) * DEFAULT_HANDLE_BUFFER_SIZE,
+ (VOID **)&(Target->Array));
+ if(!EFI_ERROR(Status)) {
+ Target->TotalSize = DEFAULT_HANDLE_BUFFER_SIZE;
+ Target->CurrentSize = 0;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IncreaseHandleBuffer
+//
+// Description: This function increases and reallocates buffer to store
+// DriverBinding handles
+//
+// Input:
+// IN OUT HANDLE_BUFFER *Target - pointer to buffer to be increased
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IncreaseHandleBuffer(
+ IN OUT HANDLE_BUFFER *Target
+)
+{
+ EFI_STATUS Status;
+ VOID *NewArray;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_HANDLE) * (Target->TotalSize + DEFAULT_HANDLE_BUFFER_SIZE),
+ &NewArray);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(NewArray, Target->Array, sizeof(EFI_HANDLE) * Target->CurrentSize);
+ Target->TotalSize += DEFAULT_HANDLE_BUFFER_SIZE;
+
+ pBS->FreePool(Target->Array);
+ Target->Array = (EFI_HANDLE *)NewArray;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddHandle
+//
+// Description: This function stores handles in allocated buffer
+//
+// Input:
+// IN OUT HANDLE_BUFFER *Target - pointer to buffer to store handle in
+// EFI_HANDLE Handle - handle to be stored
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddHandle(
+ IN OUT HANDLE_BUFFER *Target,
+ EFI_HANDLE Handle
+)
+{
+ EFI_STATUS Status;
+
+ if(Target->CurrentSize >= Target->TotalSize) {
+ Status = IncreaseHandleBuffer(Target);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ Target->Array[Target->CurrentSize] = Handle;
+ Target->CurrentSize++;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProceedToBootCallback
+//
+// Description: This callback executed when all drivers are connected and system
+// proceeds to boot
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProceedToBootCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ ProceedToBoot = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutEntry
+//
+// Description:
+// This function is CsmOptOut driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ SETUP_DATA SetupData;
+ UINTN Size = sizeof(SETUP_DATA);
+ EFI_EVENT OptOutEvent;
+ VOID *Registration;
+
+ Status = pRS->GetVariable(L"Setup", &SetupGuid, NULL, &Size, &SetupData);
+
+ if(!EFI_ERROR(Status)) {
+ CsmOptOutSetupData.CsmLaunchPolicy = SetupData.CsmLaunchPolicy;
+ CsmOptOutSetupData.BootOptionFilter = SetupData.BootOptionFilter;
+ CsmOptOutSetupData.PxeOpRom = SetupData.PxeOpRom;
+ CsmOptOutSetupData.MassStorageOpRom = SetupData.MassStorageOpRom;
+ CsmOptOutSetupData.VideoOpRom = SetupData.VideoOpRom;
+ CsmOptOutSetupData.OldOpRom = SetupData.OldOpRom;
+ }
+
+//Determine current CSM state based on whether AmiLoadCsmGuid protocol is installed
+ Size = sizeof(EFI_HANDLE);
+ Status = pBS->LocateHandle(ByProtocol, &AmiLoadCsmGuid, NULL, &Size, &Handle);
+ CurrentCsmState = (EFI_ERROR(Status)) ? 0 : 1;
+
+ if(CurrentCsmState == 1) {
+ Status = RegisterProtocolCallback(&OpRomStartEndProtocolGuid,
+ ProcessOpRomCallback,
+ NULL,
+ &OptOutEvent,
+ &ProcessOpRomRegistration);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = RegisterProtocolCallback(&BdsAllDriversConnectedProtocolGuid,
+ ProceedToBootCallback,
+ NULL,
+ &OptOutEvent,
+ &Registration);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ /* Init platform driver override protocol */
+ Status = InitHandleBuffer(&ThunkHandles);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = InitHandleBuffer(&NonThunkHandles);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = RegisterProtocolCallback(&gEfiDriverBindingProtocolGuid,
+ LocateHandlesCallback,
+ NULL,
+ &OptOutEvent,
+ &DriverBindingRegistration);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ /*call callback manually to get already registered handles */
+ LocateHandlesCallback(OptOutEvent, NULL);
+
+ Status = pBS->InstallMultipleProtocolInterfaces(&Handle,
+ &AmiOpromPolicyProtocolGuid,
+ &AmiOpRomPolicyProtocol,
+ &gEfiPlatformDriverOverrideProtocolGuid,
+ &CsmOptOutPlatformDriverOverride,
+ NULL);
+ } else {
+//Reset Boot option filter to avoid situation, when no boot options are available
+ CsmOptOutSetupData.BootOptionFilter = 0;
+//Set video policy to UEFI only
+ CsmOptOutSetupData.VideoOpRom = 1;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetUefiOpRomPolicy
+//
+// Description:
+// This function is HII driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, HII protocols installed
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckUefiOpRomPolicy(
+ IN AMI_OPROM_POLICY_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle
+)
+{
+ UINT32 i;
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClass;
+
+ for(i = 0; OemCheckUefiOpromPolicyList[i] != NULL; i++) {
+ Status = OemCheckUefiOpromPolicyList[i](PciHandle);
+ if(Status == EFI_SUCCESS || Status == EFI_UNSUPPORTED)
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(PciHandle, &gEfiPciIoProtocolGuid, &PciIo);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClass);
+
+ return (EFI_ERROR(Status))? Status : CheckOpRomExecution(PciClass, TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBusSpecificHandle
+//
+// Description: This function returns bus-specific handle for given controller
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of the controller
+// IN OUT EFI_HANDLE *DriverImageHandle - pointer to returned handle placeholder
+//
+// Output:
+// EFI_SUCCESS - handle returned
+// EFI_NOT_FOUND - handle not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetBusSpecificHandle(
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+)
+{
+ EFI_STATUS Status;
+
+ if(BusSpecific == NULL) {
+ Status = pBS->HandleProtocol(
+ ControllerHandle,
+ &gEfiBusSpecificDriverOverrideProtocolGuid,
+ &BusSpecific);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ return BusSpecific->GetDriver(BusSpecific, DriverImageHandle);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsManageable
+//
+// Description: This function returns if given PCI device class supports
+// controlled UEFI/Legacy OpROM execution sequence
+//
+// Input:
+// IN UINT8 PciClass - class of the device
+//
+// Output:
+// TRUE - controlled sequence supported
+// FALSE - controlled sequence not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsManageable(
+ IN UINT8 PciClass
+)
+{
+ if(PciClass == PCI_CL_DISPLAY ||
+ PciClass == PCI_CL_NETWORK ||
+ PciClass == PCI_CL_MASS_STOR)
+ return TRUE;
+
+ return FALSE;
+}
+
+VOID UpdateTransaction(
+ IN EFI_STATUS Status,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle
+)
+{
+ if(!EFI_ERROR(Status)) {
+ TransactionInProgress = TRUE;
+ CurrentHandle = ControllerHandle;
+ LastReturnedImageHandle = DriverImageHandle;
+ } else {
+ TransactionInProgress = FALSE;
+ CurrentHandle = NULL;
+ LastReturnedImageHandle = NULL;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutGetDriver
+//
+// Description: Implementation of Platform Drive Override protocol
+// GetDriver function
+//
+// Input:
+// IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This - pointer to the instance of
+// the protocol
+// IN EFI_HANDLE ControllerHandle - handle of controller for which to retrieve
+// DriverBinding handle
+// IN OUT EFI_HANDLE *DriverImageHandle - pointer to returned handle placeholder
+//
+// Output:
+// EFI_SUCCESS - handle returned
+// EFI_NOT_FOUND - handle not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutGetDriver(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+)
+{
+ EFI_STATUS Status;
+ if(TransactionInProgress) {
+ if(*DriverImageHandle != LastReturnedImageHandle ||
+ ControllerHandle != CurrentHandle) {
+ Status = EFI_INVALID_PARAMETER;
+ UpdateTransaction(Status, NULL, NULL);
+ return Status;
+ }
+ }
+
+ Status = CsmOptOutGetDriverWorker(This, ControllerHandle, DriverImageHandle);
+ UpdateTransaction(Status, ControllerHandle, *DriverImageHandle);
+ return Status;
+}
+
+EFI_STATUS CsmOptOutGetDriverWorker(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+)
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClass;
+ UINT8 Policy;
+
+ if(ControllerHandle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(*DriverImageHandle == NULL) { //This is first call
+ Status = pBS->HandleProtocol(ControllerHandle, &gEfiPciIoProtocolGuid, &PciIo);
+ if(EFI_ERROR(Status))
+ return EFI_NOT_FOUND; //we don't care about non pci handles
+
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClass);
+ if(EFI_ERROR(Status))
+ return EFI_NOT_FOUND;
+
+ Policy = GetOpRomPolicy(PciClass);
+ if(Policy == 0) //OpROM execution is disabled
+ return EFI_NOT_FOUND;
+
+ /* check if this pci class supported for controlled OpROM
+ execution sequence
+ */
+ if(!IsManageable(PciClass))
+ return EFI_NOT_FOUND;
+
+ ThunkFirst = (Policy == 2 || Policy == 3) ? TRUE : FALSE;
+ }
+
+ if(ThunkFirst) {
+ if(CurrentCount < ThunkHandles.CurrentSize) {
+ *DriverImageHandle = ThunkHandles.Array[CurrentCount];
+ CurrentCount++;
+ return EFI_SUCCESS;
+ } else {
+ CurrentCount = 0; //reset counter
+ return EFI_NOT_FOUND;
+ }
+ } else {
+/* first get handles provided by bus specific override protocol */
+ if((UINTN)BusSpecific != 0xfffffffa) {
+ Status = GetBusSpecificHandle(ControllerHandle, DriverImageHandle);
+ if(!EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ (UINTN)BusSpecific = 0xfffffffa; //set flag we're done with bus specific override
+ }
+/* now get other Driver binding handles except those with thunk protocol */
+ if(CurrentCount < NonThunkHandles.CurrentSize) {
+ *DriverImageHandle = NonThunkHandles.Array[CurrentCount];
+ CurrentCount++;
+ return EFI_SUCCESS;
+ } else {
+ CurrentCount = 0;
+ (UINTN)BusSpecific = 0; //set flag we need to start from bus specific next time we're called
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CsmOptOut/CsmOptOut.chm b/Core/EM/CsmOptOut/CsmOptOut.chm
new file mode 100644
index 0000000..f5e23f1
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.chm
Binary files differ
diff --git a/Core/EM/CsmOptOut/CsmOptOut.cif b/Core/EM/CsmOptOut/CsmOptOut.cif
new file mode 100644
index 0000000..4147155
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "CsmOptOut"
+ category = eModule
+ LocalRoot = "Core\EM\CsmOptOut\"
+ RefName = "CsmOptOut"
+[files]
+"CsmOptOut.sdl"
+"CsmOptOut.mak"
+"CsmOptOut.c"
+"CsmOptOutRuntime.c"
+"CsmOptOutSetup.c"
+"CsmOptOut.uni"
+"CsmOptOut.sd"
+"CsmOptOut.chm"
+<endComponent>
diff --git a/Core/EM/CsmOptOut/CsmOptOut.mak b/Core/EM/CsmOptOut/CsmOptOut.mak
new file mode 100644
index 0000000..7371b03
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.mak
@@ -0,0 +1,106 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.mak 5 1/22/13 4:29p Artems $
+#
+# $Revision: 5 $
+#
+# $Date: 1/22/13 4:29p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.mak $
+#
+# 5 1/22/13 4:29p Artems
+# [TAG] EIP111710
+# [Category] Improvement
+# [Description] Replace MessageBox message and title with string tokens
+# to allow
+# different language usage
+# [Files] CsmOptOut.mak CsmOptOut.uni CsmOptOutSetup.c
+#
+# 4 6/20/12 6:06p Artems
+# [TAG] EIP83692
+# [Category] Improvement
+# [Description] CSM OptOut setup page grayed out if secure boot is
+# enabled
+# CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+# Removed support for Launch CSM "Auto" option
+#
+# [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+# CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+#
+# 3 5/21/12 4:43p Artems
+# [TAG] EIP86097
+# [Category] Improvement
+# [Description] Separate control for loading UEFI Oprom Driver
+# Prevent user from disable CSM in setup if active video is legacy
+# [Files] CsmOptOutSetup.c CsmOptOut.sdl CsmOptOut.mak
+# CsmOptOut.sdl
+#
+# 2 3/16/12 5:15p Artems
+# EIP 82586: CSM must not be loaded if Secure Boot is enabled
+#
+# 1 11/12/11 2:57p Artems
+# Initial check-in
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CsmOptOut.mak
+#
+# Description: Make file of the CSM OptOut module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\CsmOptOut.obj
+RUNTIMEBin : $(BUILD_DIR)\CsmOptOutRuntime.obj
+SetupBin : $(BUILD_DIR)\CsmOptOutSetup.obj
+
+CFLAGS=$(CFLAGS) /D\"OEM_CHECK_UEFI_OPROM_POLICY_LIST=$(OemCheckUefiOpromPolicyList)\"
+
+{$(CsmOptOut_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /I $(CsmOptOut_DIR) /Fo$(BUILD_DIR)\ $<
+
+$(BUILD_DIR)\CsmOptOut.obj : $(CsmOptOut_DIR)\CsmOptOut.c
+$(BUILD_DIR)\CsmOptOutRuntime.obj : $(CsmOptOut_DIR)\CsmOptOutRuntime.c
+$(BUILD_DIR)\CsmOptOutSetup.obj : $(CsmOptOut_DIR)\CsmOptOutSetup.c
+
+$(BUILD_DIR)\CsmOptOut.mak : $(CsmOptOut_DIR)\CsmOptOut.cif $(BUILD_RULES)
+ $(CIF2MAK) $(CsmOptOut_DIR)\CsmOptOut.cif $(CIF2MAK_DEFAULTS)
+
+SetupSdbs : CsmOptOutSDB
+
+CsmOptOutSDB : $(BUILD_DIR)\CsmOptOut.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CsmOptOut.mak all\
+ TYPE=SDB NAME=CsmOptOut \
+ "STRING_CONSUMERS=$(CsmOptOut_DIR)\CsmOptOut.sd $(CsmOptOut_DIR)\CsmOptOutSetup.c"
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CsmOptOut/CsmOptOut.sd b/Core/EM/CsmOptOut/CsmOptOut.sd
new file mode 100644
index 0000000..ce0bba0
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.sd
@@ -0,0 +1,252 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CsmOptOut/CsmOptOut.sd 6 6/25/14 7:34a Chienhsieh $
+//
+// $Revision: 6 $
+//
+// $Date: 6/25/14 7:34a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CsmOptOut/CsmOptOut.sd $
+//
+// 6 6/25/14 7:34a Chienhsieh
+// Update CsmOptOut to 4.6.5.4_Csm_OptOut_05.
+//
+// 6 11/01/13 9:27p Artems
+// [TAG] EIP126445
+// [Category] Improvement
+// [Description] Added UEFI Only option for OpROMS of unknown types
+// [Files] CsmOptOut.c CsmOptOut.sd CsmOptOut.sdl CsmOptOut.uni
+//
+// 5 10/25/12 9:12a Wesleychen
+// Update CsmOptOut to 4.6.5.4_Csm_OptOut_04.
+//
+// 4 8/15/12 7:15a Wesleychen
+// Remove some items for compatible issue.
+//
+// 5 8/29/12 2:23p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] When enable secure boot disable CSM but preserve CSM
+// optout options setting,
+// so once secure boot is disabled they can be restored
+// [Files] CsmOptOut.sd, CsmOptOut.sdl, CsmOptOutSetup.c
+// CsmOptOutRuntime.c
+//
+// 4 6/20/12 6:07p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+//
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 3 5/21/12 4:48p Artems
+// [TAG] EIP88768
+// [Category] Improvement
+// [Description] CsmOptOut Module Interactive setup callback support
+// Prevent user from disable CSM in setup if active video is legacy
+// [Files] CsmOptOutSetup.c CsmOptOut.sd CsmOptOut.mak
+// CsmOptOut.sdl
+//
+// 2 1/23/12 7:03p Artems
+// Added OpROM handling for PCI devices other than Network, Mass storage
+// or Video
+// Behavior is same as in previous Core versions
+// Added configurability for setup controls
+//
+// 1 11/12/11 2:57p Artems
+// Initial check-in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOut.sd
+//
+// Description: Definition of CsmOptOut module setup controls
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef SETUP_DATA_DEFINITION
+ UINT8 CsmLaunchPolicy;
+ UINT8 BootOptionFilter;
+ UINT8 PxeOpRom;
+ UINT8 MassStorageOpRom;
+ UINT8 VideoOpRom;
+ UINT8 OldOpRom;
+#endif //SETUP_DATA_DEFINITION
+
+#ifdef FORM_SET_TYPEDEF
+typedef struct {
+ UINT8 SecureBoot;
+} SECURE_BOOT;
+#endif
+
+#ifdef CONTROL_DEFINITION
+
+#define CSM_OPT_OUT_CSM_LAUNCH_POLICY\
+ oneof varid = SETUP_DATA.CsmLaunchPolicy, questionid = AUTO_ID(CSM_OPT_OUT_LAUNCH_KEY),\
+ prompt = STRING_TOKEN(STR_CSM_LAUNCH_POLICY),\
+ help = STRING_TOKEN(STR_CSM_LAUNCH_POLICY_HELP),\
+ default = DEFAULT_CSM_LAUNCH_POLICY,\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = INTERACTIVE | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = INTERACTIVE | RESET_REQUIRED;\
+ endoneof;
+
+#define CSM_OPT_OUT_BOOT_OPTION_FILTER\
+ oneof varid = SETUP_DATA.BootOptionFilter,\
+ prompt = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY),\
+ help = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_HELP),\
+ default = DEFAULT_BOOT_OPTION_FILTERING_POLICY,\
+ option text = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_ALL), value = 0, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_LEGACY_ONLY), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_UEFI_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define CSM_OPT_OUT_PXE_OPROM\
+ oneof varid = SETUP_DATA.PxeOpRom,\
+ prompt = STRING_TOKEN(STR_PXE_OPROM_POLICY),\
+ help = STRING_TOKEN(STR_PXE_OPROM_POLICY_HELP),\
+ default = DEFAULT_PXE_OPROM_POLICY,\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_UEFI_ONLY), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_BEFORE_UEFI), value = 3, flags = RESET_REQUIRED;\
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_AFTER_UEFI), value = 4, flags = RESET_REQUIRED;\
+//- endoneof;
+
+#define CSM_OPT_OUT_MASS_STORAGE_OPROM\
+ oneof varid = SETUP_DATA.MassStorageOpRom,\
+ prompt = STRING_TOKEN(STR_MASS_STORAGE_OPROM_POLICY),\
+ help = STRING_TOKEN(STR_MASS_STORAGE_OPROM_POLICY_HELP),\
+ default = DEFAULT_MASS_STORAGE_OPROM_POLICY,\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_UEFI_ONLY), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_BEFORE_UEFI), value = 3, flags = RESET_REQUIRED;\
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_AFTER_UEFI), value = 4, flags = RESET_REQUIRED;\
+//- endoneof;
+
+#define CSM_OPT_OUT_VIDEO_OPROM\
+ oneof varid = SETUP_DATA.VideoOpRom,\
+ prompt = STRING_TOKEN(STR_VIDEO_OPROM_POLICY),\
+ help = STRING_TOKEN(STR_VIDEO_OPROM_POLICY_HELP),\
+ default = DEFAULT_VIDEO_OPROM_POLICY,\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_UEFI_ONLY), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_BEFORE_UEFI), value = 3, flags = RESET_REQUIRED;\
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_AFTER_UEFI), value = 4, flags = MANUFACTURING | RESET_REQUIRED;\
+//- endoneof;
+
+#if OLD_OPROM_POLICY_SUPPORT
+#define CSM_OPT_OUT_OLD_OPROM\
+ oneof varid = SETUP_DATA.OldOpRom,\
+ prompt = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY),\
+ help = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_HELP),\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_UEFI), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_LEGACY), value = 0, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define CSM_OPT_OUT_OLD_OPROM\
+ oneof varid = SETUP_DATA.OldOpRom,\
+ prompt = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY),\
+ help = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_HELP),\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_UEFI), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_LEGACY_AND_UEFI), value = 4, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_LEGACY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+#endif //#if OLD_OPROM_POLICY_SUPPORT
+
+#define CSM_OPT_OUT_FORM_GOTO\
+ suppressif ideqval SECURE_BOOT.SecureBoot == 1;\
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;\
+ goto CSM_OPTOUT_FORM_ID, \
+ prompt = STRING_TOKEN(STR_CSM_OPTOUT_FORM),\
+ help = STRING_TOKEN(STR_CSM_OPTOUT_FORM_HELP);\
+ endif;\
+ endif;
+#endif //#ifdef CONTROL_DEFINITION
+
+#ifdef CONTROLS_WITH_DEFAULTS
+
+CSM_OPT_OUT_CSM_LAUNCH_POLICY
+CSM_OPT_OUT_BOOT_OPTION_FILTER
+CSM_OPT_OUT_PXE_OPROM
+CSM_OPT_OUT_MASS_STORAGE_OPROM
+CSM_OPT_OUT_VIDEO_OPROM
+CSM_OPT_OUT_OLD_OPROM
+
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+#ifdef BOOT_FORM_SET
+ #ifdef FORM_SET_ITEM
+
+ #endif // FORM_SET_ITEM
+
+ #ifdef FORM_SET_VARSTORE
+ varstore SECURE_BOOT, name = SecureBoot, guid = EFI_GLOBAL_VARIABLE_GUID;
+ #endif // FORM_SET_VARSTORE
+
+ #ifdef FORM_SET_GOTO
+
+ CSM_OPT_OUT_FORM_GOTO
+
+ #endif // FORM_SET_GOTO
+
+ #ifdef FORM_SET_FORM
+
+ form formid = AUTO_ID(CSM_OPTOUT_FORM_ID),
+ title = STRING_TOKEN(STR_CSM_OPTOUT_FORM);
+
+ CSM_OPT_OUT_CSM_LAUNCH_POLICY
+
+ suppressif ideqval SETUP_DATA.CsmLaunchPolicy == 0;
+ CSM_OPT_OUT_BOOT_OPTION_FILTER
+ CSM_OPT_OUT_PXE_OPROM
+ CSM_OPT_OUT_MASS_STORAGE_OPROM
+ CSM_OPT_OUT_VIDEO_OPROM
+ SEPARATOR
+ CSM_OPT_OUT_OLD_OPROM
+ endif;
+
+ endform;
+
+ #endif // FORM_SET_FORM
+
+#endif // BOOT_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CsmOptOut/CsmOptOut.sdl b/Core/EM/CsmOptOut/CsmOptOut.sdl
new file mode 100644
index 0000000..11f0193
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.sdl
@@ -0,0 +1,124 @@
+TOKEN
+ Name = "CsmOptOut_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "CSM_OPTOUT_MODULE_REVISION"
+ Value = "4"
+ Help = "Version of Csm Optout module interfaces"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OLD_OPROM_POLICY_SUPPORT"
+ Value = "1"
+ Help = "If set, implement old style option ROM support for other devices where UEFI signifies both legacy and UEFI option ROMs. If disabled, provide options for UEFI only, Legacy only, or both."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_CSM_LAUNCH_POLICY"
+ Value = "1"
+ Help = "Controls default value of CSM Launch Policy setup control\1 - Launch CSM, 0 - Do not launch CSM"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_BOOT_OPTION_FILTERING_POLICY"
+ Value = "0"
+ Help = "Controls default value of Boot Option Filter setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Both UEFI and Legacy boot options enabled, 1 - Only Legacy boot options enabled , 2 - Only UEFI boot options enabled"
+End
+
+TOKEN
+ Name = "DEFAULT_PXE_OPROM_POLICY"
+ Value = "1"
+ Help = "Default value of Launch PXE OpROM policy setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Do not launch, 1 - Launch UEFI OpROM only, 2 - Launch Legacy OpROM only, 3 - Launch Legacy before UEFI, 4 - Launch Legacy after UEFI"
+End
+
+TOKEN
+ Name = "DEFAULT_MASS_STORAGE_OPROM_POLICY"
+ Value = "1"
+ Help = "Default value of Launch Storage OpROM policy setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Do not launch, 1 - Launch UEFI OpROM only, 2 - Launch Legacy OpROM only, 3 - Launch Legacy before UEFI, 4 - Launch Legacy after UEFI"
+End
+
+TOKEN
+ Name = "DEFAULT_VIDEO_OPROM_POLICY"
+ Value = "2"
+ Help = "Default value of Launch Video OpROM policy setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Do not launch, 1 - Launch UEFI OpROM only, 2 - Launch Legacy OpROM only, 3 - Launch Legacy before UEFI, 4 - Launch Legacy after UEFI"
+End
+
+PATH
+ Name = "CsmOptOut_DIR"
+End
+
+MODULE
+ Help = "Includes CsmOptOut.mak to Project"
+ File = "CsmOptOut.mak"
+End
+
+ELINK
+ Name = "$(CsmOptOut_DIR)\CsmOptOut.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 80
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CsmOptOut.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CsmOptOutFilter,"
+ Parent = "BootOptionBootDeviceFilteringFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CsmOptOutEntry,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CsmOptOutRuntimeEntry,"
+ Parent = "NvRamSmmEntry,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemCheckUefiOpromPolicyList"
+ Help = "List of callback functions to be called to determine if UEFI Oprom should be executed"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(BOOT_FORM_SET_CLASS,0,CSM_OPT_OUT_LAUNCH_KEY,CsmOptOutLaunchCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/CsmOptOut/CsmOptOut.uni b/Core/EM/CsmOptOut/CsmOptOut.uni
new file mode 100644
index 0000000..44501de
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.uni
Binary files differ
diff --git a/Core/EM/CsmOptOut/CsmOptOutRuntime.c b/Core/EM/CsmOptOut/CsmOptOutRuntime.c
new file mode 100644
index 0000000..389676f
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOutRuntime.c
@@ -0,0 +1,168 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutRuntime.c 4 8/29/12 2:25p Artems $
+//
+// $Revision: 4 $
+//
+// $Date: 8/29/12 2:25p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutRuntime.c $
+//
+// 4 8/29/12 2:25p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] When enable secure boot disable CSM but preserve CSM
+// optout options setting,
+// so once secure boot is disabled they can be restored
+// [Files] CsmOptOut.sd, CsmOptOut.sdl, CsmOptOutSetup.c
+// CsmOptOutRuntime.c
+//
+// 3 6/20/12 6:10p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+//
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 2 3/23/12 6:26p Artems
+// EIP 84012: Added fix to execute entrypoint only once
+//
+// 1 3/16/12 4:57p Artems
+// Initial check-in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOutRuntime.c
+//
+// Description: This is the entry point of CsmOptOut driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+//----------------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <AmiLoadCsmPolicy.h>
+#include <ImageAuthentication.h>
+
+//----------------------------------------------------------------------------
+
+static EFI_GUID SetupGuid = SETUP_GUID;
+static EFI_GUID AmiLoadCsmGuid = AMI_LOAD_CSM_GUID;
+static EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutNotInSmmEntry
+//
+// Description: CsmOptOut runtime callback for variable services
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutNotInSmmEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+ SETUP_DATA SetupData;
+ UINTN Size;
+ UINT8 CurrentCsmState;
+ UINT32 Attributes;
+ BOOLEAN SecureBoot;
+
+ Size = sizeof(UINT8);
+ Status = pRS->GetVariable(EFI_SECURE_BOOT_NAME, &gEfiGlobalVariableGuid, NULL, &Size, &CurrentCsmState);
+ SecureBoot = (!EFI_ERROR(Status) && CurrentCsmState != 0) ? TRUE : FALSE;
+
+ Size = sizeof(SETUP_DATA);
+ Status = pRS->GetVariable(L"Setup", &SetupGuid, &Attributes, &Size, &SetupData);
+
+ CurrentCsmState = (SecureBoot) ? 0 : (EFI_ERROR(Status)) ? DEFAULT_CSM_LAUNCH_POLICY : SetupData.CsmLaunchPolicy;
+ if(CurrentCsmState == 1) {
+ Status = pBS->InstallMultipleProtocolInterfaces(&Handle,
+ &AmiLoadCsmGuid, NULL,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutRuntimeEntry
+//
+// Description: CsmOptOut runtime callback for variable services
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutRuntimeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ UINT32 Var;
+ UINTN Size = sizeof(UINT32);
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = pRS->GetVariable(L"AmiLoadCsm", &AmiLoadCsmGuid, NULL, &Size, &Var);
+ if(!EFI_ERROR(Status))
+ return EFI_ALREADY_STARTED;
+
+ Size = sizeof(UINT32);
+ Var = 0xdeadbeef;
+ Status = pRS->SetVariable(L"AmiLoadCsm", &AmiLoadCsmGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, Size, &Var);
+ return CsmOptOutNotInSmmEntry(ImageHandle, SystemTable);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CsmOptOut/CsmOptOutSetup.c b/Core/EM/CsmOptOut/CsmOptOutSetup.c
new file mode 100644
index 0000000..f61e77b
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOutSetup.c
@@ -0,0 +1,430 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutSetup.c 10 7/08/13 4:17p Artems $
+//
+// $Revision: 10 $
+//
+// $Date: 7/08/13 4:17p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutSetup.c $
+//
+// 10 7/08/13 4:17p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Build error
+// [RootCause] Unreferenced local variable
+// [Solution] Removed variable
+// [Files] CsmOptOutSetup.c
+//
+// 9 7/02/13 5:06p Artems
+// [TAG] EIP125900
+// [Category] Improvement
+// [Description] Funciton IsUefiGop assumed, that GOP protocol installed
+// on the same handle
+// where PciIO is installed, which is not always the case.
+// Updated to handle different cases
+// [Files] CsmOptOutSetup.c
+//
+// 8 2/26/13 1:47p Artems
+// [TAG] EIP111710
+// [Category] Improvement
+// [Description] Added multilanguage support for error message box
+// [Files] CsmOptOutSetup.c
+//
+// 7 1/22/13 4:29p Artems
+// [TAG] EIP111710
+// [Category] Improvement
+// [Description] Replace MessageBox message and title with string tokens
+// to allow
+// different language usage
+// [Files] CsmOptOut.mak CsmOptOut.uni CsmOptOutSetup.c
+//
+// 6 9/27/12 7:14p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Secureboot enable callbacks moved to Secure Boot module
+// [Files] CsmOptOut.sdl CsmOptOutSetup.c
+//
+// 5 9/11/12 5:26p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Changed dependency on secureboot pkg module revision
+// [Files] CsmOptOutSetup.c
+//
+// 4 9/04/12 3:15p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] Use EFI_UNSUPPORTED status in Browser callback to
+// discard control value instead of FORM_DISCARD
+// [Files] CsmOptOutSetup.c
+//
+// 3 8/29/12 2:26p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] When enable secure boot disable CSM but preserve CSM
+// optout options setting,
+// so once secure boot is disabled they can be restored
+// [Files] CsmOptOut.sd, CsmOptOut.sdl, CsmOptOutSetup.c
+// CsmOptOutRuntime.c
+//
+// 2 6/20/12 6:10p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+//
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 1 5/21/12 4:34p Artems
+// [TAG] EIP N/A
+// [Category] New Feature
+// [Description] Prevent user from disable CSM in setup if active video
+// is legacy
+// [Files] CsmOptOutSetup.c CsmOptOut.sdl CsmOptOut.mak
+// CsmOptOut.sdl
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOutSetup.c
+//
+// Description: Implementation of interactive callback to "Launch CSM" setup control
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#include <AmiLoadCsmPolicy.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/AmiPostMgr.h>
+#include <Protocol/HiiString.h>
+
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+static EFI_GUID AmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID;
+static AMI_POST_MANAGER_PROTOCOL* AmiPostMgr = NULL;
+
+extern const char *DefaultLanguageCode;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsUefiGop
+//
+// Description: This function checks wheter passed controller is managed by UEFI GOP driver
+//
+// Input:
+// IN EFI_HANDLE pci_hnd - handle of the controller
+//
+// Output:
+// 0 - controller managed by legacy driver
+// 1 - controller managed by UEFI driver
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsUefiGop(
+ IN EFI_HANDLE pci_hnd
+)
+{
+ EFI_STATUS Status;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *ent;
+ UINTN n_ent;
+ UINTN i;
+ VOID *p;
+ static EFI_GUID AmiCsmThunkProtocolGuid = AMI_CSM_THUNK_PROTOCOL_GUID;
+ BOOLEAN Result = TRUE;
+
+ Status = pBS->OpenProtocolInformation(pci_hnd, &gEfiPciIoProtocolGuid, &ent, &n_ent);
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ for(i = 0; i < n_ent; i++) {
+ if(!(ent[i].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER))
+ continue;
+
+ Status = pBS->HandleProtocol(ent[i].AgentHandle, &AmiCsmThunkProtocolGuid, &p);
+ if(!EFI_ERROR(Status)) {
+ Result = FALSE;
+ break;
+ }
+ }
+ pBS->FreePool(ent);
+
+ return Result;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsLegacyVideo
+//
+// Description: This function checks if active video is Legacy or UEFI
+//
+// Input:
+// None
+//
+// Output:
+// 0 - active video is UEFI
+// 1 - active vide is Legacy
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsLegacyVideo(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *hnd;
+ EFI_HANDLE pci_hnd;
+ UINTN n_hnd;
+ UINTN i;
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiGraphicsOutputProtocolGuid, NULL, &n_hnd, &hnd);
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ for(i = 0; i < n_hnd; i++) {
+ Status = pBS->HandleProtocol(hnd[i], &gEfiDevicePathProtocolGuid, &dp);
+ if(EFI_ERROR(Status))
+ continue;
+ Status = pBS->LocateDevicePath(&gEfiPciIoProtocolGuid, &dp, &pci_hnd);
+ if(EFI_ERROR(Status))
+ continue;
+
+ if(IsUefiGop(pci_hnd))
+ return FALSE;
+ }
+ pBS->FreePool(hnd);
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCurrentLanguage
+//
+// Description: This function retrieves current platform language and stores it in
+// passed pointer
+//
+// Input: CHAR8 ** Lang - pointer to where to store current language
+// BOOLEAN *Allocated - flag if memory was allocated for language
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetCurrentLanguage(
+ CHAR8 ** Language,
+ BOOLEAN *Allocated
+)
+{
+ EFI_STATUS Status;
+ UINTN Size = 0;
+
+ *Allocated = FALSE;
+
+ Status = pRS->GetVariable(L"PlatformLang", &EfiVariableGuid, NULL, &Size, *Language);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, Language);
+ if(!EFI_ERROR(Status)) {
+ Status = pRS->GetVariable(L"PlatformLang", &EfiVariableGuid, NULL, &Size, *Language);
+ *Allocated = TRUE;
+ }
+ }
+ if(EFI_ERROR(Status))
+ *Language = (CHAR8 *)DefaultLanguageCode;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLangString
+//
+// Description: This function reads a string from HII database with different languages
+//
+// Input: IN EFI_HII_HANDLE HiiHandle - Efi Hii Handle
+// IN STRING_REF Token - String Token
+// IN OUT UINTN *StringSize - Length of the StringBuffer in bytes
+// OUT EFI_STRING *StringBuffer - The pointer to the buffer to receive
+// the characters in the string.
+//
+// Output: EFI_STATUS - Depending on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetLangString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID Token,
+ IN OUT UINTN *StringSize,
+ OUT EFI_STRING StringBuffer
+)
+{
+ EFI_STATUS Status;
+ EFI_HII_STRING_PROTOCOL *HiiString;
+ CHAR8 *Language;
+ BOOLEAN Allocated;
+
+ Status = pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ GetCurrentLanguage(&Language, &Allocated);
+
+ Status = HiiString->GetString(HiiString, Language, HiiHandle, Token, StringBuffer, StringSize, NULL);
+ if(Status == EFI_INVALID_LANGUAGE) {
+ if(Allocated)
+ Status = HiiString->GetString(HiiString, (CHAR8 *)DefaultLanguageCode, HiiHandle, Token, StringBuffer, StringSize, NULL);
+ }
+
+ if(Status == EFI_INVALID_LANGUAGE)
+ Status = HiiString->GetString(HiiString, LANGUAGE_CODE_ENGLISH, HiiHandle, Token, StringBuffer, StringSize, NULL);
+
+ if(Allocated)
+ pBS->FreePool(Language);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetUniString
+//
+// Description: This function reads a string from HII database
+//
+// Input: IN EFI_HII_HANDLE HiiHandle - Efi Hii Handle
+// IN STRING_REF Token - String Token
+// IN OUT UINTN *StringSize - Length of the StringBuffer in bytes
+// OUT EFI_STRING *StringBuffer - The pointer to the buffer to receive
+// the characters in the string.
+//
+// Output: EFI_STATUS - Depending on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetUniString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID Token,
+ IN OUT UINTN *StringSize,
+ OUT EFI_STRING *StringBuffer
+)
+{
+ EFI_STATUS Status;
+
+ if (*StringBuffer == NULL)
+ *StringSize = 0; //reset size if buffer is NULL
+
+
+ Status = GetLangString(HiiHandle, Token, StringSize, *StringBuffer);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, *StringSize, StringBuffer);
+ if(!EFI_ERROR(Status))
+ Status = GetLangString(HiiHandle, Token, StringSize, *StringBuffer);
+ }
+
+ if(EFI_ERROR(Status))
+ *StringBuffer = NULL;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CsmOptOutLaunchCallback
+//
+// Description: This function checks if CSM can be disabled in current boot
+//
+// Input:
+// IN EFI_HII_HANDLE HiiHandle - HII handle of formset
+// IN UINT16 Class - class of formset
+// IN UINT16 SubClass - subclass of formset
+// IN UINT16 Key - Id of setup control
+//
+// Output:
+// EF_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutLaunchCallback(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN UINT16 Class,
+ IN UINT16 SubClass,
+ IN UINT16 Key
+)
+{
+ EFI_STATUS Status;
+ UINT8 MsgKey;
+ EFI_BROWSER_ACTION_REQUEST *rq;
+ EFI_STRING Title = NULL;
+ EFI_STRING Message = NULL;
+ UINTN Size;
+
+
+ CALLBACK_PARAMETERS *Callback = NULL;
+
+ Callback = GetCallbackParameters();
+ if(!Callback || Callback->Action != EFI_BROWSER_ACTION_CHANGING)
+ return EFI_UNSUPPORTED;
+
+ rq = Callback->ActionRequest;
+ *rq = EFI_BROWSER_ACTION_REQUEST_NONE;
+
+ if(Callback->Value->u8 == 0) {
+ /* trying to disable CSM */
+ if(IsLegacyVideo()) {
+ if(AmiPostMgr == NULL)
+ Status = pBS->LocateProtocol(&AmiPostManagerProtocolGuid, NULL, &AmiPostMgr);
+ if(EFI_ERROR(Status))
+ return Status;
+ GetUniString(HiiHandle, STRING_TOKEN(STR_LEGACY_VIDEO_MSGBOX_TITLE), &Size, &Title);
+ GetUniString(HiiHandle, STRING_TOKEN(STR_LEGACY_VIDEO_MSGBOX_MESSAGE), &Size, &Message);
+
+ Status = AmiPostMgr->DisplayMsgBox((Title == NULL)? L" Warning " : Title,
+ (Message == NULL)? L"Video is in Legacy mode. Select Video policy UEFI only, reboot and try again" : Message,
+ MSGBOX_TYPE_OK,
+ &MsgKey);
+ return EFI_UNSUPPORTED;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************