/** @file Implement the Chipset Servcie IHISI OemExtra Data subfunction for this driver. ;*************************************************************************** ;* Copyright (c) 2017 - 2021, Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #include #include #include "BiosGuard.h" #include #include "IndustryStandard/Oa3_0.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern BOOLEAN mFlashME; extern UINTN mWriteSize; extern H2O_IHISI_PROTOCOL *mH2OIhisi; extern EFI_SMM_FW_BLOCK_SERVICE_PROTOCOL *mSmmFwBlockService; extern BIOSGUARD_PROTOCOL *mBiosGuardProtocol; extern EFI_PHYSICAL_ADDRESS mBiosGuardMemAddress; extern UINTN mBiosGuardMemSize; extern EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable; static EFI_GUID gMsdmAddressGuid = MEMORY_ADDRESS_FOR_MSDM_GUID; // These Offset should check BiosGuard Script, which described the Destination Flash Address and DataSize, Please reference GenBiosGuardHdr.h #define BGSL_DST_TYPE_OFFSET 0x03 #define BGSL_SIZE_OFFSET 0x05 #define BGSL_SPI_DST_ADDR_OFFSET 0x07 /** TURE -- Platform Pfat/BiosGuard feature enabling FALSE -- Platform Pfat/BiosGuard feature disabling **/ BOOLEAN IsBiosGuardSupport ( VOID ) { MSR_PLAT_FRMW_PROT_CTRL_REGISTER PlatFrmwProtCtrl; if (!MsrIsPfatEnabled()) { // // Cpu does not support Pfat/BiosGuard Feature. // return FALSE; } PlatFrmwProtCtrl.Uint64 = AsmReadMsr64 (MSR_PLAT_FRMW_PROT_CTRL); if (PlatFrmwProtCtrl.Bits.PfatEnable == 1) { // // Pfat/BiosGuard feature enabled. // return TRUE; } return FALSE; } /** TURE -- Platform FlashWearOut Set FALSE -- Platform FlashWearOut Un-set **/ BOOLEAN IsFlashWearOutSet ( VOID ) { UINT64 PlatformBiosInfo; UINTN DataSize; EFI_STATUS Status; DataSize = sizeof (UINT64); Status = mSmmVariable->SmmGetVariable ( L"BiosInfoFlagData", &gBiosInfoFlagGuid, NULL, &DataSize, &PlatformBiosInfo ); if (!EFI_ERROR(Status) && PlatformBiosInfo & BIT0) { return TRUE; } return FALSE; } STATIC BOOLEAN MsdmExist ( VOID ) { EFI_STATUS Status; UINTN DataSize; BOOLEAN MsdmExist; UINTN RomBaseAddress; EFI_ACPI_MSDM_DATA_STRUCTURE *MsdmData; UINT8 *VarDataBuffer; MsdmData = NULL; MsdmExist = FALSE; VarDataBuffer = NULL; if (IsBiosGuardSupport () && IsFlashWearOutSet()) { DataSize = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataSize); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, DataSize, (VOID **)&VarDataBuffer ); Status = mSmmVariable->SmmGetVariable ( L"MsdmUpdate", &gMsdmAddressGuid, NULL, &DataSize, VarDataBuffer ); if (!EFI_ERROR (Status)){ Status = mSmmVariable->SmmSetVariable ( L"MsdmUpdate", &gMsdmAddressGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, NULL ); } } DataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE); RomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, DataSize, (VOID **)&MsdmData ); if (EFI_ERROR (Status)) { goto Done; } *(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE; Status = mSmmFwBlockService->Read ( mSmmFwBlockService, RomBaseAddress, 0, &DataSize, (UINT8*) MsdmData ); if (EFI_ERROR (Status)) { goto Done; } if ((MsdmData->MsdmVersion == 0xFFFFFFFF) && (MsdmData->MdsmDataType == 0xFFFFFFFF) && (MsdmData->MsdmDataLength == 0xFFFFFFFF)) { goto Done; } MsdmExist = TRUE; Done: if (MsdmData != NULL) { gSmst->SmmFreePool (MsdmData); } return MsdmExist; } /** AH=41h, OEM Extra Data Communication type 50h to read/write OA3.0. @param[in] ApCommDataBuffer Pointer to AP communication data buffer. @param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer. @retval EFI_SUCCESS Read or write OA3.0 successful. **/ EFI_STATUS Oa30ReadWriteFunction ( IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer, OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer ) { UINT32 MsdmDataSize; MsdmDataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE); switch (ApCommDataBuffer->DataSize) { case OemExtraReportReadSize: BiosCommDataBuffer->Signature = BIOS_COMMUNICATION_SIGNATURE; BiosCommDataBuffer->StructureSize = sizeof (BIOS_COMMUNICATION_DATA_TABLE); BiosCommDataBuffer->BlockSize = OemExtraBlockSize4k; BiosCommDataBuffer->DataSize = OemExtraReportReadSize; BiosCommDataBuffer->PhysicalDataSize = MsdmDataSize; break; case OemExtraSkipSizeCheck: BiosCommDataBuffer->Signature = BIOS_COMMUNICATION_SIGNATURE; BiosCommDataBuffer->StructureSize = sizeof (BIOS_COMMUNICATION_DATA_TABLE); BiosCommDataBuffer->BlockSize = OemExtraBlockSize4k; BiosCommDataBuffer->DataSize = OemExtraSkipSizeCheck; //Don't care BiosCommDataBuffer->PhysicalDataSize = 0x00; //Don't care break; case OemExtraReportWriteSize: BiosCommDataBuffer->Signature = BIOS_COMMUNICATION_SIGNATURE; BiosCommDataBuffer->StructureSize = sizeof (BIOS_COMMUNICATION_DATA_TABLE); BiosCommDataBuffer->BlockSize = OemExtraBlockSize4k; BiosCommDataBuffer->DataSize = OemExtraReportWriteSize; BiosCommDataBuffer->PhysicalDataSize = MsdmDataSize; //bin size break; default: break; } if (!MsdmExist ()) { BiosCommDataBuffer->ErrorReturn = (BiosCommDataBuffer->ErrorReturn | ERROR_RETURE_OA30_NOT_EXIST); } return EFI_SUCCESS; } /** AH=41h, OEM Extra Data Communication type 51h to erase OA3.0 (reset to default). @param[in] ApCommDataBuffer Pointer to AP communication data buffer. @param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer. @retval EFI_SUCCESS Erase OA3.0 successful. **/ EFI_STATUS Oa30EraseFunction ( IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer, OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer ) { EFI_STATUS Status; EFI_STATUS OemSvcStatus; UINT8 LoopCount; UINTN RomBaseAddress; UINTN EraseSize; UINT8 Erase; RomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase); LoopCount = 0; EraseSize = 0x1000; Status = EFI_SUCCESS; if (!MsdmExist ()) { BiosCommDataBuffer->ErrorReturn = (BiosCommDataBuffer->ErrorReturn | ERROR_RETURE_OA30_NOT_EXIST); goto Done; } if (PcdGetBool (PcdEcSharedFlashSupported)) { DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n")); OemSvcStatus = OemSvcEcIdle (TRUE); DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus)); } Status = EFI_UNSUPPORTED; if (IsBiosGuardSupport () && IsFlashWearOutSet()) { Erase = 1; Status = mSmmVariable->SmmSetVariable ( L"MsdmErase", &gMsdmAddressGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, sizeof(UINT8), &Erase ); } else { *(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE; while ((EFI_ERROR (Status)) && (LoopCount < 100)) { Status = mSmmFwBlockService->EraseBlocks ( mSmmFwBlockService, RomBaseAddress, &EraseSize ); LoopCount++; } } if (PcdGetBool (PcdEcSharedFlashSupported)) { DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n")); OemSvcStatus = OemSvcEcIdle (FALSE); DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus)); } Done: BiosCommDataBuffer->DataSize = ApCommDataBuffer->DataSize; BiosCommDataBuffer->PhysicalDataSize = ApCommDataBuffer->PhysicalDataSize; return Status; } /** AH=41h, OEM Extra Data Communication type 52h to populate header. @param[in] ApCommDataBuffer Pointer to AP communication data buffer. @param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer. @retval EFI_SUCCESS populate header successful. **/ EFI_STATUS Oa30PopulateHeaderFunction ( IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer, OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer ) { return EFI_SUCCESS; } /** AH=41h, OEM Extra Data Communication type 53h to de-populate header. @param[in] ApCommDataBuffer Pointer to AP communication data buffer. @param[out] BiosCommDataBuffer Pointer to BIOS communication data buffer. @retval EFI_SUCCESS populate header successful. **/ EFI_STATUS Oa30DePopulateHeaderFunction ( IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer, OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer ) { return EFI_SUCCESS; } EFI_STATUS BiosGuardUpdateHandleFunction ( IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer, OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer ) { if (IsBiosGuardSupport () == FALSE) { BiosCommDataBuffer->ErrorReturn = ERROR_RETURE_NOT_SUPPORT; return EFI_UNSUPPORTED; } BiosCommDataBuffer->BlockSize = OemExtraMaximunBlockSize; BiosCommDataBuffer->DataSize = OemExtraReportWriteSize; BiosCommDataBuffer->PhysicalDataSize = ApCommDataBuffer->PhysicalDataSize; return EFI_SUCCESS; } EFI_STATUS BiosGuardReturnHandleFunction ( IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer, OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer ) { EFI_STATUS Status; if (IsBiosGuardSupport () == FALSE) { BiosCommDataBuffer->ErrorReturn = ERROR_RETURE_NOT_SUPPORT; return EFI_UNSUPPORTED; } BiosCommDataBuffer->BlockSize = OemExtraMaximunBlockSize; BiosCommDataBuffer->DataSize = OemExtraReportWriteSize; BiosCommDataBuffer->PhysicalDataSize = ApCommDataBuffer->PhysicalDataSize; BiosCommDataBuffer->ErrorReturn = ERROR_RETURE_RETURN_CODE_VALID; BiosCommDataBuffer->ReturnCode = AsmReadMsr64 (MSR_PLAT_FRMW_PROT_TRIG_PARAM) & (LShiftU64 (V_MSR_PLAT_FRMW_PROT_TRIG_PARAM_STATUS_MASK, N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_STATUS_OFFSET) | LShiftU64 (V_MSR_PLAT_FRMW_PROT_TRIG_PARAM_DATA_MASK, N_MSR_PLAT_FRMW_PROT_TRIG_PARAM_DATA_OFFSET)); if (mFlashME) { if (BiosCommDataBuffer->ReturnCode == 0x0) { Status = IhisiSuccess; } else { Status = FbtsWriteFail; } FlashMEAfterProcess(Status); } return EFI_SUCCESS; } EFI_STATUS BiosGuardUpdateWrite ( VOID ) { EFI_STATUS Status; UINT32 BgupcSize; UINT32 BgupcOffset; UINT32 BufferSize; EFI_PHYSICAL_ADDRESS BgupCertificate; UINT8 *InputDataBuffer; UINT32 DataSize; UINT32 *BGSL; UINT32 ROMOffset; Status = EFI_SUCCESS; InputDataBuffer = NULL; BgupcOffset = 0x00; BgupcSize = 0x00; BufferSize = 0x00; BgupCertificate = 0x00; DataSize = 0x00; BGSL = NULL; ROMOffset = 0x00; if (IsBiosGuardSupport () == FALSE){ return EFI_UNSUPPORTED; } InputDataBuffer = (UINT8*) (UINTN) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RSI); BgupcOffset = sizeof (BGUP_HEADER) + ((BGUP *) InputDataBuffer)->BgupHeader.ScriptSectionSize + ((BGUP *) InputDataBuffer)->BgupHeader.DataSectionSize; BufferSize = mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI); BgupCertificate = (EFI_PHYSICAL_ADDRESS) (mBiosGuardMemAddress + mBiosGuardMemSize - BGUPC_MEMORY_OFFSET); if (!mH2OIhisi->BufferInCmdBuffer ((VOID *) InputDataBuffer, BufferSize)) { return EFI_INVALID_PARAMETER; } switch (((BGUPC_HEADER *)(InputDataBuffer + BgupcOffset))->Algorithm) { case 1: BgupcSize = sizeof (BGUPC_ALGORITHM_1); break; default: BgupcSize = sizeof (BGUPC_ALGORITHM_1); break; } if ((BgupcOffset + BgupcSize) != BufferSize) { return EFI_INVALID_PARAMETER; } ZeroMem ((VOID *)(UINT64) mBiosGuardMemAddress, mBiosGuardMemSize); CopyMem ((VOID *)(UINT64) mBiosGuardMemAddress, InputDataBuffer, BgupcOffset); CopyMem ((VOID *) BgupCertificate, InputDataBuffer + BgupcOffset, BgupcSize); if (!mFlashME){ DataSize = ((BGUP_HEADER*)mBiosGuardMemAddress)->ScriptSectionSize; Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, DataSize, (VOID **)&BGSL ); if (!EFI_ERROR (Status )) { CopyMem (BGSL, (VOID *)(mBiosGuardMemAddress + sizeof(BGUP_HEADER)), DataSize); // // 0x00000000 means Full image // 0xFFFFFFFF means only BIOS // if ((BGSL[BGSL_DST_TYPE_OFFSET]) == 0x00000000) { mWriteSize = BGSL[BGSL_SIZE_OFFSET]; ROMOffset = BGSL[BGSL_SPI_DST_ADDR_OFFSET]; CheckInMERange (ROMOffset); } gSmst->SmmFreePool (BGSL); } } if (mFlashME){ SetMeHalt (); } // // Use Intel BIOS Guard protocol to trigger BIOS Guard ACM // // Status = gSmst->SmmIo.Io.Write (&gSmst->SmmIo, SMM_IO_UINT8, mGlobalNvsArea->BiosGuardIoTrapAddress, 1, &Trigger); mBiosGuardProtocol->Execute (mBiosGuardProtocol, TRUE); return Status; } /** Function to write OA3.0 data and do action which request from IHISI function 42h. @retval EFI_SUCCESS Successfully returns. **/ EFI_STATUS Oa30DataWrite ( VOID ) { EFI_STATUS Status; EFI_STATUS OemSvcStatus; UINT32 WriteSize; UINT8 EraseCount; UINT8 WriteCount; UINT8 ShutdownMode; UINT32 MsdmDataSize; UINTN RomBaseAddress; UINT8 *WriteDataBuffer; UINT8 *ReturnDataBuffer; UINTN Index2; UINTN EraseSize; UINT8 *TEMP; WriteDataBuffer = (UINT8 *) (UINTN) mH2OIhisi->ReadCpuReg32(EFI_SMM_SAVE_STATE_REGISTER_RSI); WriteSize = (UINT32) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RDI); RomBaseAddress = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataBase); MsdmDataSize = sizeof (EFI_ACPI_MSDM_DATA_STRUCTURE); if (WriteSize == MsdmDataSize) { EraseSize = (UINTN) FixedPcdGet32 (PcdFlashNvStorageMsdmDataSize); ReturnDataBuffer = NULL; Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, EraseSize, (VOID **)&ReturnDataBuffer ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } *(mSmmFwBlockService->FlashMode) = SMM_FW_DEFAULT_MODE; Status = mSmmFwBlockService->Read ( mSmmFwBlockService, RomBaseAddress, 0, &EraseSize, ReturnDataBuffer ); // // Only modify the first 0x31 bytes // TEMP = ReturnDataBuffer; for (Index2 = 0; Index2 < MsdmDataSize; Index2++) { TEMP[Index2] = WriteDataBuffer[Index2]; } Status = EFI_UNSUPPORTED; if (PcdGetBool (PcdEcSharedFlashSupported)) { DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n")); OemSvcStatus = OemSvcEcIdle (TRUE); DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus)); } if (IsBiosGuardSupport () && IsFlashWearOutSet()) { Status = mSmmVariable->SmmSetVariable ( L"MsdmUpdate", &gMsdmAddressGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, MsdmDataSize, ReturnDataBuffer ); } else { EraseCount = 0; WriteCount = 0; do { Status = mSmmFwBlockService->EraseBlocks ( mSmmFwBlockService, RomBaseAddress, &EraseSize ); if (!EFI_ERROR (Status)) { EraseCount = 0; Status = mSmmFwBlockService->Write ( mSmmFwBlockService, RomBaseAddress, &EraseSize, ReturnDataBuffer ); if (!EFI_ERROR (Status)) { goto WriteDone; } else { Status = IHISI_FBTS_WRITE_FAILED; WriteCount++; } } else { Status = IHISI_FBTS_ERASE_FAILED; EraseCount++; } } while ((EraseCount < 100) && (WriteCount < 100)); } WriteDone: gSmst->SmmFreePool (ReturnDataBuffer); if (PcdGetBool (PcdEcSharedFlashSupported)) { DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices Call: OemSvcEcIdle \n")); OemSvcStatus = OemSvcEcIdle (FALSE); DEBUG_OEM_SVC ((DEBUG_INFO, "OemKernelServices OemSvcEcIdle Status: %r\n", OemSvcStatus)); } if (EFI_ERROR(Status)){ return EFI_ACCESS_DENIED; } } else { return EFI_INVALID_PARAMETER; } ShutdownMode = (UINT8) mH2OIhisi->ReadCpuReg32 (EFI_SMM_SAVE_STATE_REGISTER_RCX); switch (ShutdownMode) { case DoNothing: Status = EFI_SUCCESS; break; case WindowsReboot: Status = EFI_SUCCESS; break; case WindowsShutdown: Status = EFI_SUCCESS; break; case DosReboot: // // Note: Reboot by Oem hook // Status = IhisiFbtsReboot (); break; case DosShutdown: Status = IhisiFbtsShutDown (); break; default: Status = EFI_UNSUPPORTED; break; } return EFI_SUCCESS; } /** AH=41h(OemExtraDataCommunication), This function offers an interface to do IHISI Sub function AH=41h. @param[in] ApCommDataBuffer Pointer to AP communication data buffer. @param[in, out] BiosCommDataBuffer On entry, pointer to BIOS communication data buffer. On exit, points to updated BIOS communication data buffer. @retval EFI_UNSUPPORTED Returns unsupported by default. @retval EFI_MEDIA_CHANGED Alter the Configuration Parameter or hook code. @retval EFI_SUCCESS The function performs the same operation as caller. The caller will skip the specified behavior and assuming that it has been handled completely by this function. */ EFI_STATUS EFIAPI IhisiOemExtCommunication ( IN AP_COMMUNICATION_DATA_TABLE *ApCommDataBuffer, IN OUT BIOS_COMMUNICATION_DATA_TABLE *BiosCommDataBuffer ) { EFI_STATUS Status; switch (ApCommDataBuffer->DataType) { case Oa30ReadWrite: Status = Oa30ReadWriteFunction (ApCommDataBuffer, BiosCommDataBuffer); break; case Oa30Erase: Status = Oa30EraseFunction (ApCommDataBuffer, BiosCommDataBuffer); break; case Oa30PopulateHeader: Status = Oa30PopulateHeaderFunction (ApCommDataBuffer, BiosCommDataBuffer); break; case Oa30DePopulateHeader: Status = Oa30DePopulateHeaderFunction (ApCommDataBuffer, BiosCommDataBuffer); break; case PfatUpdate: Status = BiosGuardUpdateHandleFunction (ApCommDataBuffer, BiosCommDataBuffer); break; case PfatReturn: Status = BiosGuardReturnHandleFunction (ApCommDataBuffer, BiosCommDataBuffer); break; default: Status = EFI_UNSUPPORTED; //Return unsupported to indicate this is reserved function break; } if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } else { CopyMem (ApCommDataBuffer, BiosCommDataBuffer, sizeof (BIOS_COMMUNICATION_DATA_TABLE)); return EFI_SUCCESS; } } /** AH=42h(OemExtraDataWrite) This function offers an interface to do IHISI Sub function AH=42h, @param[in] FunctionType Function type. @param[in, out] WriteDataBuffer Pointer to input file data buffer. @param[in, out] WriteSize Write size. @param[in, out] RomBaseAddress Target offset to write. @param[in] ShutdownMode Shutdown mode. @retval EFI_UNSUPPORTED Returns unsupported by default. @retval EFI_MEDIA_CHANGED Alter the Configuration Parameter or hook code. @retval EFI_SUCCESS The function performs the same operation as caller. The caller will skip the specified behavior and assuming that it has been handled completely by this function. */ EFI_STATUS EFIAPI IhisiOemExtDataWrite ( IN UINT8 FunctionType, IN OUT UINT8 *WriteDataBuffer, IN OUT UINTN *WriteSize, IN OUT UINTN *RomBaseAddress, IN UINT8 ShutdownMode ) { EFI_STATUS Status; Status = EFI_UNSUPPORTED; switch (FunctionType) { case Oa30ReadWrite: Status = Oa30DataWrite (); break; case PfatUpdate: FunctionType = 0x00; Status = BiosGuardUpdateWrite (); break; default: Status = EFI_UNSUPPORTED; break; } return Status; } /** AH=47h(OemExtraDataRead), This function offers an interface to do IHISI Sub function AH=47h, @param[in] FunctionType Function type @param[in, out] DataBuffer Pointer to return data buffer. @param[in, out] Size Read size. @param[in, out] RomBaseAddress Read address. @retval EFI_UNSUPPORTED Returns unsupported by default. @retval EFI_MEDIA_CHANGED Alter the Configuration Parameter or hook code. @retval EFI_SUCCESS The function performs the same operation as caller. The caller will skip the specified behavior and assuming that it has been handled completely by this function. */ EFI_STATUS EFIAPI IhisiOemExtDataRead ( IN UINT8 FunctionType, IN OUT UINT8 *DataBuffer, IN OUT UINTN *Size, IN OUT UINTN *RomBaseAddress ) { return EFI_UNSUPPORTED; }