From: Star Zeng Date: Fri, 17 Nov 2017 06:28:25 +0000 (+0800) Subject: IntelSiliconPkg: Move MicrocodeUpdate from UefiCpuPkg X-Git-Tag: edk2-stable201903~2973 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=c8a2f3c332e9f3c535520d9b127ca7a54f4083fa IntelSiliconPkg: Move MicrocodeUpdate from UefiCpuPkg REF: https://bugzilla.tianocore.org/show_bug.cgi?id=540 To consume FIT table for Microcode update, UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe needs to be updated to consume IntelSiliconPkg/Include/IndustryStandard/FirmwareInterfaceTable.h, but UefiCpuPkg could not depend on IntelSiliconPkg. Since the Microcode update feature is specific to Intel, we can first move the Microcode update feature code from UefiCpuPkg to IntelSiliconPkg [first step], then update the code to consume FIT table [second step]. This patch series is for the first step. Note: No any code change in this patch, just move. Next patch will update MicrocodeUpdate to build with the package. Cc: Jiewen Yao Cc: Michael D Kinney Cc: Eric Dong Cc: Laszlo Ersek Regression-tested-by: Yonghong Zhu Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Star Zeng Reviewed-by: Jiewen Yao Reviewed-by: Eric Dong Acked-by: Laszlo Ersek --- diff --git a/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c b/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c new file mode 100644 index 0000000000..7a5ec152d7 --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c @@ -0,0 +1,42 @@ +/** @file + Microcode flash device access library NULL instance. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +/** + Perform microcode write opreation. + + @param[in] FlashAddress The address of flash device to be accessed. + @param[in] Buffer The pointer to the data buffer. + @param[in] Length The length of data buffer in bytes. + + @retval EFI_SUCCESS The operation returns successfully. + @retval EFI_WRITE_PROTECTED The flash device is read only. + @retval EFI_UNSUPPORTED The flash device access is unsupported. + @retval EFI_INVALID_PARAMETER The input parameter is not valid. +**/ +EFI_STATUS +EFIAPI +MicrocodeFlashWrite ( + IN EFI_PHYSICAL_ADDRESS FlashAddress, + IN VOID *Buffer, + IN UINTN Length + ) +{ + CopyMem((VOID *)(UINTN)(FlashAddress), Buffer, Length); + return EFI_SUCCESS; +} diff --git a/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf b/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf new file mode 100644 index 0000000000..a4a47e0737 --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf @@ -0,0 +1,40 @@ +## @file +# Microcode flash device access library. +# +# Microcode flash device access library NULL instance. +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MicrocodeFlashAccessLibNull + MODULE_UNI_FILE = MicrocodeFlashAccessLibNull.uni + FILE_GUID = 6F871ADD-9D86-4676-8BAD-68E2E451FC5B + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MicrocodeFlashAccessLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + MicrocodeFlashAccessLibNull.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseMemoryLib diff --git a/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni b/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni new file mode 100644 index 0000000000..cc4195c412 --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni @@ -0,0 +1,21 @@ +// /** @file +// Microcode flash device access library. +// +// Microcode flash device access library NULL instance. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Microcode flash device access library." + +#string STR_MODULE_DESCRIPTION #language en-US "Microcode flash device access library NULL instance." + diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc new file mode 100644 index 0000000000..1b22c55117 --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc @@ -0,0 +1,33 @@ +## @file +# MicrocodeCapsulePdb +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] +# +# Uncomment the following line and update with your platform pkg name +# +# PLATFORM_NAME = + PLATFORM_GUID = 6875FD33-602E-4EF9-9DF2-8BA7D8B7A7AF + PLATFORM_VERSION = 0.1 +# +# Uncomment the following line and update with your platform pkg name +# +# FLASH_DEFINITION = /MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf +# +# Uncomment the following line and update with your platform pkg name +# +# OUTPUT_DIRECTORY = Build/ + SUPPORTED_ARCHITECTURES = IA32|X64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf new file mode 100644 index 0000000000..f171604d4f --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf @@ -0,0 +1,32 @@ +## @file +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[FmpPayload.FmpPayloadMicrocode1] +IMAGE_HEADER_INIT_VERSION = 0x02 +IMAGE_TYPE_ID = 96d4fdcd-1502-424d-9d4c-9b12d2dcae5c # Microcode GUID (do not change it) +IMAGE_INDEX = 0x1 +HARDWARE_INSTANCE = 0x0 + +# +# Uncomment the following line and update with path to Microcode PDB file +# +#FILE DATA = $(WORKSPACE)//Microcode/Microcode.pdb + +[Capsule.MicrocodeCapsule] +CAPSULE_GUID = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # FMP special Guid (do not change it) +CAPSULE_FLAGS = PersistAcrossReset,InitiateReset +CAPSULE_HEADER_SIZE = 0x20 +CAPSULE_HEADER_INIT_VERSION = 0x1 + +FMP_PAYLOAD = FmpPayloadMicrocode1 diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md new file mode 100644 index 0000000000..9f81373fda --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md @@ -0,0 +1,20 @@ +# How to generate Microcode FMP from Microcode PDB file + +1) Copy directory `UefiCpuPkg/Feature/Capsule/MicrocodeUpdatePdb` to `/MicrocodeUpdatePdb`. + +2) Uncomment and update `FILE DATA` statement in `/MicrocodeUpdatePdb/MicrocodeCapsulePdb.fdf` with path to a Microcode PDB file. The PDB file can placed in `/MicrocodeUpdatePdb` or any other path. + +`FILE DATA = ` + +Uncomment and update `PLATFORM_NAME`, `FLASH_DEFINITION`, `OUTPUT_DIRECTORY` section in `/MicrocodeUpdatePdb/MicrocodeCapsulePdb.dsc` with . + + PLATFORM_NAME = + FLASH_DEFINITION = /MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf + OUTPUT_DIRECTORY = Build/ + +3) Use EDK II build tools to generate the Microcode FMP Capsule + +`build -p /MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc` + +4) The Microcode FMP Capsule is generated at `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/MicrocodeCapsule.Cap` + diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf new file mode 100644 index 0000000000..81af841f2c --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf @@ -0,0 +1,27 @@ +## @file +# Microcode text file to binary +# +# Convert text format microcode to binary format. +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] +BASE_NAME = Microcode +FILE_GUID = ABC36AAC-2031-4422-896E-0A3B899AD0B4 +COMPONENT_TYPE = Microcode +FFS_EXT = .ffs + +[Sources] +# +# Uncomment the following line and update with name of Microcode TXT file +# +#Microcode.txt diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc new file mode 100644 index 0000000000..a66f89b4e2 --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc @@ -0,0 +1,39 @@ +## @file +# MicrocodeCapsuleTxt +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] +# +# Uncomment the following line and update with your platform pkg name +# +# PLATFORM_NAME = + PLATFORM_GUID = 6875FD33-602E-4EF9-9DF2-8BA7D8B7A7AF + PLATFORM_VERSION = 0.1 +# +# Uncomment the following line and update with your platform pkg name +# +# FLASH_DEFINITION = /MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf +# +# Uncomment the following line and update with your platform pkg name +# +# OUTPUT_DIRECTORY = Build/ + SUPPORTED_ARCHITECTURES = IA32|X64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + +[Components] +# +# Uncomment the following line and update with path to Microcode INF file +# +# /MicrocodeCapsuleTxt/Microcode/Microcode.inf diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf new file mode 100644 index 0000000000..113693b1df --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf @@ -0,0 +1,32 @@ +## @file +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[FmpPayload.FmpPayloadMicrocode1] +IMAGE_HEADER_INIT_VERSION = 0x02 +IMAGE_TYPE_ID = 96d4fdcd-1502-424d-9d4c-9b12d2dcae5c # Microcode GUID (do not change it) +IMAGE_INDEX = 0x1 +HARDWARE_INSTANCE = 0x0 + +# +# Uncomment the following line and update with path to Microcode MCB file +# +#FILE DATA = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/IA32/PlatformPkg/MicrocodeCapsuleTxt/Microcode/Microcode/OUTPUT/Microcode.mcb + +[Capsule.MicrocodeCapsule] +CAPSULE_GUID = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # FMP special Guid (do not change it) +CAPSULE_FLAGS = PersistAcrossReset,InitiateReset +CAPSULE_HEADER_SIZE = 0x20 +CAPSULE_HEADER_INIT_VERSION = 0x1 + +FMP_PAYLOAD = FmpPayloadMicrocode1 diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md new file mode 100644 index 0000000000..f7d7040fcb --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md @@ -0,0 +1,33 @@ +# How to generate Microcode FMP from Microcode TXT file + +1) Copy directory `UefiCpuPkg/Feature/Capsule/MicrocodeUpdateTxt` to `/MicrocodeUpdateTxt` + +2) Copy microcode TXT file to`/MicrocodeUpdateTxt/Microcode` + +3) Uncomment and update statement in `[Sources]` section of `/MicrocodeUpdateTxt/Microcode/Microcode.inf` with name of Microcode TXT file copied in previous step. + + [Sources] + + +Uncomment and update `FILE DATA` statement in `/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.fdf` with path to a Microcode MCB file. The MCB file is placed in `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/IA32//MicrocodeUpdateTxt/Microcode/Microcode/OUTPUT/`. + +`FILE DATA = ` + +Uncomment and update `PLATFORM_NAME`, `FLASH_DEFINITION`, `OUTPUT_DIRECTORY` section in `/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.dsc` with . + + PLATFORM_NAME = + FLASH_DEFINITION = /MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf + OUTPUT_DIRECTORY = Build/ + +Uncomment and update statement in `Components` section of `/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.dsc` with path to a Microcode INF file. + + [Components] + + +4) Use EDK II build tools to generate the Microcode FMP Capsule + +`build -p /MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc` + +5) The generated Microcode FMP Capsule is found at `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/MicrocodeCapsule.Cap` + + diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c new file mode 100644 index 0000000000..ebde93a91e --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c @@ -0,0 +1,748 @@ +/** @file + Produce FMP instance for Microcode. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "MicrocodeUpdate.h" + +// +// MicrocodeFmp driver private data +// +MICROCODE_FMP_PRIVATE_DATA *mMicrocodeFmpPrivate = NULL; + +EFI_FIRMWARE_MANAGEMENT_PROTOCOL mFirmwareManagementProtocol = { + FmpGetImageInfo, + FmpGetImage, + FmpSetImage, + FmpCheckImage, + FmpGetPackageInfo, + FmpSetPackageInfo +}; + +/** + Initialize Microcode Descriptor. + + @param[in] MicrocodeFmpPrivate private data structure to be initialized. + + @return EFI_SUCCESS Microcode Descriptor is initialized. +**/ +EFI_STATUS +InitializeMicrocodeDescriptor ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ); + +/** + Returns information about the current firmware image(s) of the device. + + This function allows a copy of the current firmware image to be created and saved. + The saved copy could later been used, for example, in firmware image recovery or rollback. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer. + On input, this is the size of the buffer allocated by the caller. + On output, it is the size of the buffer returned by the firmware + if the buffer was large enough, or the size of the buffer needed + to contain the image(s) information if the buffer was too small. + @param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s) + information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs. + @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number + associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] DescriptorCount A pointer to the location in which firmware returns the number of + descriptors or firmware images within this device. + @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes, + of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] PackageVersion A version number that represents all the firmware images in the device. + The format is vendor specific and new version must have a greater value + than the old version. If PackageVersion is not supported, the value is + 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison + is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates + that package version update is in progress. + @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the + package version name. The buffer is allocated by this function with + AllocatePool(), and it is the caller's responsibility to free it with a call + to FreePool(). + + @retval EFI_SUCCESS The device was successfully updated with the new image. + @retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size + needed to hold the image(s) information is returned in ImageInfoSize. + @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL. + @retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image. + +**/ +EFI_STATUS +EFIAPI +FmpGetImageInfo ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN OUT UINTN *ImageInfoSize, + IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo, + OUT UINT32 *DescriptorVersion, + OUT UINT8 *DescriptorCount, + OUT UINTN *DescriptorSize, + OUT UINT32 *PackageVersion, + OUT CHAR16 **PackageVersionName + ) +{ + MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate; + UINTN Index; + + MicrocodeFmpPrivate = MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(This); + + if(ImageInfoSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (*ImageInfoSize < sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount) { + *ImageInfoSize = sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount; + return EFI_BUFFER_TOO_SMALL; + } + + if (ImageInfo == NULL || + DescriptorVersion == NULL || + DescriptorCount == NULL || + DescriptorSize == NULL || + PackageVersion == NULL || + PackageVersionName == NULL) { + return EFI_INVALID_PARAMETER; + } + + *ImageInfoSize = sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount; + *DescriptorSize = sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR); + *DescriptorCount = MicrocodeFmpPrivate->DescriptorCount; + *DescriptorVersion = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; + + // + // supports 1 ImageInfo descriptor + // + CopyMem(&ImageInfo[0], MicrocodeFmpPrivate->ImageDescriptor, sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount); + for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { + if ((ImageInfo[Index].AttributesSetting & IMAGE_ATTRIBUTE_IN_USE) != 0) { + ImageInfo[Index].LastAttemptVersion = MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion; + ImageInfo[Index].LastAttemptStatus = MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus; + } + } + + // + // package version + // + *PackageVersion = MicrocodeFmpPrivate->PackageVersion; + if (MicrocodeFmpPrivate->PackageVersionName != NULL) { + *PackageVersionName = AllocateCopyPool(StrSize(MicrocodeFmpPrivate->PackageVersionName), MicrocodeFmpPrivate->PackageVersionName); + } + + return EFI_SUCCESS; +} + +/** + Retrieves a copy of the current firmware image of the device. + + This function allows a copy of the current firmware image to be created and saved. + The saved copy could later been used, for example, in firmware image recovery or rollback. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. + The number is between 1 and DescriptorCount. + @param[in,out] Image Points to the buffer where the current image is copied to. + @param[in,out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes. + On return, points to the length of the image, in bytes. + + @retval EFI_SUCCESS The device was successfully updated with the new image. + @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the + image. The current buffer size needed to hold the image is returned + in ImageSize. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_NOT_FOUND The current image is not copied to the buffer. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpGetImage ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN UINT8 ImageIndex, + IN OUT VOID *Image, + IN OUT UINTN *ImageSize + ) +{ + MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate; + MICROCODE_INFO *MicrocodeInfo; + + if (Image == NULL || ImageSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + MicrocodeFmpPrivate = MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(This); + + if (ImageIndex == 0 || ImageIndex > MicrocodeFmpPrivate->DescriptorCount || ImageSize == NULL || Image == NULL) { + return EFI_INVALID_PARAMETER; + } + + MicrocodeInfo = &MicrocodeFmpPrivate->MicrocodeInfo[ImageIndex - 1]; + + if (*ImageSize < MicrocodeInfo->TotalSize) { + *ImageSize = MicrocodeInfo->TotalSize; + return EFI_BUFFER_TOO_SMALL; + } + + *ImageSize = MicrocodeInfo->TotalSize; + CopyMem (Image, MicrocodeInfo->MicrocodeEntryPoint, MicrocodeInfo->TotalSize); + return EFI_SUCCESS; +} + +/** + Updates the firmware image of the device. + + This function updates the hardware with the new firmware image. + This function returns EFI_UNSUPPORTED if the firmware image is not updatable. + If the firmware image is updatable, the function should perform the following minimal validations + before proceeding to do the firmware image update. + - Validate the image authentication if image has attribute + IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns + EFI_SECURITY_VIOLATION if the validation fails. + - Validate the image is a supported image for this device. The function returns EFI_ABORTED if + the image is unsupported. The function can optionally provide more detailed information on + why the image is not a supported image. + - Validate the data from VendorCode if not null. Image validation must be performed before + VendorCode data validation. VendorCode data is ignored or considered invalid if image + validation failed. The function returns EFI_ABORTED if the data is invalid. + + VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if + the caller did not specify the policy or use the default policy. As an example, vendor can implement + a policy to allow an option to force a firmware image update when the abort reason is due to the new + firmware image version is older than the current firmware image version or bad image checksum. + Sensitive operations such as those wiping the entire firmware image and render the device to be + non-functional should be encoded in the image itself rather than passed with the VendorCode. + AbortReason enables vendor to have the option to provide a more detailed description of the abort + reason to the caller. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. + The number is between 1 and DescriptorCount. + @param[in] Image Points to the new image. + @param[in] ImageSize Size of the new image in bytes. + @param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy. + Null indicates the caller did not specify the policy or use the default policy. + @param[in] Progress A function used by the driver to report the progress of the firmware update. + @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more + details for the aborted operation. The buffer is allocated by this function + with AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + + @retval EFI_SUCCESS The device was successfully updated with the new image. + @retval EFI_ABORTED The operation is aborted. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpSetImage ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN UINT8 ImageIndex, + IN CONST VOID *Image, + IN UINTN ImageSize, + IN CONST VOID *VendorCode, + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, + OUT CHAR16 **AbortReason + ) +{ + EFI_STATUS Status; + EFI_STATUS VarStatus; + MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate; + + if (Image == NULL || AbortReason == NULL) { + return EFI_INVALID_PARAMETER; + } + + MicrocodeFmpPrivate = MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(This); + *AbortReason = NULL; + + if (ImageIndex == 0 || ImageIndex > MicrocodeFmpPrivate->DescriptorCount || Image == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = MicrocodeWrite(MicrocodeFmpPrivate, (VOID *)Image, ImageSize, &MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, &MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus, AbortReason); + DEBUG((DEBUG_INFO, "SetImage - LastAttemp Version - 0x%x, State - 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); + VarStatus = gRT->SetVariable( + MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME, + &gEfiCallerIdGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(MicrocodeFmpPrivate->LastAttempt), + &MicrocodeFmpPrivate->LastAttempt + ); + DEBUG((DEBUG_INFO, "SetLastAttemp - %r\n", VarStatus)); + + if (!EFI_ERROR(Status)) { + InitializeMicrocodeDescriptor(MicrocodeFmpPrivate); + DumpPrivateInfo (MicrocodeFmpPrivate); + } + + return Status; +} + +/** + Checks if the firmware image is valid for the device. + + This function allows firmware update application to validate the firmware image without + invoking the SetImage() first. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. + The number is between 1 and DescriptorCount. + @param[in] Image Points to the new image. + @param[in] ImageSize Size of the new image in bytes. + @param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides, + if available, additional information if the image is invalid. + + @retval EFI_SUCCESS The image was successfully checked. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpCheckImage ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN UINT8 ImageIndex, + IN CONST VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *ImageUpdatable + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Returns information about the firmware package. + + This function returns package information. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[out] PackageVersion A version number that represents all the firmware images in the device. + The format is vendor specific and new version must have a greater value + than the old version. If PackageVersion is not supported, the value is + 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version + comparison is to be performed using PackageVersionName. A value of + 0xFFFFFFFD indicates that package version update is in progress. + @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing + the package version name. The buffer is allocated by this function with + AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + @param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of + package version name. A value of 0 indicates the device does not support + update of package version name. Length is the number of Unicode characters, + including the terminating null character. + @param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute + Definitions' for possible returned values of this parameter. A value of 1 + indicates the attribute is supported and the current setting value is + indicated in AttributesSetting. A value of 0 indicates the attribute is not + supported and the current setting value in AttributesSetting is meaningless. + @param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned + values of this parameter + + @retval EFI_SUCCESS The package information was successfully returned. + @retval EFI_UNSUPPORTED The operation is not supported. + +**/ +EFI_STATUS +EFIAPI +FmpGetPackageInfo ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + OUT UINT32 *PackageVersion, + OUT CHAR16 **PackageVersionName, + OUT UINT32 *PackageVersionNameMaxLen, + OUT UINT64 *AttributesSupported, + OUT UINT64 *AttributesSetting + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Updates information about the firmware package. + + This function updates package information. + This function returns EFI_UNSUPPORTED if the package information is not updatable. + VendorCode enables vendor to implement vendor-specific package information update policy. + Null if the caller did not specify this policy or use the default policy. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] Image Points to the authentication image. + Null if authentication is not required. + @param[in] ImageSize Size of the authentication image in bytes. + 0 if authentication is not required. + @param[in] VendorCode This enables vendor to implement vendor-specific firmware + image update policy. + Null indicates the caller did not specify this policy or use + the default policy. + @param[in] PackageVersion The new package version. + @param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing + the package version name. + The string length is equal to or less than the value returned in + PackageVersionNameMaxLen. + + @retval EFI_SUCCESS The device was successfully updated with the new package + information. + @retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value + returned in PackageVersionNameMaxLen. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpSetPackageInfo ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN CONST VOID *Image, + IN UINTN ImageSize, + IN CONST VOID *VendorCode, + IN UINT32 PackageVersion, + IN CONST CHAR16 *PackageVersionName + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Initialize Processor Microcode Index. + + @param[in] MicrocodeFmpPrivate private data structure to be initialized. +**/ +VOID +InitializedProcessorMicrocodeIndex ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + UINTN CpuIndex; + UINTN MicrocodeIndex; + UINTN TargetCpuIndex; + UINT32 AttemptStatus; + EFI_STATUS Status; + + for (CpuIndex = 0; CpuIndex < MicrocodeFmpPrivate->ProcessorCount; CpuIndex++) { + if (MicrocodeFmpPrivate->ProcessorInfo[CpuIndex].MicrocodeIndex != (UINTN)-1) { + continue; + } + for (MicrocodeIndex = 0; MicrocodeIndex < MicrocodeFmpPrivate->DescriptorCount; MicrocodeIndex++) { + if (!MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].InUse) { + continue; + } + TargetCpuIndex = CpuIndex; + Status = VerifyMicrocode( + MicrocodeFmpPrivate, + MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].MicrocodeEntryPoint, + MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].TotalSize, + FALSE, + &AttemptStatus, + NULL, + &TargetCpuIndex + ); + if (!EFI_ERROR(Status)) { + MicrocodeFmpPrivate->ProcessorInfo[CpuIndex].MicrocodeIndex = MicrocodeIndex; + } + } + } +} + +/** + Initialize Microcode Descriptor. + + @param[in] MicrocodeFmpPrivate private data structure to be initialized. + + @return EFI_SUCCESS Microcode Descriptor is initialized. +**/ +EFI_STATUS +InitializeMicrocodeDescriptor ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + UINT8 CurrentMicrocodeCount; + + CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate, 0, NULL, NULL); + + if (CurrentMicrocodeCount > MicrocodeFmpPrivate->DescriptorCount) { + if (MicrocodeFmpPrivate->ImageDescriptor != NULL) { + FreePool(MicrocodeFmpPrivate->ImageDescriptor); + MicrocodeFmpPrivate->ImageDescriptor = NULL; + } + if (MicrocodeFmpPrivate->MicrocodeInfo != NULL) { + FreePool(MicrocodeFmpPrivate->MicrocodeInfo); + MicrocodeFmpPrivate->MicrocodeInfo = NULL; + } + } else { + ZeroMem(MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->DescriptorCount * sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR)); + ZeroMem(MicrocodeFmpPrivate->MicrocodeInfo, MicrocodeFmpPrivate->DescriptorCount * sizeof(MICROCODE_INFO)); + } + + MicrocodeFmpPrivate->DescriptorCount = CurrentMicrocodeCount; + + if (MicrocodeFmpPrivate->ImageDescriptor == NULL) { + MicrocodeFmpPrivate->ImageDescriptor = AllocateZeroPool(MicrocodeFmpPrivate->DescriptorCount * sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR)); + if (MicrocodeFmpPrivate->ImageDescriptor == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + if (MicrocodeFmpPrivate->MicrocodeInfo == NULL) { + MicrocodeFmpPrivate->MicrocodeInfo = AllocateZeroPool(MicrocodeFmpPrivate->DescriptorCount * sizeof(MICROCODE_INFO)); + if (MicrocodeFmpPrivate->MicrocodeInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate, MicrocodeFmpPrivate->DescriptorCount, MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->MicrocodeInfo); + ASSERT(CurrentMicrocodeCount == MicrocodeFmpPrivate->DescriptorCount); + + InitializedProcessorMicrocodeIndex (MicrocodeFmpPrivate); + + return EFI_SUCCESS; +} + +/** + Initialize MicrocodeFmpDriver multiprocessor information. + + @param[in] MicrocodeFmpPrivate private data structure to be initialized. + + @return EFI_SUCCESS private data is initialized. +**/ +EFI_STATUS +InitializeProcessorInfo ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpService; + UINTN NumberOfProcessors; + UINTN NumberOfEnabledProcessors; + UINTN Index; + UINTN BspIndex; + + Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpService); + ASSERT_EFI_ERROR(Status); + + MicrocodeFmpPrivate->MpService = MpService; + MicrocodeFmpPrivate->ProcessorCount = 0; + MicrocodeFmpPrivate->ProcessorInfo = NULL; + + Status = MpService->GetNumberOfProcessors (MpService, &NumberOfProcessors, &NumberOfEnabledProcessors); + ASSERT_EFI_ERROR(Status); + MicrocodeFmpPrivate->ProcessorCount = NumberOfProcessors; + + Status = MpService->WhoAmI (MpService, &BspIndex); + ASSERT_EFI_ERROR(Status); + MicrocodeFmpPrivate->BspIndex = BspIndex; + + MicrocodeFmpPrivate->ProcessorInfo = AllocateZeroPool (sizeof(PROCESSOR_INFO) * MicrocodeFmpPrivate->ProcessorCount); + if (MicrocodeFmpPrivate->ProcessorInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < NumberOfProcessors; Index++) { + MicrocodeFmpPrivate->ProcessorInfo[Index].CpuIndex = Index; + MicrocodeFmpPrivate->ProcessorInfo[Index].MicrocodeIndex = (UINTN)-1; + if (Index == BspIndex) { + CollectProcessorInfo (&MicrocodeFmpPrivate->ProcessorInfo[Index]); + } else { + Status = MpService->StartupThisAP ( + MpService, + CollectProcessorInfo, + Index, + NULL, + 0, + &MicrocodeFmpPrivate->ProcessorInfo[Index], + NULL + ); + ASSERT_EFI_ERROR(Status); + } + } + + return EFI_SUCCESS; +} + +/** + Dump private information. + + @param[in] MicrocodeFmpPrivate private data structure. +**/ +VOID +DumpPrivateInfo ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + UINTN Index; + PROCESSOR_INFO *ProcessorInfo; + MICROCODE_INFO *MicrocodeInfo; + EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; + + DEBUG ((DEBUG_INFO, "ProcessorInfo:\n")); + DEBUG ((DEBUG_INFO, " ProcessorCount - 0x%x\n", MicrocodeFmpPrivate->ProcessorCount)); + DEBUG ((DEBUG_INFO, " BspIndex - 0x%x\n", MicrocodeFmpPrivate->BspIndex)); + + ProcessorInfo = MicrocodeFmpPrivate->ProcessorInfo; + for (Index = 0; Index < MicrocodeFmpPrivate->ProcessorCount; Index++) { + DEBUG (( + DEBUG_INFO, + " ProcessorInfo[0x%x] - 0x%08x, 0x%02x, 0x%08x, (0x%x)\n", + ProcessorInfo[Index].CpuIndex, + ProcessorInfo[Index].ProcessorSignature, + ProcessorInfo[Index].PlatformId, + ProcessorInfo[Index].MicrocodeRevision, + ProcessorInfo[Index].MicrocodeIndex + )); + } + + DEBUG ((DEBUG_INFO, "MicrocodeInfo:\n")); + MicrocodeInfo = MicrocodeFmpPrivate->MicrocodeInfo; + DEBUG ((DEBUG_INFO, " MicrocodeRegion - 0x%x - 0x%x\n", MicrocodeFmpPrivate->MicrocodePatchAddress, MicrocodeFmpPrivate->MicrocodePatchRegionSize)); + DEBUG ((DEBUG_INFO, " MicrocodeCount - 0x%x\n", MicrocodeFmpPrivate->DescriptorCount)); + for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { + DEBUG (( + DEBUG_INFO, + " MicrocodeInfo[0x%x] - 0x%08x, 0x%08x, (0x%x)\n", + Index, + MicrocodeInfo[Index].MicrocodeEntryPoint, + MicrocodeInfo[Index].TotalSize, + MicrocodeInfo[Index].InUse + )); + } + + ImageDescriptor = MicrocodeFmpPrivate->ImageDescriptor; + DEBUG ((DEBUG_VERBOSE, "ImageDescriptor:\n")); + for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { + DEBUG((DEBUG_VERBOSE, " ImageDescriptor (%d)\n", Index)); + DEBUG((DEBUG_VERBOSE, " ImageIndex - 0x%x\n", ImageDescriptor[Index].ImageIndex)); + DEBUG((DEBUG_VERBOSE, " ImageTypeId - %g\n", &ImageDescriptor[Index].ImageTypeId)); + DEBUG((DEBUG_VERBOSE, " ImageId - 0x%lx\n", ImageDescriptor[Index].ImageId)); + DEBUG((DEBUG_VERBOSE, " ImageIdName - %s\n", ImageDescriptor[Index].ImageIdName)); + DEBUG((DEBUG_VERBOSE, " Version - 0x%x\n", ImageDescriptor[Index].Version)); + DEBUG((DEBUG_VERBOSE, " VersionName - %s\n", ImageDescriptor[Index].VersionName)); + DEBUG((DEBUG_VERBOSE, " Size - 0x%x\n", ImageDescriptor[Index].Size)); + DEBUG((DEBUG_VERBOSE, " AttributesSupported - 0x%lx\n", ImageDescriptor[Index].AttributesSupported)); + DEBUG((DEBUG_VERBOSE, " AttributesSetting - 0x%lx\n", ImageDescriptor[Index].AttributesSetting)); + DEBUG((DEBUG_VERBOSE, " Compatibilities - 0x%lx\n", ImageDescriptor[Index].Compatibilities)); + DEBUG((DEBUG_VERBOSE, " LowestSupportedImageVersion - 0x%x\n", ImageDescriptor[Index].LowestSupportedImageVersion)); + DEBUG((DEBUG_VERBOSE, " LastAttemptVersion - 0x%x\n", ImageDescriptor[Index].LastAttemptVersion)); + DEBUG((DEBUG_VERBOSE, " LastAttemptStatus - 0x%x\n", ImageDescriptor[Index].LastAttemptStatus)); + DEBUG((DEBUG_VERBOSE, " HardwareInstance - 0x%lx\n", ImageDescriptor[Index].HardwareInstance)); + } +} + +/** + Initialize MicrocodeFmpDriver private data structure. + + @param[in] MicrocodeFmpPrivate private data structure to be initialized. + + @return EFI_SUCCESS private data is initialized. +**/ +EFI_STATUS +InitializePrivateData ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + EFI_STATUS Status; + EFI_STATUS VarStatus; + UINTN VarSize; + BOOLEAN Result; + + MicrocodeFmpPrivate->Signature = MICROCODE_FMP_PRIVATE_DATA_SIGNATURE; + MicrocodeFmpPrivate->Handle = NULL; + CopyMem(&MicrocodeFmpPrivate->Fmp, &mFirmwareManagementProtocol, sizeof(EFI_FIRMWARE_MANAGEMENT_PROTOCOL)); + + MicrocodeFmpPrivate->PackageVersion = 0x1; + MicrocodeFmpPrivate->PackageVersionName = L"Microcode"; + + MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion = 0x0; + MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus = 0x0; + VarSize = sizeof(MicrocodeFmpPrivate->LastAttempt); + VarStatus = gRT->GetVariable( + MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME, + &gEfiCallerIdGuid, + NULL, + &VarSize, + &MicrocodeFmpPrivate->LastAttempt + ); + DEBUG((DEBUG_INFO, "GetLastAttemp - %r\n", VarStatus)); + DEBUG((DEBUG_INFO, "GetLastAttemp Version - 0x%x, State - 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); + + Result = GetMicrocodeRegion(&MicrocodeFmpPrivate->MicrocodePatchAddress, &MicrocodeFmpPrivate->MicrocodePatchRegionSize); + if (!Result) { + DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n")); + return EFI_NOT_FOUND; + } + + Status = InitializeProcessorInfo (MicrocodeFmpPrivate); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "InitializeProcessorInfo - %r\n", Status)); + return Status; + } + + Status = InitializeMicrocodeDescriptor(MicrocodeFmpPrivate); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "InitializeMicrocodeDescriptor - %r\n", Status)); + return Status; + } + + DumpPrivateInfo (MicrocodeFmpPrivate); + + return Status; +} + +/** + Microcode FMP module entrypoint + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @return EFI_SUCCESS Microcode FMP module is initialized. +**/ +EFI_STATUS +EFIAPI +MicrocodeFmpMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Initialize MicrocodeFmpPrivateData + // + mMicrocodeFmpPrivate = AllocateZeroPool (sizeof(MICROCODE_FMP_PRIVATE_DATA)); + if (mMicrocodeFmpPrivate == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = InitializePrivateData(mMicrocodeFmpPrivate); + if (EFI_ERROR(Status)) { + FreePool(mMicrocodeFmpPrivate); + mMicrocodeFmpPrivate = NULL; + return Status; + } + + // + // Install FMP protocol. + // + Status = gBS->InstallProtocolInterface ( + &mMicrocodeFmpPrivate->Handle, + &gEfiFirmwareManagementProtocolGuid, + EFI_NATIVE_INTERFACE, + &mMicrocodeFmpPrivate->Fmp + ); + if (EFI_ERROR (Status)) { + FreePool(mMicrocodeFmpPrivate); + mMicrocodeFmpPrivate = NULL; + return Status; + } + + return Status; +} diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c new file mode 100644 index 0000000000..4e8f1d5fd8 --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c @@ -0,0 +1,981 @@ +/** @file + SetImage instance to update Microcode. + + Caution: This module requires additional review when modified. + This module will have external input - capsule image. + This external input must be validated carefully to avoid security issue like + buffer overflow, integer overflow. + + MicrocodeWrite() and VerifyMicrocode() will receive untrusted input and do basic validation. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "MicrocodeUpdate.h" + +/** + Get Microcode Region. + + @param[out] MicrocodePatchAddress The address of Microcode + @param[out] MicrocodePatchRegionSize The region size of Microcode + + @retval TRUE The Microcode region is returned. + @retval FALSE No Microcode region. +**/ +BOOLEAN +GetMicrocodeRegion ( + OUT VOID **MicrocodePatchAddress, + OUT UINTN *MicrocodePatchRegionSize + ) +{ + *MicrocodePatchAddress = (VOID *)(UINTN)PcdGet64(PcdCpuMicrocodePatchAddress); + *MicrocodePatchRegionSize = (UINTN)PcdGet64(PcdCpuMicrocodePatchRegionSize); + + if ((*MicrocodePatchAddress == NULL) || (*MicrocodePatchRegionSize == 0)) { + return FALSE; + } + + return TRUE; +} + +/** + Get Microcode update signature of currently loaded Microcode update. + + @return Microcode signature. + +**/ +UINT32 +GetCurrentMicrocodeSignature ( + VOID + ) +{ + UINT64 Signature; + + AsmWriteMsr64(MSR_IA32_BIOS_SIGN_ID, 0); + AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); + Signature = AsmReadMsr64(MSR_IA32_BIOS_SIGN_ID); + return (UINT32)RShiftU64(Signature, 32); +} + +/** + Get current processor signature. + + @return current processor signature. +**/ +UINT32 +GetCurrentProcessorSignature ( + VOID + ) +{ + UINT32 RegEax; + AsmCpuid(CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL); + return RegEax; +} + +/** + Get current platform ID. + + @return current platform ID. +**/ +UINT8 +GetCurrentPlatformId ( + VOID + ) +{ + UINT8 PlatformId; + + PlatformId = (UINT8)AsmMsrBitFieldRead64(MSR_IA32_PLATFORM_ID, 50, 52); + return PlatformId; +} + +/** + Load new Microcode. + + @param[in] Address The address of new Microcode. + + @return Loaded Microcode signature. + +**/ +UINT32 +LoadMicrocode ( + IN UINT64 Address + ) +{ + AsmWriteMsr64(MSR_IA32_BIOS_UPDT_TRIG, Address); + return GetCurrentMicrocodeSignature(); +} + +/** + Load Microcode on an Application Processor. + The function prototype for invoking a function on an Application Processor. + + @param[in,out] Buffer The pointer to private data buffer. +**/ +VOID +EFIAPI +MicrocodeLoadAp ( + IN OUT VOID *Buffer + ) +{ + MICROCODE_LOAD_BUFFER *MicrocodeLoadBuffer; + + MicrocodeLoadBuffer = Buffer; + MicrocodeLoadBuffer->Revision = LoadMicrocode (MicrocodeLoadBuffer->Address); +} + +/** + Load new Microcode on this processor + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] CpuIndex The index of the processor. + @param[in] Address The address of new Microcode. + + @return Loaded Microcode signature. + +**/ +UINT32 +LoadMicrocodeOnThis ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN UINTN CpuIndex, + IN UINT64 Address + ) +{ + EFI_STATUS Status; + EFI_MP_SERVICES_PROTOCOL *MpService; + MICROCODE_LOAD_BUFFER MicrocodeLoadBuffer; + + if (CpuIndex == MicrocodeFmpPrivate->BspIndex) { + return LoadMicrocode (Address); + } else { + MpService = MicrocodeFmpPrivate->MpService; + MicrocodeLoadBuffer.Address = Address; + MicrocodeLoadBuffer.Revision = 0; + Status = MpService->StartupThisAP ( + MpService, + MicrocodeLoadAp, + CpuIndex, + NULL, + 0, + &MicrocodeLoadBuffer, + NULL + ); + ASSERT_EFI_ERROR(Status); + return MicrocodeLoadBuffer.Revision; + } +} + +/** + Collect processor information. + The function prototype for invoking a function on an Application Processor. + + @param[in,out] Buffer The pointer to private data buffer. +**/ +VOID +EFIAPI +CollectProcessorInfo ( + IN OUT VOID *Buffer + ) +{ + PROCESSOR_INFO *ProcessorInfo; + + ProcessorInfo = Buffer; + ProcessorInfo->ProcessorSignature = GetCurrentProcessorSignature(); + ProcessorInfo->PlatformId = GetCurrentPlatformId(); + ProcessorInfo->MicrocodeRevision = GetCurrentMicrocodeSignature(); +} + +/** + Get current Microcode information. + + The ProcessorInformation (BspIndex/ProcessorCount/ProcessorInfo) + in MicrocodeFmpPrivate must be initialized. + + The MicrocodeInformation (DescriptorCount/ImageDescriptor/MicrocodeInfo) + in MicrocodeFmpPrivate may not be avaiable in this function. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] DescriptorCount The count of Microcode ImageDescriptor allocated. + @param[out] ImageDescriptor Microcode ImageDescriptor + @param[out] MicrocodeInfo Microcode information + + @return Microcode count +**/ +UINTN +GetMicrocodeInfo ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN UINTN DescriptorCount, OPTIONAL + OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor, OPTIONAL + OUT MICROCODE_INFO *MicrocodeInfo OPTIONAL + ) +{ + VOID *MicrocodePatchAddress; + UINTN MicrocodePatchRegionSize; + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + UINTN MicrocodeEnd; + UINTN TotalSize; + UINTN Count; + UINT64 ImageAttributes; + BOOLEAN IsInUse; + EFI_STATUS Status; + UINT32 AttemptStatus; + UINTN TargetCpuIndex; + + MicrocodePatchAddress = MicrocodeFmpPrivate->MicrocodePatchAddress; + MicrocodePatchRegionSize = MicrocodeFmpPrivate->MicrocodePatchRegionSize; + + DEBUG((DEBUG_INFO, "Microcode Region - 0x%x - 0x%x\n", MicrocodePatchAddress, MicrocodePatchRegionSize)); + + Count = 0; + + MicrocodeEnd = (UINTN)MicrocodePatchAddress + MicrocodePatchRegionSize; + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress; + do { + if (MicrocodeEntryPoint->HeaderVersion == 0x1 && MicrocodeEntryPoint->LoaderRevision == 0x1) { + // + // It is the microcode header. It is not the padding data between microcode patches + // becasue the padding data should not include 0x00000001 and it should be the repeated + // byte format (like 0xXYXYXYXY....). + // + if (MicrocodeEntryPoint->DataSize == 0) { + TotalSize = 2048; + } else { + TotalSize = MicrocodeEntryPoint->TotalSize; + } + + TargetCpuIndex = (UINTN)-1; + Status = VerifyMicrocode(MicrocodeFmpPrivate, MicrocodeEntryPoint, TotalSize, FALSE, &AttemptStatus, NULL, &TargetCpuIndex); + if (!EFI_ERROR(Status)) { + IsInUse = TRUE; + ASSERT (TargetCpuIndex < MicrocodeFmpPrivate->ProcessorCount); + MicrocodeFmpPrivate->ProcessorInfo[TargetCpuIndex].MicrocodeIndex = Count; + } else { + IsInUse = FALSE; + } + + if (ImageDescriptor != NULL && DescriptorCount > Count) { + ImageDescriptor[Count].ImageIndex = (UINT8)(Count + 1); + CopyGuid (&ImageDescriptor[Count].ImageTypeId, &gMicrocodeFmpImageTypeIdGuid); + ImageDescriptor[Count].ImageId = LShiftU64(MicrocodeEntryPoint->ProcessorFlags, 32) + MicrocodeEntryPoint->ProcessorSignature.Uint32; + ImageDescriptor[Count].ImageIdName = NULL; + ImageDescriptor[Count].Version = MicrocodeEntryPoint->UpdateRevision; + ImageDescriptor[Count].VersionName = NULL; + ImageDescriptor[Count].Size = TotalSize; + ImageAttributes = IMAGE_ATTRIBUTE_IMAGE_UPDATABLE | IMAGE_ATTRIBUTE_RESET_REQUIRED; + if (IsInUse) { + ImageAttributes |= IMAGE_ATTRIBUTE_IN_USE; + } + ImageDescriptor[Count].AttributesSupported = ImageAttributes | IMAGE_ATTRIBUTE_IN_USE; + ImageDescriptor[Count].AttributesSetting = ImageAttributes; + ImageDescriptor[Count].Compatibilities = 0; + ImageDescriptor[Count].LowestSupportedImageVersion = MicrocodeEntryPoint->UpdateRevision; // do not support rollback + ImageDescriptor[Count].LastAttemptVersion = 0; + ImageDescriptor[Count].LastAttemptStatus = 0; + ImageDescriptor[Count].HardwareInstance = 0; + } + if (MicrocodeInfo != NULL && DescriptorCount > Count) { + MicrocodeInfo[Count].MicrocodeEntryPoint = MicrocodeEntryPoint; + MicrocodeInfo[Count].TotalSize = TotalSize; + MicrocodeInfo[Count].InUse = IsInUse; + } + } else { + // + // It is the padding data between the microcode patches for microcode patches alignment. + // Because the microcode patch is the multiple of 1-KByte, the padding data should not + // exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode + // alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to + // find the next possible microcode patch header. + // + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); + continue; + } + + Count++; + ASSERT(Count < 0xFF); + + // + // Get the next patch. + // + MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize); + } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); + + return Count; +} + +/** + Return matched processor information. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] ProcessorSignature The processor signature to be matched + @param[in] ProcessorFlags The processor flags to be matched + @param[in, out] TargetCpuIndex On input, the index of target CPU which tries to match the Microcode. (UINTN)-1 means to try all. + On output, the index of target CPU which matches the Microcode. + + @return matched processor information. +**/ +PROCESSOR_INFO * +GetMatchedProcessor ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN UINT32 ProcessorSignature, + IN UINT32 ProcessorFlags, + IN OUT UINTN *TargetCpuIndex + ) +{ + UINTN Index; + + if (*TargetCpuIndex != (UINTN)-1) { + Index = *TargetCpuIndex; + if ((ProcessorSignature == MicrocodeFmpPrivate->ProcessorInfo[Index].ProcessorSignature) && + ((ProcessorFlags & (1 << MicrocodeFmpPrivate->ProcessorInfo[Index].PlatformId)) != 0)) { + return &MicrocodeFmpPrivate->ProcessorInfo[Index]; + } else { + return NULL; + } + } + + for (Index = 0; Index < MicrocodeFmpPrivate->ProcessorCount; Index++) { + if ((ProcessorSignature == MicrocodeFmpPrivate->ProcessorInfo[Index].ProcessorSignature) && + ((ProcessorFlags & (1 << MicrocodeFmpPrivate->ProcessorInfo[Index].PlatformId)) != 0)) { + *TargetCpuIndex = Index; + return &MicrocodeFmpPrivate->ProcessorInfo[Index]; + } + } + return NULL; +} + +/** + Verify Microcode. + + Caution: This function may receive untrusted input. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffer in bytes. + @param[in] TryLoad Try to load Microcode or not. + @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more + details for the aborted operation. The buffer is allocated by this function + with AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + @param[in, out] TargetCpuIndex On input, the index of target CPU which tries to match the Microcode. (UINTN)-1 means to try all. + On output, the index of target CPU which matches the Microcode. + + @retval EFI_SUCCESS The Microcode image passes verification. + @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. + @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. + @retval EFI_UNSUPPORTED The Microcode ProcessorSignature or ProcessorFlags is incorrect. + @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. +**/ +EFI_STATUS +VerifyMicrocode ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN VOID *Image, + IN UINTN ImageSize, + IN BOOLEAN TryLoad, + OUT UINT32 *LastAttemptStatus, + OUT CHAR16 **AbortReason, OPTIONAL + IN OUT UINTN *TargetCpuIndex + ) +{ + UINTN Index; + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + UINTN TotalSize; + UINTN DataSize; + UINT32 CurrentRevision; + PROCESSOR_INFO *ProcessorInfo; + UINT32 CheckSum32; + UINTN ExtendedTableLength; + UINT32 ExtendedTableCount; + CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; + CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; + BOOLEAN CorrectMicrocode; + + // + // Check HeaderVersion + // + MicrocodeEntryPoint = Image; + if (MicrocodeEntryPoint->HeaderVersion != 0x1) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on HeaderVersion\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidHeaderVersion"), L"InvalidHeaderVersion"); + } + return EFI_INCOMPATIBLE_VERSION; + } + // + // Check LoaderRevision + // + if (MicrocodeEntryPoint->LoaderRevision != 0x1) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on LoaderRevision\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidLoaderVersion"), L"InvalidLoaderVersion"); + } + return EFI_INCOMPATIBLE_VERSION; + } + // + // Check Size + // + if (MicrocodeEntryPoint->DataSize == 0) { + TotalSize = 2048; + } else { + TotalSize = MicrocodeEntryPoint->TotalSize; + } + if (TotalSize <= sizeof(CPU_MICROCODE_HEADER)) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - TotalSize too small\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidTotalSize"), L"InvalidTotalSize"); + } + return EFI_VOLUME_CORRUPTED; + } + if (TotalSize != ImageSize) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on TotalSize\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidTotalSize"), L"InvalidTotalSize"); + } + return EFI_VOLUME_CORRUPTED; + } + // + // Check CheckSum32 + // + if (MicrocodeEntryPoint->DataSize == 0) { + DataSize = 2048 - sizeof(CPU_MICROCODE_HEADER); + } else { + DataSize = MicrocodeEntryPoint->DataSize; + } + if (DataSize > TotalSize - sizeof(CPU_MICROCODE_HEADER)) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - DataSize too big\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidDataSize"), L"InvalidDataSize"); + } + return EFI_VOLUME_CORRUPTED; + } + if ((DataSize & 0x3) != 0) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - DataSize not aligned\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidDataSize"), L"InvalidDataSize"); + } + return EFI_VOLUME_CORRUPTED; + } + CheckSum32 = CalculateSum32((UINT32 *)MicrocodeEntryPoint, DataSize + sizeof(CPU_MICROCODE_HEADER)); + if (CheckSum32 != 0) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on CheckSum32\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidChecksum"), L"InvalidChecksum"); + } + return EFI_VOLUME_CORRUPTED; + } + + // + // Check ProcessorSignature/ProcessorFlags + // + + ProcessorInfo = GetMatchedProcessor (MicrocodeFmpPrivate, MicrocodeEntryPoint->ProcessorSignature.Uint32, MicrocodeEntryPoint->ProcessorFlags, TargetCpuIndex); + if (ProcessorInfo == NULL) { + CorrectMicrocode = FALSE; + ExtendedTableLength = TotalSize - (DataSize + sizeof(CPU_MICROCODE_HEADER)); + if (ExtendedTableLength != 0) { + // + // Extended Table exist, check if the CPU in support list + // + ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + DataSize + sizeof(CPU_MICROCODE_HEADER)); + // + // Calculate Extended Checksum + // + if ((ExtendedTableLength > sizeof(CPU_MICROCODE_EXTENDED_TABLE_HEADER)) && ((ExtendedTableLength & 0x3) != 0)) { + CheckSum32 = CalculateSum32((UINT32 *)ExtendedTableHeader, ExtendedTableLength); + if (CheckSum32 == 0) { + // + // Checksum correct + // + ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount; + if (ExtendedTableCount <= (ExtendedTableLength - sizeof(CPU_MICROCODE_EXTENDED_TABLE_HEADER)) / sizeof(CPU_MICROCODE_EXTENDED_TABLE)) { + ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1); + for (Index = 0; Index < ExtendedTableCount; Index++) { + CheckSum32 = CalculateSum32((UINT32 *)ExtendedTable, sizeof(CPU_MICROCODE_EXTENDED_TABLE)); + if (CheckSum32 == 0) { + // + // Verify Header + // + ProcessorInfo = GetMatchedProcessor (MicrocodeFmpPrivate, ExtendedTable->ProcessorSignature.Uint32, ExtendedTable->ProcessorFlag, TargetCpuIndex); + if (ProcessorInfo != NULL) { + // + // Find one + // + CorrectMicrocode = TRUE; + break; + } + } + ExtendedTable++; + } + } + } + } + } + if (!CorrectMicrocode) { + if (TryLoad) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on CurrentProcessorSignature/ProcessorFlags\n")); + } + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"UnsupportedProcessSignature/ProcessorFlags"), L"UnsupportedProcessSignature/ProcessorFlags"); + } + return EFI_UNSUPPORTED; + } + } + + // + // Check UpdateRevision + // + CurrentRevision = ProcessorInfo->MicrocodeRevision; + if ((MicrocodeEntryPoint->UpdateRevision < CurrentRevision) || + (TryLoad && (MicrocodeEntryPoint->UpdateRevision == CurrentRevision))) { + if (TryLoad) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on UpdateRevision\n")); + } + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"IncorrectRevision"), L"IncorrectRevision"); + } + return EFI_INCOMPATIBLE_VERSION; + } + + // + // try load MCU + // + if (TryLoad) { + CurrentRevision = LoadMicrocodeOnThis(MicrocodeFmpPrivate, ProcessorInfo->CpuIndex, (UINTN)MicrocodeEntryPoint + sizeof(CPU_MICROCODE_HEADER)); + if (MicrocodeEntryPoint->UpdateRevision != CurrentRevision) { + DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on LoadMicrocode\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR; + if (AbortReason != NULL) { + *AbortReason = AllocateCopyPool(sizeof(L"InvalidData"), L"InvalidData"); + } + return EFI_SECURITY_VIOLATION; + } + } + + return EFI_SUCCESS; +} + +/** + Get next Microcode entrypoint. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] MicrocodeEntryPoint Current Microcode entrypoint + + @return next Microcode entrypoint. +**/ +CPU_MICROCODE_HEADER * +GetNextMicrocode ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint + ) +{ + UINTN Index; + + for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { + if (MicrocodeEntryPoint == MicrocodeFmpPrivate->MicrocodeInfo[Index].MicrocodeEntryPoint) { + if (Index == (UINTN)MicrocodeFmpPrivate->DescriptorCount - 1) { + // it is last one + return NULL; + } else { + // return next one + return MicrocodeFmpPrivate->MicrocodeInfo[Index + 1].MicrocodeEntryPoint; + } + } + } + + ASSERT(FALSE); + return NULL; +} + +/** + Get current Microcode used region size. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + + @return current Microcode used region size. +**/ +UINTN +GetCurrentMicrocodeUsedRegionSize ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ) +{ + if (MicrocodeFmpPrivate->DescriptorCount == 0) { + return 0; + } + + return (UINTN)MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeFmpPrivate->DescriptorCount - 1].MicrocodeEntryPoint + + (UINTN)MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeFmpPrivate->DescriptorCount - 1].TotalSize + - (UINTN)MicrocodeFmpPrivate->MicrocodePatchAddress; +} + +/** + Update Microcode. + + @param[in] Address The flash address of Microcode. + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffer in bytes. + @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + + @retval EFI_SUCCESS The Microcode image is updated. + @retval EFI_WRITE_PROTECTED The flash device is read only. +**/ +EFI_STATUS +UpdateMicrocode ( + IN UINT64 Address, + IN VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *LastAttemptStatus + ) +{ + EFI_STATUS Status; + + DEBUG((DEBUG_INFO, "PlatformUpdate:")); + DEBUG((DEBUG_INFO, " Address - 0x%lx,", Address)); + DEBUG((DEBUG_INFO, " Legnth - 0x%x\n", ImageSize)); + + Status = MicrocodeFlashWrite ( + Address, + Image, + ImageSize + ); + if (!EFI_ERROR(Status)) { + *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; + } else { + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; + } + return Status; +} + +/** + Update Microcode flash region. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] TargetMicrocodeEntryPoint Target Microcode entrypoint to be updated + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffer in bytes. + @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + + @retval EFI_SUCCESS The Microcode image is written. + @retval EFI_WRITE_PROTECTED The flash device is read only. +**/ +EFI_STATUS +UpdateMicrocodeFlashRegion ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN CPU_MICROCODE_HEADER *TargetMicrocodeEntryPoint, + IN VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *LastAttemptStatus + ) +{ + VOID *MicrocodePatchAddress; + UINTN MicrocodePatchRegionSize; + UINTN TargetTotalSize; + UINTN UsedRegionSize; + EFI_STATUS Status; + VOID *MicrocodePatchScratchBuffer; + UINT8 *ScratchBufferPtr; + UINTN ScratchBufferSize; + UINTN RestSize; + UINTN AvailableSize; + VOID *NextMicrocodeEntryPoint; + MICROCODE_INFO *MicrocodeInfo; + UINTN MicrocodeCount; + UINTN Index; + + DEBUG((DEBUG_INFO, "UpdateMicrocodeFlashRegion: Image - 0x%x, size - 0x%x\n", Image, ImageSize)); + + MicrocodePatchAddress = MicrocodeFmpPrivate->MicrocodePatchAddress; + MicrocodePatchRegionSize = MicrocodeFmpPrivate->MicrocodePatchRegionSize; + + MicrocodePatchScratchBuffer = AllocateZeroPool (MicrocodePatchRegionSize); + if (MicrocodePatchScratchBuffer == NULL) { + DEBUG((DEBUG_ERROR, "Fail to allocate Microcode Scratch buffer\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; + return EFI_OUT_OF_RESOURCES; + } + ScratchBufferPtr = MicrocodePatchScratchBuffer; + ScratchBufferSize = 0; + + // + // Target data collection + // + TargetTotalSize = 0; + AvailableSize = 0; + NextMicrocodeEntryPoint = NULL; + if (TargetMicrocodeEntryPoint != NULL) { + if (TargetMicrocodeEntryPoint->DataSize == 0) { + TargetTotalSize = 2048; + } else { + TargetTotalSize = TargetMicrocodeEntryPoint->TotalSize; + } + DEBUG((DEBUG_INFO, " TargetTotalSize - 0x%x\n", TargetTotalSize)); + NextMicrocodeEntryPoint = GetNextMicrocode(MicrocodeFmpPrivate, TargetMicrocodeEntryPoint); + DEBUG((DEBUG_INFO, " NextMicrocodeEntryPoint - 0x%x\n", NextMicrocodeEntryPoint)); + if (NextMicrocodeEntryPoint != NULL) { + ASSERT ((UINTN)NextMicrocodeEntryPoint >= ((UINTN)TargetMicrocodeEntryPoint + TargetTotalSize)); + AvailableSize = (UINTN)NextMicrocodeEntryPoint - (UINTN)TargetMicrocodeEntryPoint; + } else { + AvailableSize = (UINTN)MicrocodePatchAddress + MicrocodePatchRegionSize - (UINTN)TargetMicrocodeEntryPoint; + } + DEBUG((DEBUG_INFO, " AvailableSize - 0x%x\n", AvailableSize)); + } + ASSERT (AvailableSize >= TargetTotalSize); + UsedRegionSize = GetCurrentMicrocodeUsedRegionSize(MicrocodeFmpPrivate); + DEBUG((DEBUG_INFO, " UsedRegionSize - 0x%x\n", UsedRegionSize)); + ASSERT (UsedRegionSize >= TargetTotalSize); + if (TargetMicrocodeEntryPoint != NULL) { + ASSERT ((UINTN)MicrocodePatchAddress + UsedRegionSize >= ((UINTN)TargetMicrocodeEntryPoint + TargetTotalSize)); + } + // + // Total Size means the Microcode data size. + // Available Size means the Microcode data size plus the pad till (1) next Microcode or (2) the end. + // + // (1) + // +------+-----------+-----+------+===================+ + // | MCU1 | Microcode | PAD | MCU2 | Empty | + // +------+-----------+-----+------+===================+ + // | TotalSize | + // |<-AvailableSize->| + // |<- UsedRegionSize ->| + // + // (2) + // +------+-----------+===================+ + // | MCU | Microcode | Empty | + // +------+-----------+===================+ + // | TotalSize | + // |<- AvailableSize ->| + // |<-UsedRegionSize->| + // + + // + // Update based on policy + // + + // + // 1. If there is enough space to update old one in situ, replace old microcode in situ. + // + if (AvailableSize >= ImageSize) { + DEBUG((DEBUG_INFO, "Replace old microcode in situ\n")); + // + // +------+------------+------+===================+ + // |Other1| Old Image |Other2| Empty | + // +------+------------+------+===================+ + // + // +------+---------+--+------+===================+ + // |Other1|New Image|FF|Other2| Empty | + // +------+---------+--+------+===================+ + // + // 1.1. Copy new image + CopyMem (ScratchBufferPtr, Image, ImageSize); + ScratchBufferSize += ImageSize; + ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; + // 1.2. Pad 0xFF + RestSize = AvailableSize - ImageSize; + if (RestSize > 0) { + SetMem (ScratchBufferPtr, RestSize, 0xFF); + ScratchBufferSize += RestSize; + ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; + } + Status = UpdateMicrocode((UINTN)TargetMicrocodeEntryPoint, MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); + return Status; + } + + // + // 2. If there is enough space to remove old one and add new one, reorg and replace old microcode. + // + if (MicrocodePatchRegionSize - (UsedRegionSize - TargetTotalSize) >= ImageSize) { + if (TargetMicrocodeEntryPoint == NULL) { + DEBUG((DEBUG_INFO, "Append new microcode\n")); + // + // +------+------------+------+===================+ + // |Other1| Other |Other2| Empty | + // +------+------------+------+===================+ + // + // +------+------------+------+-----------+=======+ + // |Other1| Other |Other2| New Image | Empty | + // +------+------------+------+-----------+=======+ + // + Status = UpdateMicrocode((UINTN)MicrocodePatchAddress + UsedRegionSize, Image, ImageSize, LastAttemptStatus); + } else { + DEBUG((DEBUG_INFO, "Reorg and replace old microcode\n")); + // + // +------+------------+------+===================+ + // |Other1| Old Image |Other2| Empty | + // +------+------------+------+===================+ + // + // +------+---------------+------+================+ + // |Other1| New Image |Other2| Empty | + // +------+---------------+------+================+ + // + // 2.1. Copy new image + CopyMem (ScratchBufferPtr, Image, ImageSize); + ScratchBufferSize += ImageSize; + ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; + // 2.2. Copy rest images after the old image. + if (NextMicrocodeEntryPoint != 0) { + RestSize = (UINTN)MicrocodePatchAddress + UsedRegionSize - ((UINTN)NextMicrocodeEntryPoint); + CopyMem (ScratchBufferPtr, (UINT8 *)TargetMicrocodeEntryPoint + TargetTotalSize, RestSize); + ScratchBufferSize += RestSize; + ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; + } + Status = UpdateMicrocode((UINTN)TargetMicrocodeEntryPoint, MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); + } + return Status; + } + + // + // 3. The new image can be put in MCU region, but not all others can be put. + // So all the unused MCU is removed. + // + if (MicrocodePatchRegionSize >= ImageSize) { + // + // +------+------------+------+===================+ + // |Other1| Old Image |Other2| Empty | + // +------+------------+------+===================+ + // + // +-------------------------------------+--------+ + // | New Image | Other | + // +-------------------------------------+--------+ + // + DEBUG((DEBUG_INFO, "Add new microcode from beginning\n")); + + MicrocodeCount = MicrocodeFmpPrivate->DescriptorCount; + MicrocodeInfo = MicrocodeFmpPrivate->MicrocodeInfo; + + // 3.1. Copy new image + CopyMem (ScratchBufferPtr, Image, ImageSize); + ScratchBufferSize += ImageSize; + ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; + // 3.2. Copy some others to rest buffer + for (Index = 0; Index < MicrocodeCount; Index++) { + if (!MicrocodeInfo[Index].InUse) { + continue; + } + if (MicrocodeInfo[Index].MicrocodeEntryPoint == TargetMicrocodeEntryPoint) { + continue; + } + if (MicrocodeInfo[Index].TotalSize <= MicrocodePatchRegionSize - ScratchBufferSize) { + CopyMem (ScratchBufferPtr, MicrocodeInfo[Index].MicrocodeEntryPoint, MicrocodeInfo[Index].TotalSize); + ScratchBufferSize += MicrocodeInfo[Index].TotalSize; + ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; + } + } + // 3.3. Pad 0xFF + RestSize = MicrocodePatchRegionSize - ScratchBufferSize; + if (RestSize > 0) { + SetMem (ScratchBufferPtr, RestSize, 0xFF); + ScratchBufferSize += RestSize; + ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; + } + Status = UpdateMicrocode((UINTN)MicrocodePatchAddress, MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); + return Status; + } + + // + // 4. The new image size is bigger than the whole MCU region. + // + DEBUG((DEBUG_ERROR, "Microcode too big\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + + return Status; +} + +/** + Write Microcode. + + Caution: This function may receive untrusted input. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffer in bytes. + @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more + details for the aborted operation. The buffer is allocated by this function + with AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + + @retval EFI_SUCCESS The Microcode image is written. + @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. + @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. + @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. + @retval EFI_WRITE_PROTECTED The flash device is read only. +**/ +EFI_STATUS +MicrocodeWrite ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *LastAttemptVersion, + OUT UINT32 *LastAttemptStatus, + OUT CHAR16 **AbortReason + ) +{ + EFI_STATUS Status; + VOID *AlignedImage; + CPU_MICROCODE_HEADER *TargetMicrocodeEntryPoint; + UINTN TargetCpuIndex; + UINTN TargetMicrcodeIndex; + + // + // MCU must be 16 bytes aligned + // + AlignedImage = AllocateCopyPool(ImageSize, Image); + if (AlignedImage == NULL) { + DEBUG((DEBUG_ERROR, "Fail to allocate aligned image\n")); + *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; + return EFI_OUT_OF_RESOURCES; + } + + *LastAttemptVersion = ((CPU_MICROCODE_HEADER *)Image)->UpdateRevision; + TargetCpuIndex = (UINTN)-1; + Status = VerifyMicrocode(MicrocodeFmpPrivate, AlignedImage, ImageSize, TRUE, LastAttemptStatus, AbortReason, &TargetCpuIndex); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "Fail to verify Microcode Region\n")); + FreePool(AlignedImage); + return Status; + } + DEBUG((DEBUG_INFO, "Pass VerifyMicrocode\n")); + + DEBUG((DEBUG_INFO, " TargetCpuIndex - 0x%x\n", TargetCpuIndex)); + ASSERT (TargetCpuIndex < MicrocodeFmpPrivate->ProcessorCount); + TargetMicrcodeIndex = MicrocodeFmpPrivate->ProcessorInfo[TargetCpuIndex].MicrocodeIndex; + DEBUG((DEBUG_INFO, " TargetMicrcodeIndex - 0x%x\n", TargetMicrcodeIndex)); + if (TargetMicrcodeIndex != (UINTN)-1) { + ASSERT (TargetMicrcodeIndex < MicrocodeFmpPrivate->DescriptorCount); + TargetMicrocodeEntryPoint = MicrocodeFmpPrivate->MicrocodeInfo[TargetMicrcodeIndex].MicrocodeEntryPoint; + } else { + TargetMicrocodeEntryPoint = NULL; + } + DEBUG((DEBUG_INFO, " TargetMicrocodeEntryPoint - 0x%x\n", TargetMicrocodeEntryPoint)); + + Status = UpdateMicrocodeFlashRegion( + MicrocodeFmpPrivate, + TargetMicrocodeEntryPoint, + AlignedImage, + ImageSize, + LastAttemptStatus + ); + + FreePool(AlignedImage); + + return Status; +} + + diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h new file mode 100644 index 0000000000..9dc306324e --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h @@ -0,0 +1,494 @@ +/** @file + Microcode update header file. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _MICROCODE_FMP_H_ +#define _MICROCODE_FMP_H_ + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define MICROCODE_FMP_PRIVATE_DATA_SIGNATURE SIGNATURE_32('M', 'C', 'U', 'F') + +// +// Microcode FMP private data structure. +// + +typedef struct { + UINT32 LastAttemptVersion; + UINT32 LastAttemptStatus; +} MICROCODE_FMP_LAST_ATTEMPT_VARIABLE; + +typedef struct { + CPU_MICROCODE_HEADER *MicrocodeEntryPoint; + UINTN TotalSize; + BOOLEAN InUse; +} MICROCODE_INFO; + +typedef struct { + UINTN CpuIndex; + UINT32 ProcessorSignature; + UINT8 PlatformId; + UINT32 MicrocodeRevision; + UINTN MicrocodeIndex; +} PROCESSOR_INFO; + +typedef struct { + UINT64 Address; + UINT32 Revision; +} MICROCODE_LOAD_BUFFER; + +struct _MICROCODE_FMP_PRIVATE_DATA { + UINT32 Signature; + EFI_FIRMWARE_MANAGEMENT_PROTOCOL Fmp; + EFI_HANDLE Handle; + VOID *MicrocodePatchAddress; + UINTN MicrocodePatchRegionSize; + UINT8 DescriptorCount; + EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; + MICROCODE_INFO *MicrocodeInfo; + UINT32 PackageVersion; + CHAR16 *PackageVersionName; + MICROCODE_FMP_LAST_ATTEMPT_VARIABLE LastAttempt; + EFI_MP_SERVICES_PROTOCOL *MpService; + UINTN BspIndex; + UINTN ProcessorCount; + PROCESSOR_INFO *ProcessorInfo; +}; + +typedef struct _MICROCODE_FMP_PRIVATE_DATA MICROCODE_FMP_PRIVATE_DATA; + +#define MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME L"MicrocodeLastAttempVar" + +/** + Returns a pointer to the MICROCODE_FMP_PRIVATE_DATA structure from the input a as Fmp. + + If the signatures matches, then a pointer to the data structure that contains + a specified field of that data structure is returned. + + @param a Pointer to the field specified by ServiceBinding within + a data structure of type MICROCODE_FMP_PRIVATE_DATA. + +**/ +#define MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(a) \ + CR ( \ + (a), \ + MICROCODE_FMP_PRIVATE_DATA, \ + Fmp, \ + MICROCODE_FMP_PRIVATE_DATA_SIGNATURE \ + ) + +/** + Get Microcode Region. + + @param[out] MicrocodePatchAddress The address of Microcode + @param[out] MicrocodePatchRegionSize The region size of Microcode + + @retval TRUE The Microcode region is returned. + @retval FALSE No Microcode region. +**/ +BOOLEAN +GetMicrocodeRegion ( + OUT VOID **MicrocodePatchAddress, + OUT UINTN *MicrocodePatchRegionSize + ); + +/** + Collect processor information. + The function prototype for invoking a function on an Application Processor. + + @param[in,out] Buffer The pointer to private data buffer. +**/ +VOID +EFIAPI +CollectProcessorInfo ( + IN OUT VOID *Buffer + ); + +/** + Get current Microcode information. + + The ProcessorInformation (BspIndex/ProcessorCount/ProcessorInfo) + in MicrocodeFmpPrivate must be initialized. + + The MicrocodeInformation (DescriptorCount/ImageDescriptor/MicrocodeInfo) + in MicrocodeFmpPrivate may not be avaiable in this function. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] DescriptorCount The count of Microcode ImageDescriptor allocated. + @param[out] ImageDescriptor Microcode ImageDescriptor + @param[out] MicrocodeInfo Microcode information + + @return Microcode count +**/ +UINTN +GetMicrocodeInfo ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN UINTN DescriptorCount, OPTIONAL + OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor, OPTIONAL + OUT MICROCODE_INFO *MicrocodeInfo OPTIONAL + ); + +/** + Verify Microcode. + + Caution: This function may receive untrusted input. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffer in bytes. + @param[in] TryLoad Try to load Microcode or not. + @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more + details for the aborted operation. The buffer is allocated by this function + with AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + @param[in, out] TargetCpuIndex On input, the index of target CPU which tries to match the Microcode. (UINTN)-1 means to try all. + On output, the index of target CPU which matches the Microcode. + + @retval EFI_SUCCESS The Microcode image passes verification. + @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. + @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. + @retval EFI_UNSUPPORTED The Microcode ProcessorSignature or ProcessorFlags is incorrect. + @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. +**/ +EFI_STATUS +VerifyMicrocode ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN VOID *Image, + IN UINTN ImageSize, + IN BOOLEAN TryLoad, + OUT UINT32 *LastAttemptStatus, + OUT CHAR16 **AbortReason, OPTIONAL + IN OUT UINTN *TargetCpuIndex OPTIONAL + ); + +/** + Write Microcode. + + @param[in] MicrocodeFmpPrivate The Microcode driver private data + @param[in] Image The Microcode image buffer. + @param[in] ImageSize The size of Microcode image buffer in bytes. + @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more + details for the aborted operation. The buffer is allocated by this function + with AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + + @retval EFI_SUCCESS The Microcode image is written. + @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. + @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. + @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. + @retval EFI_WRITE_PROTECTED The flash device is read only. +**/ +EFI_STATUS +MicrocodeWrite ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, + IN VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *LastAttemptVersion, + OUT UINT32 *LastAttemptStatus, + OUT CHAR16 **AbortReason + ); + +/** + Dump private information. + + @param[in] MicrocodeFmpPrivate private data structure. +**/ +VOID +DumpPrivateInfo ( + IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate + ); + +/** + Returns information about the current firmware image(s) of the device. + + This function allows a copy of the current firmware image to be created and saved. + The saved copy could later been used, for example, in firmware image recovery or rollback. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer. + On input, this is the size of the buffer allocated by the caller. + On output, it is the size of the buffer returned by the firmware + if the buffer was large enough, or the size of the buffer needed + to contain the image(s) information if the buffer was too small. + @param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s) + information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs. + @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number + associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] DescriptorCount A pointer to the location in which firmware returns the number of + descriptors or firmware images within this device. + @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes, + of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR. + @param[out] PackageVersion A version number that represents all the firmware images in the device. + The format is vendor specific and new version must have a greater value + than the old version. If PackageVersion is not supported, the value is + 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison + is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates + that package version update is in progress. + @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the + package version name. The buffer is allocated by this function with + AllocatePool(), and it is the caller's responsibility to free it with a call + to FreePool(). + + @retval EFI_SUCCESS The device was successfully updated with the new image. + @retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size + needed to hold the image(s) information is returned in ImageInfoSize. + @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL. + @retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image. + +**/ +EFI_STATUS +EFIAPI +FmpGetImageInfo ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN OUT UINTN *ImageInfoSize, + IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo, + OUT UINT32 *DescriptorVersion, + OUT UINT8 *DescriptorCount, + OUT UINTN *DescriptorSize, + OUT UINT32 *PackageVersion, + OUT CHAR16 **PackageVersionName + ); + +/** + Retrieves a copy of the current firmware image of the device. + + This function allows a copy of the current firmware image to be created and saved. + The saved copy could later been used, for example, in firmware image recovery or rollback. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. + The number is between 1 and DescriptorCount. + @param[in,out] Image Points to the buffer where the current image is copied to. + @param[in,out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes. + On return, points to the length of the image, in bytes. + + @retval EFI_SUCCESS The device was successfully updated with the new image. + @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the + image. The current buffer size needed to hold the image is returned + in ImageSize. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_NOT_FOUND The current image is not copied to the buffer. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpGetImage ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN UINT8 ImageIndex, + IN OUT VOID *Image, + IN OUT UINTN *ImageSize + ); + +/** + Updates the firmware image of the device. + + This function updates the hardware with the new firmware image. + This function returns EFI_UNSUPPORTED if the firmware image is not updatable. + If the firmware image is updatable, the function should perform the following minimal validations + before proceeding to do the firmware image update. + - Validate the image authentication if image has attribute + IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns + EFI_SECURITY_VIOLATION if the validation fails. + - Validate the image is a supported image for this device. The function returns EFI_ABORTED if + the image is unsupported. The function can optionally provide more detailed information on + why the image is not a supported image. + - Validate the data from VendorCode if not null. Image validation must be performed before + VendorCode data validation. VendorCode data is ignored or considered invalid if image + validation failed. The function returns EFI_ABORTED if the data is invalid. + + VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if + the caller did not specify the policy or use the default policy. As an example, vendor can implement + a policy to allow an option to force a firmware image update when the abort reason is due to the new + firmware image version is older than the current firmware image version or bad image checksum. + Sensitive operations such as those wiping the entire firmware image and render the device to be + non-functional should be encoded in the image itself rather than passed with the VendorCode. + AbortReason enables vendor to have the option to provide a more detailed description of the abort + reason to the caller. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. + The number is between 1 and DescriptorCount. + @param[in] Image Points to the new image. + @param[in] ImageSize Size of the new image in bytes. + @param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy. + Null indicates the caller did not specify the policy or use the default policy. + @param[in] Progress A function used by the driver to report the progress of the firmware update. + @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more + details for the aborted operation. The buffer is allocated by this function + with AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + + @retval EFI_SUCCESS The device was successfully updated with the new image. + @retval EFI_ABORTED The operation is aborted. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpSetImage ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN UINT8 ImageIndex, + IN CONST VOID *Image, + IN UINTN ImageSize, + IN CONST VOID *VendorCode, + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, + OUT CHAR16 **AbortReason + ); + +/** + Checks if the firmware image is valid for the device. + + This function allows firmware update application to validate the firmware image without + invoking the SetImage() first. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. + The number is between 1 and DescriptorCount. + @param[in] Image Points to the new image. + @param[in] ImageSize Size of the new image in bytes. + @param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides, + if available, additional information if the image is invalid. + + @retval EFI_SUCCESS The image was successfully checked. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpCheckImage ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN UINT8 ImageIndex, + IN CONST VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *ImageUpdatable + ); + +/** + Returns information about the firmware package. + + This function returns package information. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[out] PackageVersion A version number that represents all the firmware images in the device. + The format is vendor specific and new version must have a greater value + than the old version. If PackageVersion is not supported, the value is + 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version + comparison is to be performed using PackageVersionName. A value of + 0xFFFFFFFD indicates that package version update is in progress. + @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing + the package version name. The buffer is allocated by this function with + AllocatePool(), and it is the caller's responsibility to free it with a + call to FreePool(). + @param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of + package version name. A value of 0 indicates the device does not support + update of package version name. Length is the number of Unicode characters, + including the terminating null character. + @param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute + Definitions' for possible returned values of this parameter. A value of 1 + indicates the attribute is supported and the current setting value is + indicated in AttributesSetting. A value of 0 indicates the attribute is not + supported and the current setting value in AttributesSetting is meaningless. + @param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned + values of this parameter + + @retval EFI_SUCCESS The package information was successfully returned. + @retval EFI_UNSUPPORTED The operation is not supported. + +**/ +EFI_STATUS +EFIAPI +FmpGetPackageInfo ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + OUT UINT32 *PackageVersion, + OUT CHAR16 **PackageVersionName, + OUT UINT32 *PackageVersionNameMaxLen, + OUT UINT64 *AttributesSupported, + OUT UINT64 *AttributesSetting + ); + +/** + Updates information about the firmware package. + + This function updates package information. + This function returns EFI_UNSUPPORTED if the package information is not updatable. + VendorCode enables vendor to implement vendor-specific package information update policy. + Null if the caller did not specify this policy or use the default policy. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. + @param[in] Image Points to the authentication image. + Null if authentication is not required. + @param[in] ImageSize Size of the authentication image in bytes. + 0 if authentication is not required. + @param[in] VendorCode This enables vendor to implement vendor-specific firmware + image update policy. + Null indicates the caller did not specify this policy or use + the default policy. + @param[in] PackageVersion The new package version. + @param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing + the package version name. + The string length is equal to or less than the value returned in + PackageVersionNameMaxLen. + + @retval EFI_SUCCESS The device was successfully updated with the new package + information. + @retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value + returned in PackageVersionNameMaxLen. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +FmpSetPackageInfo ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN CONST VOID *Image, + IN UINTN ImageSize, + IN CONST VOID *VendorCode, + IN UINT32 PackageVersion, + IN CONST CHAR16 *PackageVersionName + ); + +#endif + diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf new file mode 100644 index 0000000000..55797cf132 --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf @@ -0,0 +1,71 @@ +## @file +# Microcode FMP update driver. +# +# Produce FMP instance to update Microcode. +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MicrocodeUpdateDxe + MODULE_UNI_FILE = MicrocodeUpdateDxe.uni + FILE_GUID = 0565365C-2FE1-4F88-B3BE-624C04623A20 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MicrocodeFmpMain + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = X64 +# + +[Sources] + MicrocodeUpdate.h + MicrocodeFmp.c + MicrocodeUpdate.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + UefiLib + BaseMemoryLib + DebugLib + PcdLib + MemoryAllocationLib + UefiBootServicesTableLib + HobLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + MicrocodeFlashAccessLib + +[Guids] + gMicrocodeFmpImageTypeIdGuid ## CONSUMES ## GUID + +[Protocols] + gEfiFirmwareManagementProtocolGuid ## PRODUCES + gEfiMpServiceProtocolGuid ## CONSUMES + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES + +[Depex] + gEfiVariableArchProtocolGuid AND + gEfiMpServiceProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + MicrocodeUpdateDxeExtra.uni + diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni new file mode 100644 index 0000000000..1b0d4941dc --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni @@ -0,0 +1,21 @@ +// /** @file +// Microcode FMP update driver. +// +// Produce FMP instance to update Microcode. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Microcode FMP update driver." + +#string STR_MODULE_DESCRIPTION #language en-US "Produce FMP instance to update Microcode." diff --git a/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni new file mode 100644 index 0000000000..b667f12f5c --- /dev/null +++ b/IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni @@ -0,0 +1,20 @@ +// /** @file +// MicrocodeUpdateDxe Localized Strings and Content +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"MicrocodeUpdate DXE Driver" + + diff --git a/IntelSiliconPkg/Include/Guid/MicrocodeFmp.h b/IntelSiliconPkg/Include/Guid/MicrocodeFmp.h new file mode 100644 index 0000000000..88a19538c8 --- /dev/null +++ b/IntelSiliconPkg/Include/Guid/MicrocodeFmp.h @@ -0,0 +1,21 @@ +/** @file + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __MICROCODE_FMP_GUID_H__ +#define __MICROCODE_FMP_GUID_H__ + +#define MICROCODE_FMP_IMAGE_TYPE_ID_GUID { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } } + +extern EFI_GUID gMicrocodeFmpImageTypeIdGuid; + +#endif diff --git a/IntelSiliconPkg/Include/Library/MicrocodeFlashAccessLib.h b/IntelSiliconPkg/Include/Library/MicrocodeFlashAccessLib.h new file mode 100644 index 0000000000..0dfc3ef376 --- /dev/null +++ b/IntelSiliconPkg/Include/Library/MicrocodeFlashAccessLib.h @@ -0,0 +1,39 @@ +/** @file + Microcode flash device access library. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + + +#ifndef __MICROCODE_FLASH_ACCESS_LIB_H__ +#define __MICROCODE_FLASH_ACCESS_LIB_H__ + +/** + Perform microcode write opreation. + + @param[in] FlashAddress The address of flash device to be accessed. + @param[in] Buffer The pointer to the data buffer. + @param[in] Length The length of data buffer in bytes. + + @retval EFI_SUCCESS The operation returns successfully. + @retval EFI_WRITE_PROTECTED The flash device is read only. + @retval EFI_UNSUPPORTED The flash device access is unsupported. + @retval EFI_INVALID_PARAMETER The input parameter is not valid. +**/ +EFI_STATUS +EFIAPI +MicrocodeFlashWrite ( + IN EFI_PHYSICAL_ADDRESS FlashAddress, + IN VOID *Buffer, + IN UINTN Length + ); + +#endif diff --git a/IntelSiliconPkg/IntelSiliconPkg.dec b/IntelSiliconPkg/IntelSiliconPkg.dec index b88630d138..a15d3dee39 100644 --- a/IntelSiliconPkg/IntelSiliconPkg.dec +++ b/IntelSiliconPkg/IntelSiliconPkg.dec @@ -3,7 +3,7 @@ # # This package provides common open source Intel silicon modules. # -# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
# This program and the accompanying materials are licensed and made available under # the terms and conditions of the BSD License that accompanies this distribution. # The full text of the license may be found at @@ -23,6 +23,11 @@ [Includes] Include +[LibraryClasses.IA32, LibraryClasses.X64] + ## @libraryclass Provides services to access Microcode region on flash device. + # + MicrocodeFlashAccessLib|Include/Library/MicrocodeFlashAccessLib.h + [Guids] ## GUID for Package token space # {A9F8D54E-1107-4F0A-ADD0-4587E7A4A735} @@ -33,6 +38,9 @@ # Generic DXE Library / Driver can locate HOB(s) and add SMBIOS records into SMBIOS table gIntelSmbiosDataHobGuid = { 0x798e722e, 0x15b2, 0x4e13, { 0x8a, 0xe9, 0x6b, 0xa3, 0x0f, 0xf7, 0xf1, 0x67 }} + ## Include/Guid/MicrocodeFmp.h + gMicrocodeFmpImageTypeIdGuid = { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } } + [Ppis] gEdkiiVTdInfoPpiGuid = { 0x8a59fcb3, 0xf191, 0x400c, { 0x97, 0x67, 0x67, 0xaf, 0x2b, 0x25, 0x68, 0x4a } } diff --git a/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c b/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c deleted file mode 100644 index 7a5ec152d7..0000000000 --- a/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c +++ /dev/null @@ -1,42 +0,0 @@ -/** @file - Microcode flash device access library NULL instance. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include - -/** - Perform microcode write opreation. - - @param[in] FlashAddress The address of flash device to be accessed. - @param[in] Buffer The pointer to the data buffer. - @param[in] Length The length of data buffer in bytes. - - @retval EFI_SUCCESS The operation returns successfully. - @retval EFI_WRITE_PROTECTED The flash device is read only. - @retval EFI_UNSUPPORTED The flash device access is unsupported. - @retval EFI_INVALID_PARAMETER The input parameter is not valid. -**/ -EFI_STATUS -EFIAPI -MicrocodeFlashWrite ( - IN EFI_PHYSICAL_ADDRESS FlashAddress, - IN VOID *Buffer, - IN UINTN Length - ) -{ - CopyMem((VOID *)(UINTN)(FlashAddress), Buffer, Length); - return EFI_SUCCESS; -} diff --git a/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf b/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf deleted file mode 100644 index a4a47e0737..0000000000 --- a/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf +++ /dev/null @@ -1,40 +0,0 @@ -## @file -# Microcode flash device access library. -# -# Microcode flash device access library NULL instance. -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = MicrocodeFlashAccessLibNull - MODULE_UNI_FILE = MicrocodeFlashAccessLibNull.uni - FILE_GUID = 6F871ADD-9D86-4676-8BAD-68E2E451FC5B - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = MicrocodeFlashAccessLib - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - MicrocodeFlashAccessLibNull.c - -[Packages] - MdePkg/MdePkg.dec - UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseMemoryLib diff --git a/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni b/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni deleted file mode 100644 index cc4195c412..0000000000 --- a/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// Microcode flash device access library. -// -// Microcode flash device access library NULL instance. -// -// Copyright (c) 2016, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Microcode flash device access library." - -#string STR_MODULE_DESCRIPTION #language en-US "Microcode flash device access library NULL instance." - diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc deleted file mode 100644 index 1b22c55117..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc +++ /dev/null @@ -1,33 +0,0 @@ -## @file -# MicrocodeCapsulePdb -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] -# -# Uncomment the following line and update with your platform pkg name -# -# PLATFORM_NAME = - PLATFORM_GUID = 6875FD33-602E-4EF9-9DF2-8BA7D8B7A7AF - PLATFORM_VERSION = 0.1 -# -# Uncomment the following line and update with your platform pkg name -# -# FLASH_DEFINITION = /MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf -# -# Uncomment the following line and update with your platform pkg name -# -# OUTPUT_DIRECTORY = Build/ - SUPPORTED_ARCHITECTURES = IA32|X64 - BUILD_TARGETS = DEBUG|RELEASE - SKUID_IDENTIFIER = DEFAULT diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf deleted file mode 100644 index f171604d4f..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf +++ /dev/null @@ -1,32 +0,0 @@ -## @file -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[FmpPayload.FmpPayloadMicrocode1] -IMAGE_HEADER_INIT_VERSION = 0x02 -IMAGE_TYPE_ID = 96d4fdcd-1502-424d-9d4c-9b12d2dcae5c # Microcode GUID (do not change it) -IMAGE_INDEX = 0x1 -HARDWARE_INSTANCE = 0x0 - -# -# Uncomment the following line and update with path to Microcode PDB file -# -#FILE DATA = $(WORKSPACE)//Microcode/Microcode.pdb - -[Capsule.MicrocodeCapsule] -CAPSULE_GUID = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # FMP special Guid (do not change it) -CAPSULE_FLAGS = PersistAcrossReset,InitiateReset -CAPSULE_HEADER_SIZE = 0x20 -CAPSULE_HEADER_INIT_VERSION = 0x1 - -FMP_PAYLOAD = FmpPayloadMicrocode1 diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md deleted file mode 100644 index 9f81373fda..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md +++ /dev/null @@ -1,20 +0,0 @@ -# How to generate Microcode FMP from Microcode PDB file - -1) Copy directory `UefiCpuPkg/Feature/Capsule/MicrocodeUpdatePdb` to `/MicrocodeUpdatePdb`. - -2) Uncomment and update `FILE DATA` statement in `/MicrocodeUpdatePdb/MicrocodeCapsulePdb.fdf` with path to a Microcode PDB file. The PDB file can placed in `/MicrocodeUpdatePdb` or any other path. - -`FILE DATA = ` - -Uncomment and update `PLATFORM_NAME`, `FLASH_DEFINITION`, `OUTPUT_DIRECTORY` section in `/MicrocodeUpdatePdb/MicrocodeCapsulePdb.dsc` with . - - PLATFORM_NAME = - FLASH_DEFINITION = /MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf - OUTPUT_DIRECTORY = Build/ - -3) Use EDK II build tools to generate the Microcode FMP Capsule - -`build -p /MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc` - -4) The Microcode FMP Capsule is generated at `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/MicrocodeCapsule.Cap` - diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf deleted file mode 100644 index 81af841f2c..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf +++ /dev/null @@ -1,27 +0,0 @@ -## @file -# Microcode text file to binary -# -# Convert text format microcode to binary format. -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] -BASE_NAME = Microcode -FILE_GUID = ABC36AAC-2031-4422-896E-0A3B899AD0B4 -COMPONENT_TYPE = Microcode -FFS_EXT = .ffs - -[Sources] -# -# Uncomment the following line and update with name of Microcode TXT file -# -#Microcode.txt diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc deleted file mode 100644 index a66f89b4e2..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc +++ /dev/null @@ -1,39 +0,0 @@ -## @file -# MicrocodeCapsuleTxt -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] -# -# Uncomment the following line and update with your platform pkg name -# -# PLATFORM_NAME = - PLATFORM_GUID = 6875FD33-602E-4EF9-9DF2-8BA7D8B7A7AF - PLATFORM_VERSION = 0.1 -# -# Uncomment the following line and update with your platform pkg name -# -# FLASH_DEFINITION = /MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf -# -# Uncomment the following line and update with your platform pkg name -# -# OUTPUT_DIRECTORY = Build/ - SUPPORTED_ARCHITECTURES = IA32|X64 - BUILD_TARGETS = DEBUG|RELEASE - SKUID_IDENTIFIER = DEFAULT - -[Components] -# -# Uncomment the following line and update with path to Microcode INF file -# -# /MicrocodeCapsuleTxt/Microcode/Microcode.inf diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf deleted file mode 100644 index 113693b1df..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf +++ /dev/null @@ -1,32 +0,0 @@ -## @file -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[FmpPayload.FmpPayloadMicrocode1] -IMAGE_HEADER_INIT_VERSION = 0x02 -IMAGE_TYPE_ID = 96d4fdcd-1502-424d-9d4c-9b12d2dcae5c # Microcode GUID (do not change it) -IMAGE_INDEX = 0x1 -HARDWARE_INSTANCE = 0x0 - -# -# Uncomment the following line and update with path to Microcode MCB file -# -#FILE DATA = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/IA32/PlatformPkg/MicrocodeCapsuleTxt/Microcode/Microcode/OUTPUT/Microcode.mcb - -[Capsule.MicrocodeCapsule] -CAPSULE_GUID = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # FMP special Guid (do not change it) -CAPSULE_FLAGS = PersistAcrossReset,InitiateReset -CAPSULE_HEADER_SIZE = 0x20 -CAPSULE_HEADER_INIT_VERSION = 0x1 - -FMP_PAYLOAD = FmpPayloadMicrocode1 diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md deleted file mode 100644 index f7d7040fcb..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md +++ /dev/null @@ -1,33 +0,0 @@ -# How to generate Microcode FMP from Microcode TXT file - -1) Copy directory `UefiCpuPkg/Feature/Capsule/MicrocodeUpdateTxt` to `/MicrocodeUpdateTxt` - -2) Copy microcode TXT file to`/MicrocodeUpdateTxt/Microcode` - -3) Uncomment and update statement in `[Sources]` section of `/MicrocodeUpdateTxt/Microcode/Microcode.inf` with name of Microcode TXT file copied in previous step. - - [Sources] - - -Uncomment and update `FILE DATA` statement in `/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.fdf` with path to a Microcode MCB file. The MCB file is placed in `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/IA32//MicrocodeUpdateTxt/Microcode/Microcode/OUTPUT/`. - -`FILE DATA = ` - -Uncomment and update `PLATFORM_NAME`, `FLASH_DEFINITION`, `OUTPUT_DIRECTORY` section in `/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.dsc` with . - - PLATFORM_NAME = - FLASH_DEFINITION = /MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf - OUTPUT_DIRECTORY = Build/ - -Uncomment and update statement in `Components` section of `/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.dsc` with path to a Microcode INF file. - - [Components] - - -4) Use EDK II build tools to generate the Microcode FMP Capsule - -`build -p /MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc` - -5) The generated Microcode FMP Capsule is found at `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/MicrocodeCapsule.Cap` - - diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c deleted file mode 100644 index ebde93a91e..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c +++ /dev/null @@ -1,748 +0,0 @@ -/** @file - Produce FMP instance for Microcode. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "MicrocodeUpdate.h" - -// -// MicrocodeFmp driver private data -// -MICROCODE_FMP_PRIVATE_DATA *mMicrocodeFmpPrivate = NULL; - -EFI_FIRMWARE_MANAGEMENT_PROTOCOL mFirmwareManagementProtocol = { - FmpGetImageInfo, - FmpGetImage, - FmpSetImage, - FmpCheckImage, - FmpGetPackageInfo, - FmpSetPackageInfo -}; - -/** - Initialize Microcode Descriptor. - - @param[in] MicrocodeFmpPrivate private data structure to be initialized. - - @return EFI_SUCCESS Microcode Descriptor is initialized. -**/ -EFI_STATUS -InitializeMicrocodeDescriptor ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ); - -/** - Returns information about the current firmware image(s) of the device. - - This function allows a copy of the current firmware image to be created and saved. - The saved copy could later been used, for example, in firmware image recovery or rollback. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer. - On input, this is the size of the buffer allocated by the caller. - On output, it is the size of the buffer returned by the firmware - if the buffer was large enough, or the size of the buffer needed - to contain the image(s) information if the buffer was too small. - @param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s) - information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs. - @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number - associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] DescriptorCount A pointer to the location in which firmware returns the number of - descriptors or firmware images within this device. - @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes, - of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] PackageVersion A version number that represents all the firmware images in the device. - The format is vendor specific and new version must have a greater value - than the old version. If PackageVersion is not supported, the value is - 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison - is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates - that package version update is in progress. - @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the - package version name. The buffer is allocated by this function with - AllocatePool(), and it is the caller's responsibility to free it with a call - to FreePool(). - - @retval EFI_SUCCESS The device was successfully updated with the new image. - @retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size - needed to hold the image(s) information is returned in ImageInfoSize. - @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL. - @retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image. - -**/ -EFI_STATUS -EFIAPI -FmpGetImageInfo ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN OUT UINTN *ImageInfoSize, - IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo, - OUT UINT32 *DescriptorVersion, - OUT UINT8 *DescriptorCount, - OUT UINTN *DescriptorSize, - OUT UINT32 *PackageVersion, - OUT CHAR16 **PackageVersionName - ) -{ - MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate; - UINTN Index; - - MicrocodeFmpPrivate = MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(This); - - if(ImageInfoSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (*ImageInfoSize < sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount) { - *ImageInfoSize = sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount; - return EFI_BUFFER_TOO_SMALL; - } - - if (ImageInfo == NULL || - DescriptorVersion == NULL || - DescriptorCount == NULL || - DescriptorSize == NULL || - PackageVersion == NULL || - PackageVersionName == NULL) { - return EFI_INVALID_PARAMETER; - } - - *ImageInfoSize = sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount; - *DescriptorSize = sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR); - *DescriptorCount = MicrocodeFmpPrivate->DescriptorCount; - *DescriptorVersion = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; - - // - // supports 1 ImageInfo descriptor - // - CopyMem(&ImageInfo[0], MicrocodeFmpPrivate->ImageDescriptor, sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR) * MicrocodeFmpPrivate->DescriptorCount); - for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { - if ((ImageInfo[Index].AttributesSetting & IMAGE_ATTRIBUTE_IN_USE) != 0) { - ImageInfo[Index].LastAttemptVersion = MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion; - ImageInfo[Index].LastAttemptStatus = MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus; - } - } - - // - // package version - // - *PackageVersion = MicrocodeFmpPrivate->PackageVersion; - if (MicrocodeFmpPrivate->PackageVersionName != NULL) { - *PackageVersionName = AllocateCopyPool(StrSize(MicrocodeFmpPrivate->PackageVersionName), MicrocodeFmpPrivate->PackageVersionName); - } - - return EFI_SUCCESS; -} - -/** - Retrieves a copy of the current firmware image of the device. - - This function allows a copy of the current firmware image to be created and saved. - The saved copy could later been used, for example, in firmware image recovery or rollback. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. - The number is between 1 and DescriptorCount. - @param[in,out] Image Points to the buffer where the current image is copied to. - @param[in,out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes. - On return, points to the length of the image, in bytes. - - @retval EFI_SUCCESS The device was successfully updated with the new image. - @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the - image. The current buffer size needed to hold the image is returned - in ImageSize. - @retval EFI_INVALID_PARAMETER The Image was NULL. - @retval EFI_NOT_FOUND The current image is not copied to the buffer. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpGetImage ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN UINT8 ImageIndex, - IN OUT VOID *Image, - IN OUT UINTN *ImageSize - ) -{ - MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate; - MICROCODE_INFO *MicrocodeInfo; - - if (Image == NULL || ImageSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - MicrocodeFmpPrivate = MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(This); - - if (ImageIndex == 0 || ImageIndex > MicrocodeFmpPrivate->DescriptorCount || ImageSize == NULL || Image == NULL) { - return EFI_INVALID_PARAMETER; - } - - MicrocodeInfo = &MicrocodeFmpPrivate->MicrocodeInfo[ImageIndex - 1]; - - if (*ImageSize < MicrocodeInfo->TotalSize) { - *ImageSize = MicrocodeInfo->TotalSize; - return EFI_BUFFER_TOO_SMALL; - } - - *ImageSize = MicrocodeInfo->TotalSize; - CopyMem (Image, MicrocodeInfo->MicrocodeEntryPoint, MicrocodeInfo->TotalSize); - return EFI_SUCCESS; -} - -/** - Updates the firmware image of the device. - - This function updates the hardware with the new firmware image. - This function returns EFI_UNSUPPORTED if the firmware image is not updatable. - If the firmware image is updatable, the function should perform the following minimal validations - before proceeding to do the firmware image update. - - Validate the image authentication if image has attribute - IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns - EFI_SECURITY_VIOLATION if the validation fails. - - Validate the image is a supported image for this device. The function returns EFI_ABORTED if - the image is unsupported. The function can optionally provide more detailed information on - why the image is not a supported image. - - Validate the data from VendorCode if not null. Image validation must be performed before - VendorCode data validation. VendorCode data is ignored or considered invalid if image - validation failed. The function returns EFI_ABORTED if the data is invalid. - - VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if - the caller did not specify the policy or use the default policy. As an example, vendor can implement - a policy to allow an option to force a firmware image update when the abort reason is due to the new - firmware image version is older than the current firmware image version or bad image checksum. - Sensitive operations such as those wiping the entire firmware image and render the device to be - non-functional should be encoded in the image itself rather than passed with the VendorCode. - AbortReason enables vendor to have the option to provide a more detailed description of the abort - reason to the caller. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. - The number is between 1 and DescriptorCount. - @param[in] Image Points to the new image. - @param[in] ImageSize Size of the new image in bytes. - @param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy. - Null indicates the caller did not specify the policy or use the default policy. - @param[in] Progress A function used by the driver to report the progress of the firmware update. - @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more - details for the aborted operation. The buffer is allocated by this function - with AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - - @retval EFI_SUCCESS The device was successfully updated with the new image. - @retval EFI_ABORTED The operation is aborted. - @retval EFI_INVALID_PARAMETER The Image was NULL. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpSetImage ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN UINT8 ImageIndex, - IN CONST VOID *Image, - IN UINTN ImageSize, - IN CONST VOID *VendorCode, - IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, - OUT CHAR16 **AbortReason - ) -{ - EFI_STATUS Status; - EFI_STATUS VarStatus; - MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate; - - if (Image == NULL || AbortReason == NULL) { - return EFI_INVALID_PARAMETER; - } - - MicrocodeFmpPrivate = MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(This); - *AbortReason = NULL; - - if (ImageIndex == 0 || ImageIndex > MicrocodeFmpPrivate->DescriptorCount || Image == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = MicrocodeWrite(MicrocodeFmpPrivate, (VOID *)Image, ImageSize, &MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, &MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus, AbortReason); - DEBUG((DEBUG_INFO, "SetImage - LastAttemp Version - 0x%x, State - 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); - VarStatus = gRT->SetVariable( - MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME, - &gEfiCallerIdGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof(MicrocodeFmpPrivate->LastAttempt), - &MicrocodeFmpPrivate->LastAttempt - ); - DEBUG((DEBUG_INFO, "SetLastAttemp - %r\n", VarStatus)); - - if (!EFI_ERROR(Status)) { - InitializeMicrocodeDescriptor(MicrocodeFmpPrivate); - DumpPrivateInfo (MicrocodeFmpPrivate); - } - - return Status; -} - -/** - Checks if the firmware image is valid for the device. - - This function allows firmware update application to validate the firmware image without - invoking the SetImage() first. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. - The number is between 1 and DescriptorCount. - @param[in] Image Points to the new image. - @param[in] ImageSize Size of the new image in bytes. - @param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides, - if available, additional information if the image is invalid. - - @retval EFI_SUCCESS The image was successfully checked. - @retval EFI_INVALID_PARAMETER The Image was NULL. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpCheckImage ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN UINT8 ImageIndex, - IN CONST VOID *Image, - IN UINTN ImageSize, - OUT UINT32 *ImageUpdatable - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Returns information about the firmware package. - - This function returns package information. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[out] PackageVersion A version number that represents all the firmware images in the device. - The format is vendor specific and new version must have a greater value - than the old version. If PackageVersion is not supported, the value is - 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version - comparison is to be performed using PackageVersionName. A value of - 0xFFFFFFFD indicates that package version update is in progress. - @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing - the package version name. The buffer is allocated by this function with - AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - @param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of - package version name. A value of 0 indicates the device does not support - update of package version name. Length is the number of Unicode characters, - including the terminating null character. - @param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute - Definitions' for possible returned values of this parameter. A value of 1 - indicates the attribute is supported and the current setting value is - indicated in AttributesSetting. A value of 0 indicates the attribute is not - supported and the current setting value in AttributesSetting is meaningless. - @param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned - values of this parameter - - @retval EFI_SUCCESS The package information was successfully returned. - @retval EFI_UNSUPPORTED The operation is not supported. - -**/ -EFI_STATUS -EFIAPI -FmpGetPackageInfo ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - OUT UINT32 *PackageVersion, - OUT CHAR16 **PackageVersionName, - OUT UINT32 *PackageVersionNameMaxLen, - OUT UINT64 *AttributesSupported, - OUT UINT64 *AttributesSetting - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Updates information about the firmware package. - - This function updates package information. - This function returns EFI_UNSUPPORTED if the package information is not updatable. - VendorCode enables vendor to implement vendor-specific package information update policy. - Null if the caller did not specify this policy or use the default policy. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] Image Points to the authentication image. - Null if authentication is not required. - @param[in] ImageSize Size of the authentication image in bytes. - 0 if authentication is not required. - @param[in] VendorCode This enables vendor to implement vendor-specific firmware - image update policy. - Null indicates the caller did not specify this policy or use - the default policy. - @param[in] PackageVersion The new package version. - @param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing - the package version name. - The string length is equal to or less than the value returned in - PackageVersionNameMaxLen. - - @retval EFI_SUCCESS The device was successfully updated with the new package - information. - @retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value - returned in PackageVersionNameMaxLen. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpSetPackageInfo ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN CONST VOID *Image, - IN UINTN ImageSize, - IN CONST VOID *VendorCode, - IN UINT32 PackageVersion, - IN CONST CHAR16 *PackageVersionName - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Initialize Processor Microcode Index. - - @param[in] MicrocodeFmpPrivate private data structure to be initialized. -**/ -VOID -InitializedProcessorMicrocodeIndex ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ) -{ - UINTN CpuIndex; - UINTN MicrocodeIndex; - UINTN TargetCpuIndex; - UINT32 AttemptStatus; - EFI_STATUS Status; - - for (CpuIndex = 0; CpuIndex < MicrocodeFmpPrivate->ProcessorCount; CpuIndex++) { - if (MicrocodeFmpPrivate->ProcessorInfo[CpuIndex].MicrocodeIndex != (UINTN)-1) { - continue; - } - for (MicrocodeIndex = 0; MicrocodeIndex < MicrocodeFmpPrivate->DescriptorCount; MicrocodeIndex++) { - if (!MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].InUse) { - continue; - } - TargetCpuIndex = CpuIndex; - Status = VerifyMicrocode( - MicrocodeFmpPrivate, - MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].MicrocodeEntryPoint, - MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeIndex].TotalSize, - FALSE, - &AttemptStatus, - NULL, - &TargetCpuIndex - ); - if (!EFI_ERROR(Status)) { - MicrocodeFmpPrivate->ProcessorInfo[CpuIndex].MicrocodeIndex = MicrocodeIndex; - } - } - } -} - -/** - Initialize Microcode Descriptor. - - @param[in] MicrocodeFmpPrivate private data structure to be initialized. - - @return EFI_SUCCESS Microcode Descriptor is initialized. -**/ -EFI_STATUS -InitializeMicrocodeDescriptor ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ) -{ - UINT8 CurrentMicrocodeCount; - - CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate, 0, NULL, NULL); - - if (CurrentMicrocodeCount > MicrocodeFmpPrivate->DescriptorCount) { - if (MicrocodeFmpPrivate->ImageDescriptor != NULL) { - FreePool(MicrocodeFmpPrivate->ImageDescriptor); - MicrocodeFmpPrivate->ImageDescriptor = NULL; - } - if (MicrocodeFmpPrivate->MicrocodeInfo != NULL) { - FreePool(MicrocodeFmpPrivate->MicrocodeInfo); - MicrocodeFmpPrivate->MicrocodeInfo = NULL; - } - } else { - ZeroMem(MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->DescriptorCount * sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR)); - ZeroMem(MicrocodeFmpPrivate->MicrocodeInfo, MicrocodeFmpPrivate->DescriptorCount * sizeof(MICROCODE_INFO)); - } - - MicrocodeFmpPrivate->DescriptorCount = CurrentMicrocodeCount; - - if (MicrocodeFmpPrivate->ImageDescriptor == NULL) { - MicrocodeFmpPrivate->ImageDescriptor = AllocateZeroPool(MicrocodeFmpPrivate->DescriptorCount * sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR)); - if (MicrocodeFmpPrivate->ImageDescriptor == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - if (MicrocodeFmpPrivate->MicrocodeInfo == NULL) { - MicrocodeFmpPrivate->MicrocodeInfo = AllocateZeroPool(MicrocodeFmpPrivate->DescriptorCount * sizeof(MICROCODE_INFO)); - if (MicrocodeFmpPrivate->MicrocodeInfo == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo (MicrocodeFmpPrivate, MicrocodeFmpPrivate->DescriptorCount, MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->MicrocodeInfo); - ASSERT(CurrentMicrocodeCount == MicrocodeFmpPrivate->DescriptorCount); - - InitializedProcessorMicrocodeIndex (MicrocodeFmpPrivate); - - return EFI_SUCCESS; -} - -/** - Initialize MicrocodeFmpDriver multiprocessor information. - - @param[in] MicrocodeFmpPrivate private data structure to be initialized. - - @return EFI_SUCCESS private data is initialized. -**/ -EFI_STATUS -InitializeProcessorInfo ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ) -{ - EFI_STATUS Status; - EFI_MP_SERVICES_PROTOCOL *MpService; - UINTN NumberOfProcessors; - UINTN NumberOfEnabledProcessors; - UINTN Index; - UINTN BspIndex; - - Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpService); - ASSERT_EFI_ERROR(Status); - - MicrocodeFmpPrivate->MpService = MpService; - MicrocodeFmpPrivate->ProcessorCount = 0; - MicrocodeFmpPrivate->ProcessorInfo = NULL; - - Status = MpService->GetNumberOfProcessors (MpService, &NumberOfProcessors, &NumberOfEnabledProcessors); - ASSERT_EFI_ERROR(Status); - MicrocodeFmpPrivate->ProcessorCount = NumberOfProcessors; - - Status = MpService->WhoAmI (MpService, &BspIndex); - ASSERT_EFI_ERROR(Status); - MicrocodeFmpPrivate->BspIndex = BspIndex; - - MicrocodeFmpPrivate->ProcessorInfo = AllocateZeroPool (sizeof(PROCESSOR_INFO) * MicrocodeFmpPrivate->ProcessorCount); - if (MicrocodeFmpPrivate->ProcessorInfo == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - for (Index = 0; Index < NumberOfProcessors; Index++) { - MicrocodeFmpPrivate->ProcessorInfo[Index].CpuIndex = Index; - MicrocodeFmpPrivate->ProcessorInfo[Index].MicrocodeIndex = (UINTN)-1; - if (Index == BspIndex) { - CollectProcessorInfo (&MicrocodeFmpPrivate->ProcessorInfo[Index]); - } else { - Status = MpService->StartupThisAP ( - MpService, - CollectProcessorInfo, - Index, - NULL, - 0, - &MicrocodeFmpPrivate->ProcessorInfo[Index], - NULL - ); - ASSERT_EFI_ERROR(Status); - } - } - - return EFI_SUCCESS; -} - -/** - Dump private information. - - @param[in] MicrocodeFmpPrivate private data structure. -**/ -VOID -DumpPrivateInfo ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ) -{ - UINTN Index; - PROCESSOR_INFO *ProcessorInfo; - MICROCODE_INFO *MicrocodeInfo; - EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; - - DEBUG ((DEBUG_INFO, "ProcessorInfo:\n")); - DEBUG ((DEBUG_INFO, " ProcessorCount - 0x%x\n", MicrocodeFmpPrivate->ProcessorCount)); - DEBUG ((DEBUG_INFO, " BspIndex - 0x%x\n", MicrocodeFmpPrivate->BspIndex)); - - ProcessorInfo = MicrocodeFmpPrivate->ProcessorInfo; - for (Index = 0; Index < MicrocodeFmpPrivate->ProcessorCount; Index++) { - DEBUG (( - DEBUG_INFO, - " ProcessorInfo[0x%x] - 0x%08x, 0x%02x, 0x%08x, (0x%x)\n", - ProcessorInfo[Index].CpuIndex, - ProcessorInfo[Index].ProcessorSignature, - ProcessorInfo[Index].PlatformId, - ProcessorInfo[Index].MicrocodeRevision, - ProcessorInfo[Index].MicrocodeIndex - )); - } - - DEBUG ((DEBUG_INFO, "MicrocodeInfo:\n")); - MicrocodeInfo = MicrocodeFmpPrivate->MicrocodeInfo; - DEBUG ((DEBUG_INFO, " MicrocodeRegion - 0x%x - 0x%x\n", MicrocodeFmpPrivate->MicrocodePatchAddress, MicrocodeFmpPrivate->MicrocodePatchRegionSize)); - DEBUG ((DEBUG_INFO, " MicrocodeCount - 0x%x\n", MicrocodeFmpPrivate->DescriptorCount)); - for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { - DEBUG (( - DEBUG_INFO, - " MicrocodeInfo[0x%x] - 0x%08x, 0x%08x, (0x%x)\n", - Index, - MicrocodeInfo[Index].MicrocodeEntryPoint, - MicrocodeInfo[Index].TotalSize, - MicrocodeInfo[Index].InUse - )); - } - - ImageDescriptor = MicrocodeFmpPrivate->ImageDescriptor; - DEBUG ((DEBUG_VERBOSE, "ImageDescriptor:\n")); - for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { - DEBUG((DEBUG_VERBOSE, " ImageDescriptor (%d)\n", Index)); - DEBUG((DEBUG_VERBOSE, " ImageIndex - 0x%x\n", ImageDescriptor[Index].ImageIndex)); - DEBUG((DEBUG_VERBOSE, " ImageTypeId - %g\n", &ImageDescriptor[Index].ImageTypeId)); - DEBUG((DEBUG_VERBOSE, " ImageId - 0x%lx\n", ImageDescriptor[Index].ImageId)); - DEBUG((DEBUG_VERBOSE, " ImageIdName - %s\n", ImageDescriptor[Index].ImageIdName)); - DEBUG((DEBUG_VERBOSE, " Version - 0x%x\n", ImageDescriptor[Index].Version)); - DEBUG((DEBUG_VERBOSE, " VersionName - %s\n", ImageDescriptor[Index].VersionName)); - DEBUG((DEBUG_VERBOSE, " Size - 0x%x\n", ImageDescriptor[Index].Size)); - DEBUG((DEBUG_VERBOSE, " AttributesSupported - 0x%lx\n", ImageDescriptor[Index].AttributesSupported)); - DEBUG((DEBUG_VERBOSE, " AttributesSetting - 0x%lx\n", ImageDescriptor[Index].AttributesSetting)); - DEBUG((DEBUG_VERBOSE, " Compatibilities - 0x%lx\n", ImageDescriptor[Index].Compatibilities)); - DEBUG((DEBUG_VERBOSE, " LowestSupportedImageVersion - 0x%x\n", ImageDescriptor[Index].LowestSupportedImageVersion)); - DEBUG((DEBUG_VERBOSE, " LastAttemptVersion - 0x%x\n", ImageDescriptor[Index].LastAttemptVersion)); - DEBUG((DEBUG_VERBOSE, " LastAttemptStatus - 0x%x\n", ImageDescriptor[Index].LastAttemptStatus)); - DEBUG((DEBUG_VERBOSE, " HardwareInstance - 0x%lx\n", ImageDescriptor[Index].HardwareInstance)); - } -} - -/** - Initialize MicrocodeFmpDriver private data structure. - - @param[in] MicrocodeFmpPrivate private data structure to be initialized. - - @return EFI_SUCCESS private data is initialized. -**/ -EFI_STATUS -InitializePrivateData ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ) -{ - EFI_STATUS Status; - EFI_STATUS VarStatus; - UINTN VarSize; - BOOLEAN Result; - - MicrocodeFmpPrivate->Signature = MICROCODE_FMP_PRIVATE_DATA_SIGNATURE; - MicrocodeFmpPrivate->Handle = NULL; - CopyMem(&MicrocodeFmpPrivate->Fmp, &mFirmwareManagementProtocol, sizeof(EFI_FIRMWARE_MANAGEMENT_PROTOCOL)); - - MicrocodeFmpPrivate->PackageVersion = 0x1; - MicrocodeFmpPrivate->PackageVersionName = L"Microcode"; - - MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion = 0x0; - MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus = 0x0; - VarSize = sizeof(MicrocodeFmpPrivate->LastAttempt); - VarStatus = gRT->GetVariable( - MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME, - &gEfiCallerIdGuid, - NULL, - &VarSize, - &MicrocodeFmpPrivate->LastAttempt - ); - DEBUG((DEBUG_INFO, "GetLastAttemp - %r\n", VarStatus)); - DEBUG((DEBUG_INFO, "GetLastAttemp Version - 0x%x, State - 0x%x\n", MicrocodeFmpPrivate->LastAttempt.LastAttemptVersion, MicrocodeFmpPrivate->LastAttempt.LastAttemptStatus)); - - Result = GetMicrocodeRegion(&MicrocodeFmpPrivate->MicrocodePatchAddress, &MicrocodeFmpPrivate->MicrocodePatchRegionSize); - if (!Result) { - DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n")); - return EFI_NOT_FOUND; - } - - Status = InitializeProcessorInfo (MicrocodeFmpPrivate); - if (EFI_ERROR(Status)) { - DEBUG((DEBUG_ERROR, "InitializeProcessorInfo - %r\n", Status)); - return Status; - } - - Status = InitializeMicrocodeDescriptor(MicrocodeFmpPrivate); - if (EFI_ERROR(Status)) { - DEBUG((DEBUG_ERROR, "InitializeMicrocodeDescriptor - %r\n", Status)); - return Status; - } - - DumpPrivateInfo (MicrocodeFmpPrivate); - - return Status; -} - -/** - Microcode FMP module entrypoint - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @return EFI_SUCCESS Microcode FMP module is initialized. -**/ -EFI_STATUS -EFIAPI -MicrocodeFmpMain ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - // - // Initialize MicrocodeFmpPrivateData - // - mMicrocodeFmpPrivate = AllocateZeroPool (sizeof(MICROCODE_FMP_PRIVATE_DATA)); - if (mMicrocodeFmpPrivate == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = InitializePrivateData(mMicrocodeFmpPrivate); - if (EFI_ERROR(Status)) { - FreePool(mMicrocodeFmpPrivate); - mMicrocodeFmpPrivate = NULL; - return Status; - } - - // - // Install FMP protocol. - // - Status = gBS->InstallProtocolInterface ( - &mMicrocodeFmpPrivate->Handle, - &gEfiFirmwareManagementProtocolGuid, - EFI_NATIVE_INTERFACE, - &mMicrocodeFmpPrivate->Fmp - ); - if (EFI_ERROR (Status)) { - FreePool(mMicrocodeFmpPrivate); - mMicrocodeFmpPrivate = NULL; - return Status; - } - - return Status; -} diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c deleted file mode 100644 index 4e8f1d5fd8..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c +++ /dev/null @@ -1,981 +0,0 @@ -/** @file - SetImage instance to update Microcode. - - Caution: This module requires additional review when modified. - This module will have external input - capsule image. - This external input must be validated carefully to avoid security issue like - buffer overflow, integer overflow. - - MicrocodeWrite() and VerifyMicrocode() will receive untrusted input and do basic validation. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "MicrocodeUpdate.h" - -/** - Get Microcode Region. - - @param[out] MicrocodePatchAddress The address of Microcode - @param[out] MicrocodePatchRegionSize The region size of Microcode - - @retval TRUE The Microcode region is returned. - @retval FALSE No Microcode region. -**/ -BOOLEAN -GetMicrocodeRegion ( - OUT VOID **MicrocodePatchAddress, - OUT UINTN *MicrocodePatchRegionSize - ) -{ - *MicrocodePatchAddress = (VOID *)(UINTN)PcdGet64(PcdCpuMicrocodePatchAddress); - *MicrocodePatchRegionSize = (UINTN)PcdGet64(PcdCpuMicrocodePatchRegionSize); - - if ((*MicrocodePatchAddress == NULL) || (*MicrocodePatchRegionSize == 0)) { - return FALSE; - } - - return TRUE; -} - -/** - Get Microcode update signature of currently loaded Microcode update. - - @return Microcode signature. - -**/ -UINT32 -GetCurrentMicrocodeSignature ( - VOID - ) -{ - UINT64 Signature; - - AsmWriteMsr64(MSR_IA32_BIOS_SIGN_ID, 0); - AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); - Signature = AsmReadMsr64(MSR_IA32_BIOS_SIGN_ID); - return (UINT32)RShiftU64(Signature, 32); -} - -/** - Get current processor signature. - - @return current processor signature. -**/ -UINT32 -GetCurrentProcessorSignature ( - VOID - ) -{ - UINT32 RegEax; - AsmCpuid(CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL); - return RegEax; -} - -/** - Get current platform ID. - - @return current platform ID. -**/ -UINT8 -GetCurrentPlatformId ( - VOID - ) -{ - UINT8 PlatformId; - - PlatformId = (UINT8)AsmMsrBitFieldRead64(MSR_IA32_PLATFORM_ID, 50, 52); - return PlatformId; -} - -/** - Load new Microcode. - - @param[in] Address The address of new Microcode. - - @return Loaded Microcode signature. - -**/ -UINT32 -LoadMicrocode ( - IN UINT64 Address - ) -{ - AsmWriteMsr64(MSR_IA32_BIOS_UPDT_TRIG, Address); - return GetCurrentMicrocodeSignature(); -} - -/** - Load Microcode on an Application Processor. - The function prototype for invoking a function on an Application Processor. - - @param[in,out] Buffer The pointer to private data buffer. -**/ -VOID -EFIAPI -MicrocodeLoadAp ( - IN OUT VOID *Buffer - ) -{ - MICROCODE_LOAD_BUFFER *MicrocodeLoadBuffer; - - MicrocodeLoadBuffer = Buffer; - MicrocodeLoadBuffer->Revision = LoadMicrocode (MicrocodeLoadBuffer->Address); -} - -/** - Load new Microcode on this processor - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] CpuIndex The index of the processor. - @param[in] Address The address of new Microcode. - - @return Loaded Microcode signature. - -**/ -UINT32 -LoadMicrocodeOnThis ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN UINTN CpuIndex, - IN UINT64 Address - ) -{ - EFI_STATUS Status; - EFI_MP_SERVICES_PROTOCOL *MpService; - MICROCODE_LOAD_BUFFER MicrocodeLoadBuffer; - - if (CpuIndex == MicrocodeFmpPrivate->BspIndex) { - return LoadMicrocode (Address); - } else { - MpService = MicrocodeFmpPrivate->MpService; - MicrocodeLoadBuffer.Address = Address; - MicrocodeLoadBuffer.Revision = 0; - Status = MpService->StartupThisAP ( - MpService, - MicrocodeLoadAp, - CpuIndex, - NULL, - 0, - &MicrocodeLoadBuffer, - NULL - ); - ASSERT_EFI_ERROR(Status); - return MicrocodeLoadBuffer.Revision; - } -} - -/** - Collect processor information. - The function prototype for invoking a function on an Application Processor. - - @param[in,out] Buffer The pointer to private data buffer. -**/ -VOID -EFIAPI -CollectProcessorInfo ( - IN OUT VOID *Buffer - ) -{ - PROCESSOR_INFO *ProcessorInfo; - - ProcessorInfo = Buffer; - ProcessorInfo->ProcessorSignature = GetCurrentProcessorSignature(); - ProcessorInfo->PlatformId = GetCurrentPlatformId(); - ProcessorInfo->MicrocodeRevision = GetCurrentMicrocodeSignature(); -} - -/** - Get current Microcode information. - - The ProcessorInformation (BspIndex/ProcessorCount/ProcessorInfo) - in MicrocodeFmpPrivate must be initialized. - - The MicrocodeInformation (DescriptorCount/ImageDescriptor/MicrocodeInfo) - in MicrocodeFmpPrivate may not be avaiable in this function. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] DescriptorCount The count of Microcode ImageDescriptor allocated. - @param[out] ImageDescriptor Microcode ImageDescriptor - @param[out] MicrocodeInfo Microcode information - - @return Microcode count -**/ -UINTN -GetMicrocodeInfo ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN UINTN DescriptorCount, OPTIONAL - OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor, OPTIONAL - OUT MICROCODE_INFO *MicrocodeInfo OPTIONAL - ) -{ - VOID *MicrocodePatchAddress; - UINTN MicrocodePatchRegionSize; - CPU_MICROCODE_HEADER *MicrocodeEntryPoint; - UINTN MicrocodeEnd; - UINTN TotalSize; - UINTN Count; - UINT64 ImageAttributes; - BOOLEAN IsInUse; - EFI_STATUS Status; - UINT32 AttemptStatus; - UINTN TargetCpuIndex; - - MicrocodePatchAddress = MicrocodeFmpPrivate->MicrocodePatchAddress; - MicrocodePatchRegionSize = MicrocodeFmpPrivate->MicrocodePatchRegionSize; - - DEBUG((DEBUG_INFO, "Microcode Region - 0x%x - 0x%x\n", MicrocodePatchAddress, MicrocodePatchRegionSize)); - - Count = 0; - - MicrocodeEnd = (UINTN)MicrocodePatchAddress + MicrocodePatchRegionSize; - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (UINTN) MicrocodePatchAddress; - do { - if (MicrocodeEntryPoint->HeaderVersion == 0x1 && MicrocodeEntryPoint->LoaderRevision == 0x1) { - // - // It is the microcode header. It is not the padding data between microcode patches - // becasue the padding data should not include 0x00000001 and it should be the repeated - // byte format (like 0xXYXYXYXY....). - // - if (MicrocodeEntryPoint->DataSize == 0) { - TotalSize = 2048; - } else { - TotalSize = MicrocodeEntryPoint->TotalSize; - } - - TargetCpuIndex = (UINTN)-1; - Status = VerifyMicrocode(MicrocodeFmpPrivate, MicrocodeEntryPoint, TotalSize, FALSE, &AttemptStatus, NULL, &TargetCpuIndex); - if (!EFI_ERROR(Status)) { - IsInUse = TRUE; - ASSERT (TargetCpuIndex < MicrocodeFmpPrivate->ProcessorCount); - MicrocodeFmpPrivate->ProcessorInfo[TargetCpuIndex].MicrocodeIndex = Count; - } else { - IsInUse = FALSE; - } - - if (ImageDescriptor != NULL && DescriptorCount > Count) { - ImageDescriptor[Count].ImageIndex = (UINT8)(Count + 1); - CopyGuid (&ImageDescriptor[Count].ImageTypeId, &gMicrocodeFmpImageTypeIdGuid); - ImageDescriptor[Count].ImageId = LShiftU64(MicrocodeEntryPoint->ProcessorFlags, 32) + MicrocodeEntryPoint->ProcessorSignature.Uint32; - ImageDescriptor[Count].ImageIdName = NULL; - ImageDescriptor[Count].Version = MicrocodeEntryPoint->UpdateRevision; - ImageDescriptor[Count].VersionName = NULL; - ImageDescriptor[Count].Size = TotalSize; - ImageAttributes = IMAGE_ATTRIBUTE_IMAGE_UPDATABLE | IMAGE_ATTRIBUTE_RESET_REQUIRED; - if (IsInUse) { - ImageAttributes |= IMAGE_ATTRIBUTE_IN_USE; - } - ImageDescriptor[Count].AttributesSupported = ImageAttributes | IMAGE_ATTRIBUTE_IN_USE; - ImageDescriptor[Count].AttributesSetting = ImageAttributes; - ImageDescriptor[Count].Compatibilities = 0; - ImageDescriptor[Count].LowestSupportedImageVersion = MicrocodeEntryPoint->UpdateRevision; // do not support rollback - ImageDescriptor[Count].LastAttemptVersion = 0; - ImageDescriptor[Count].LastAttemptStatus = 0; - ImageDescriptor[Count].HardwareInstance = 0; - } - if (MicrocodeInfo != NULL && DescriptorCount > Count) { - MicrocodeInfo[Count].MicrocodeEntryPoint = MicrocodeEntryPoint; - MicrocodeInfo[Count].TotalSize = TotalSize; - MicrocodeInfo[Count].InUse = IsInUse; - } - } else { - // - // It is the padding data between the microcode patches for microcode patches alignment. - // Because the microcode patch is the multiple of 1-KByte, the padding data should not - // exist if the microcode patch alignment value is not larger than 1-KByte. So, the microcode - // alignment value should be larger than 1-KByte. We could skip SIZE_1KB padding data to - // find the next possible microcode patch header. - // - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + SIZE_1KB); - continue; - } - - Count++; - ASSERT(Count < 0xFF); - - // - // Get the next patch. - // - MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *) (((UINTN) MicrocodeEntryPoint) + TotalSize); - } while (((UINTN) MicrocodeEntryPoint < MicrocodeEnd)); - - return Count; -} - -/** - Return matched processor information. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] ProcessorSignature The processor signature to be matched - @param[in] ProcessorFlags The processor flags to be matched - @param[in, out] TargetCpuIndex On input, the index of target CPU which tries to match the Microcode. (UINTN)-1 means to try all. - On output, the index of target CPU which matches the Microcode. - - @return matched processor information. -**/ -PROCESSOR_INFO * -GetMatchedProcessor ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN UINT32 ProcessorSignature, - IN UINT32 ProcessorFlags, - IN OUT UINTN *TargetCpuIndex - ) -{ - UINTN Index; - - if (*TargetCpuIndex != (UINTN)-1) { - Index = *TargetCpuIndex; - if ((ProcessorSignature == MicrocodeFmpPrivate->ProcessorInfo[Index].ProcessorSignature) && - ((ProcessorFlags & (1 << MicrocodeFmpPrivate->ProcessorInfo[Index].PlatformId)) != 0)) { - return &MicrocodeFmpPrivate->ProcessorInfo[Index]; - } else { - return NULL; - } - } - - for (Index = 0; Index < MicrocodeFmpPrivate->ProcessorCount; Index++) { - if ((ProcessorSignature == MicrocodeFmpPrivate->ProcessorInfo[Index].ProcessorSignature) && - ((ProcessorFlags & (1 << MicrocodeFmpPrivate->ProcessorInfo[Index].PlatformId)) != 0)) { - *TargetCpuIndex = Index; - return &MicrocodeFmpPrivate->ProcessorInfo[Index]; - } - } - return NULL; -} - -/** - Verify Microcode. - - Caution: This function may receive untrusted input. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in bytes. - @param[in] TryLoad Try to load Microcode or not. - @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more - details for the aborted operation. The buffer is allocated by this function - with AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - @param[in, out] TargetCpuIndex On input, the index of target CPU which tries to match the Microcode. (UINTN)-1 means to try all. - On output, the index of target CPU which matches the Microcode. - - @retval EFI_SUCCESS The Microcode image passes verification. - @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. - @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. - @retval EFI_UNSUPPORTED The Microcode ProcessorSignature or ProcessorFlags is incorrect. - @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. -**/ -EFI_STATUS -VerifyMicrocode ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN VOID *Image, - IN UINTN ImageSize, - IN BOOLEAN TryLoad, - OUT UINT32 *LastAttemptStatus, - OUT CHAR16 **AbortReason, OPTIONAL - IN OUT UINTN *TargetCpuIndex - ) -{ - UINTN Index; - CPU_MICROCODE_HEADER *MicrocodeEntryPoint; - UINTN TotalSize; - UINTN DataSize; - UINT32 CurrentRevision; - PROCESSOR_INFO *ProcessorInfo; - UINT32 CheckSum32; - UINTN ExtendedTableLength; - UINT32 ExtendedTableCount; - CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; - CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; - BOOLEAN CorrectMicrocode; - - // - // Check HeaderVersion - // - MicrocodeEntryPoint = Image; - if (MicrocodeEntryPoint->HeaderVersion != 0x1) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on HeaderVersion\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidHeaderVersion"), L"InvalidHeaderVersion"); - } - return EFI_INCOMPATIBLE_VERSION; - } - // - // Check LoaderRevision - // - if (MicrocodeEntryPoint->LoaderRevision != 0x1) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on LoaderRevision\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidLoaderVersion"), L"InvalidLoaderVersion"); - } - return EFI_INCOMPATIBLE_VERSION; - } - // - // Check Size - // - if (MicrocodeEntryPoint->DataSize == 0) { - TotalSize = 2048; - } else { - TotalSize = MicrocodeEntryPoint->TotalSize; - } - if (TotalSize <= sizeof(CPU_MICROCODE_HEADER)) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - TotalSize too small\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidTotalSize"), L"InvalidTotalSize"); - } - return EFI_VOLUME_CORRUPTED; - } - if (TotalSize != ImageSize) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on TotalSize\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidTotalSize"), L"InvalidTotalSize"); - } - return EFI_VOLUME_CORRUPTED; - } - // - // Check CheckSum32 - // - if (MicrocodeEntryPoint->DataSize == 0) { - DataSize = 2048 - sizeof(CPU_MICROCODE_HEADER); - } else { - DataSize = MicrocodeEntryPoint->DataSize; - } - if (DataSize > TotalSize - sizeof(CPU_MICROCODE_HEADER)) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - DataSize too big\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidDataSize"), L"InvalidDataSize"); - } - return EFI_VOLUME_CORRUPTED; - } - if ((DataSize & 0x3) != 0) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - DataSize not aligned\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidDataSize"), L"InvalidDataSize"); - } - return EFI_VOLUME_CORRUPTED; - } - CheckSum32 = CalculateSum32((UINT32 *)MicrocodeEntryPoint, DataSize + sizeof(CPU_MICROCODE_HEADER)); - if (CheckSum32 != 0) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on CheckSum32\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidChecksum"), L"InvalidChecksum"); - } - return EFI_VOLUME_CORRUPTED; - } - - // - // Check ProcessorSignature/ProcessorFlags - // - - ProcessorInfo = GetMatchedProcessor (MicrocodeFmpPrivate, MicrocodeEntryPoint->ProcessorSignature.Uint32, MicrocodeEntryPoint->ProcessorFlags, TargetCpuIndex); - if (ProcessorInfo == NULL) { - CorrectMicrocode = FALSE; - ExtendedTableLength = TotalSize - (DataSize + sizeof(CPU_MICROCODE_HEADER)); - if (ExtendedTableLength != 0) { - // - // Extended Table exist, check if the CPU in support list - // - ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINT8 *)(MicrocodeEntryPoint) + DataSize + sizeof(CPU_MICROCODE_HEADER)); - // - // Calculate Extended Checksum - // - if ((ExtendedTableLength > sizeof(CPU_MICROCODE_EXTENDED_TABLE_HEADER)) && ((ExtendedTableLength & 0x3) != 0)) { - CheckSum32 = CalculateSum32((UINT32 *)ExtendedTableHeader, ExtendedTableLength); - if (CheckSum32 == 0) { - // - // Checksum correct - // - ExtendedTableCount = ExtendedTableHeader->ExtendedSignatureCount; - if (ExtendedTableCount <= (ExtendedTableLength - sizeof(CPU_MICROCODE_EXTENDED_TABLE_HEADER)) / sizeof(CPU_MICROCODE_EXTENDED_TABLE)) { - ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1); - for (Index = 0; Index < ExtendedTableCount; Index++) { - CheckSum32 = CalculateSum32((UINT32 *)ExtendedTable, sizeof(CPU_MICROCODE_EXTENDED_TABLE)); - if (CheckSum32 == 0) { - // - // Verify Header - // - ProcessorInfo = GetMatchedProcessor (MicrocodeFmpPrivate, ExtendedTable->ProcessorSignature.Uint32, ExtendedTable->ProcessorFlag, TargetCpuIndex); - if (ProcessorInfo != NULL) { - // - // Find one - // - CorrectMicrocode = TRUE; - break; - } - } - ExtendedTable++; - } - } - } - } - } - if (!CorrectMicrocode) { - if (TryLoad) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on CurrentProcessorSignature/ProcessorFlags\n")); - } - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"UnsupportedProcessSignature/ProcessorFlags"), L"UnsupportedProcessSignature/ProcessorFlags"); - } - return EFI_UNSUPPORTED; - } - } - - // - // Check UpdateRevision - // - CurrentRevision = ProcessorInfo->MicrocodeRevision; - if ((MicrocodeEntryPoint->UpdateRevision < CurrentRevision) || - (TryLoad && (MicrocodeEntryPoint->UpdateRevision == CurrentRevision))) { - if (TryLoad) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on UpdateRevision\n")); - } - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"IncorrectRevision"), L"IncorrectRevision"); - } - return EFI_INCOMPATIBLE_VERSION; - } - - // - // try load MCU - // - if (TryLoad) { - CurrentRevision = LoadMicrocodeOnThis(MicrocodeFmpPrivate, ProcessorInfo->CpuIndex, (UINTN)MicrocodeEntryPoint + sizeof(CPU_MICROCODE_HEADER)); - if (MicrocodeEntryPoint->UpdateRevision != CurrentRevision) { - DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on LoadMicrocode\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR; - if (AbortReason != NULL) { - *AbortReason = AllocateCopyPool(sizeof(L"InvalidData"), L"InvalidData"); - } - return EFI_SECURITY_VIOLATION; - } - } - - return EFI_SUCCESS; -} - -/** - Get next Microcode entrypoint. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] MicrocodeEntryPoint Current Microcode entrypoint - - @return next Microcode entrypoint. -**/ -CPU_MICROCODE_HEADER * -GetNextMicrocode ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN CPU_MICROCODE_HEADER *MicrocodeEntryPoint - ) -{ - UINTN Index; - - for (Index = 0; Index < MicrocodeFmpPrivate->DescriptorCount; Index++) { - if (MicrocodeEntryPoint == MicrocodeFmpPrivate->MicrocodeInfo[Index].MicrocodeEntryPoint) { - if (Index == (UINTN)MicrocodeFmpPrivate->DescriptorCount - 1) { - // it is last one - return NULL; - } else { - // return next one - return MicrocodeFmpPrivate->MicrocodeInfo[Index + 1].MicrocodeEntryPoint; - } - } - } - - ASSERT(FALSE); - return NULL; -} - -/** - Get current Microcode used region size. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - - @return current Microcode used region size. -**/ -UINTN -GetCurrentMicrocodeUsedRegionSize ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ) -{ - if (MicrocodeFmpPrivate->DescriptorCount == 0) { - return 0; - } - - return (UINTN)MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeFmpPrivate->DescriptorCount - 1].MicrocodeEntryPoint - + (UINTN)MicrocodeFmpPrivate->MicrocodeInfo[MicrocodeFmpPrivate->DescriptorCount - 1].TotalSize - - (UINTN)MicrocodeFmpPrivate->MicrocodePatchAddress; -} - -/** - Update Microcode. - - @param[in] Address The flash address of Microcode. - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in bytes. - @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - - @retval EFI_SUCCESS The Microcode image is updated. - @retval EFI_WRITE_PROTECTED The flash device is read only. -**/ -EFI_STATUS -UpdateMicrocode ( - IN UINT64 Address, - IN VOID *Image, - IN UINTN ImageSize, - OUT UINT32 *LastAttemptStatus - ) -{ - EFI_STATUS Status; - - DEBUG((DEBUG_INFO, "PlatformUpdate:")); - DEBUG((DEBUG_INFO, " Address - 0x%lx,", Address)); - DEBUG((DEBUG_INFO, " Legnth - 0x%x\n", ImageSize)); - - Status = MicrocodeFlashWrite ( - Address, - Image, - ImageSize - ); - if (!EFI_ERROR(Status)) { - *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; - } else { - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; - } - return Status; -} - -/** - Update Microcode flash region. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] TargetMicrocodeEntryPoint Target Microcode entrypoint to be updated - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in bytes. - @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - - @retval EFI_SUCCESS The Microcode image is written. - @retval EFI_WRITE_PROTECTED The flash device is read only. -**/ -EFI_STATUS -UpdateMicrocodeFlashRegion ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN CPU_MICROCODE_HEADER *TargetMicrocodeEntryPoint, - IN VOID *Image, - IN UINTN ImageSize, - OUT UINT32 *LastAttemptStatus - ) -{ - VOID *MicrocodePatchAddress; - UINTN MicrocodePatchRegionSize; - UINTN TargetTotalSize; - UINTN UsedRegionSize; - EFI_STATUS Status; - VOID *MicrocodePatchScratchBuffer; - UINT8 *ScratchBufferPtr; - UINTN ScratchBufferSize; - UINTN RestSize; - UINTN AvailableSize; - VOID *NextMicrocodeEntryPoint; - MICROCODE_INFO *MicrocodeInfo; - UINTN MicrocodeCount; - UINTN Index; - - DEBUG((DEBUG_INFO, "UpdateMicrocodeFlashRegion: Image - 0x%x, size - 0x%x\n", Image, ImageSize)); - - MicrocodePatchAddress = MicrocodeFmpPrivate->MicrocodePatchAddress; - MicrocodePatchRegionSize = MicrocodeFmpPrivate->MicrocodePatchRegionSize; - - MicrocodePatchScratchBuffer = AllocateZeroPool (MicrocodePatchRegionSize); - if (MicrocodePatchScratchBuffer == NULL) { - DEBUG((DEBUG_ERROR, "Fail to allocate Microcode Scratch buffer\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; - return EFI_OUT_OF_RESOURCES; - } - ScratchBufferPtr = MicrocodePatchScratchBuffer; - ScratchBufferSize = 0; - - // - // Target data collection - // - TargetTotalSize = 0; - AvailableSize = 0; - NextMicrocodeEntryPoint = NULL; - if (TargetMicrocodeEntryPoint != NULL) { - if (TargetMicrocodeEntryPoint->DataSize == 0) { - TargetTotalSize = 2048; - } else { - TargetTotalSize = TargetMicrocodeEntryPoint->TotalSize; - } - DEBUG((DEBUG_INFO, " TargetTotalSize - 0x%x\n", TargetTotalSize)); - NextMicrocodeEntryPoint = GetNextMicrocode(MicrocodeFmpPrivate, TargetMicrocodeEntryPoint); - DEBUG((DEBUG_INFO, " NextMicrocodeEntryPoint - 0x%x\n", NextMicrocodeEntryPoint)); - if (NextMicrocodeEntryPoint != NULL) { - ASSERT ((UINTN)NextMicrocodeEntryPoint >= ((UINTN)TargetMicrocodeEntryPoint + TargetTotalSize)); - AvailableSize = (UINTN)NextMicrocodeEntryPoint - (UINTN)TargetMicrocodeEntryPoint; - } else { - AvailableSize = (UINTN)MicrocodePatchAddress + MicrocodePatchRegionSize - (UINTN)TargetMicrocodeEntryPoint; - } - DEBUG((DEBUG_INFO, " AvailableSize - 0x%x\n", AvailableSize)); - } - ASSERT (AvailableSize >= TargetTotalSize); - UsedRegionSize = GetCurrentMicrocodeUsedRegionSize(MicrocodeFmpPrivate); - DEBUG((DEBUG_INFO, " UsedRegionSize - 0x%x\n", UsedRegionSize)); - ASSERT (UsedRegionSize >= TargetTotalSize); - if (TargetMicrocodeEntryPoint != NULL) { - ASSERT ((UINTN)MicrocodePatchAddress + UsedRegionSize >= ((UINTN)TargetMicrocodeEntryPoint + TargetTotalSize)); - } - // - // Total Size means the Microcode data size. - // Available Size means the Microcode data size plus the pad till (1) next Microcode or (2) the end. - // - // (1) - // +------+-----------+-----+------+===================+ - // | MCU1 | Microcode | PAD | MCU2 | Empty | - // +------+-----------+-----+------+===================+ - // | TotalSize | - // |<-AvailableSize->| - // |<- UsedRegionSize ->| - // - // (2) - // +------+-----------+===================+ - // | MCU | Microcode | Empty | - // +------+-----------+===================+ - // | TotalSize | - // |<- AvailableSize ->| - // |<-UsedRegionSize->| - // - - // - // Update based on policy - // - - // - // 1. If there is enough space to update old one in situ, replace old microcode in situ. - // - if (AvailableSize >= ImageSize) { - DEBUG((DEBUG_INFO, "Replace old microcode in situ\n")); - // - // +------+------------+------+===================+ - // |Other1| Old Image |Other2| Empty | - // +------+------------+------+===================+ - // - // +------+---------+--+------+===================+ - // |Other1|New Image|FF|Other2| Empty | - // +------+---------+--+------+===================+ - // - // 1.1. Copy new image - CopyMem (ScratchBufferPtr, Image, ImageSize); - ScratchBufferSize += ImageSize; - ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; - // 1.2. Pad 0xFF - RestSize = AvailableSize - ImageSize; - if (RestSize > 0) { - SetMem (ScratchBufferPtr, RestSize, 0xFF); - ScratchBufferSize += RestSize; - ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; - } - Status = UpdateMicrocode((UINTN)TargetMicrocodeEntryPoint, MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); - return Status; - } - - // - // 2. If there is enough space to remove old one and add new one, reorg and replace old microcode. - // - if (MicrocodePatchRegionSize - (UsedRegionSize - TargetTotalSize) >= ImageSize) { - if (TargetMicrocodeEntryPoint == NULL) { - DEBUG((DEBUG_INFO, "Append new microcode\n")); - // - // +------+------------+------+===================+ - // |Other1| Other |Other2| Empty | - // +------+------------+------+===================+ - // - // +------+------------+------+-----------+=======+ - // |Other1| Other |Other2| New Image | Empty | - // +------+------------+------+-----------+=======+ - // - Status = UpdateMicrocode((UINTN)MicrocodePatchAddress + UsedRegionSize, Image, ImageSize, LastAttemptStatus); - } else { - DEBUG((DEBUG_INFO, "Reorg and replace old microcode\n")); - // - // +------+------------+------+===================+ - // |Other1| Old Image |Other2| Empty | - // +------+------------+------+===================+ - // - // +------+---------------+------+================+ - // |Other1| New Image |Other2| Empty | - // +------+---------------+------+================+ - // - // 2.1. Copy new image - CopyMem (ScratchBufferPtr, Image, ImageSize); - ScratchBufferSize += ImageSize; - ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; - // 2.2. Copy rest images after the old image. - if (NextMicrocodeEntryPoint != 0) { - RestSize = (UINTN)MicrocodePatchAddress + UsedRegionSize - ((UINTN)NextMicrocodeEntryPoint); - CopyMem (ScratchBufferPtr, (UINT8 *)TargetMicrocodeEntryPoint + TargetTotalSize, RestSize); - ScratchBufferSize += RestSize; - ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; - } - Status = UpdateMicrocode((UINTN)TargetMicrocodeEntryPoint, MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); - } - return Status; - } - - // - // 3. The new image can be put in MCU region, but not all others can be put. - // So all the unused MCU is removed. - // - if (MicrocodePatchRegionSize >= ImageSize) { - // - // +------+------------+------+===================+ - // |Other1| Old Image |Other2| Empty | - // +------+------------+------+===================+ - // - // +-------------------------------------+--------+ - // | New Image | Other | - // +-------------------------------------+--------+ - // - DEBUG((DEBUG_INFO, "Add new microcode from beginning\n")); - - MicrocodeCount = MicrocodeFmpPrivate->DescriptorCount; - MicrocodeInfo = MicrocodeFmpPrivate->MicrocodeInfo; - - // 3.1. Copy new image - CopyMem (ScratchBufferPtr, Image, ImageSize); - ScratchBufferSize += ImageSize; - ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; - // 3.2. Copy some others to rest buffer - for (Index = 0; Index < MicrocodeCount; Index++) { - if (!MicrocodeInfo[Index].InUse) { - continue; - } - if (MicrocodeInfo[Index].MicrocodeEntryPoint == TargetMicrocodeEntryPoint) { - continue; - } - if (MicrocodeInfo[Index].TotalSize <= MicrocodePatchRegionSize - ScratchBufferSize) { - CopyMem (ScratchBufferPtr, MicrocodeInfo[Index].MicrocodeEntryPoint, MicrocodeInfo[Index].TotalSize); - ScratchBufferSize += MicrocodeInfo[Index].TotalSize; - ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; - } - } - // 3.3. Pad 0xFF - RestSize = MicrocodePatchRegionSize - ScratchBufferSize; - if (RestSize > 0) { - SetMem (ScratchBufferPtr, RestSize, 0xFF); - ScratchBufferSize += RestSize; - ScratchBufferPtr = (UINT8 *)MicrocodePatchScratchBuffer + ScratchBufferSize; - } - Status = UpdateMicrocode((UINTN)MicrocodePatchAddress, MicrocodePatchScratchBuffer, ScratchBufferSize, LastAttemptStatus); - return Status; - } - - // - // 4. The new image size is bigger than the whole MCU region. - // - DEBUG((DEBUG_ERROR, "Microcode too big\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; - Status = EFI_OUT_OF_RESOURCES; - - return Status; -} - -/** - Write Microcode. - - Caution: This function may receive untrusted input. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in bytes. - @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more - details for the aborted operation. The buffer is allocated by this function - with AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - - @retval EFI_SUCCESS The Microcode image is written. - @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. - @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. - @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. - @retval EFI_WRITE_PROTECTED The flash device is read only. -**/ -EFI_STATUS -MicrocodeWrite ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN VOID *Image, - IN UINTN ImageSize, - OUT UINT32 *LastAttemptVersion, - OUT UINT32 *LastAttemptStatus, - OUT CHAR16 **AbortReason - ) -{ - EFI_STATUS Status; - VOID *AlignedImage; - CPU_MICROCODE_HEADER *TargetMicrocodeEntryPoint; - UINTN TargetCpuIndex; - UINTN TargetMicrcodeIndex; - - // - // MCU must be 16 bytes aligned - // - AlignedImage = AllocateCopyPool(ImageSize, Image); - if (AlignedImage == NULL) { - DEBUG((DEBUG_ERROR, "Fail to allocate aligned image\n")); - *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES; - return EFI_OUT_OF_RESOURCES; - } - - *LastAttemptVersion = ((CPU_MICROCODE_HEADER *)Image)->UpdateRevision; - TargetCpuIndex = (UINTN)-1; - Status = VerifyMicrocode(MicrocodeFmpPrivate, AlignedImage, ImageSize, TRUE, LastAttemptStatus, AbortReason, &TargetCpuIndex); - if (EFI_ERROR(Status)) { - DEBUG((DEBUG_ERROR, "Fail to verify Microcode Region\n")); - FreePool(AlignedImage); - return Status; - } - DEBUG((DEBUG_INFO, "Pass VerifyMicrocode\n")); - - DEBUG((DEBUG_INFO, " TargetCpuIndex - 0x%x\n", TargetCpuIndex)); - ASSERT (TargetCpuIndex < MicrocodeFmpPrivate->ProcessorCount); - TargetMicrcodeIndex = MicrocodeFmpPrivate->ProcessorInfo[TargetCpuIndex].MicrocodeIndex; - DEBUG((DEBUG_INFO, " TargetMicrcodeIndex - 0x%x\n", TargetMicrcodeIndex)); - if (TargetMicrcodeIndex != (UINTN)-1) { - ASSERT (TargetMicrcodeIndex < MicrocodeFmpPrivate->DescriptorCount); - TargetMicrocodeEntryPoint = MicrocodeFmpPrivate->MicrocodeInfo[TargetMicrcodeIndex].MicrocodeEntryPoint; - } else { - TargetMicrocodeEntryPoint = NULL; - } - DEBUG((DEBUG_INFO, " TargetMicrocodeEntryPoint - 0x%x\n", TargetMicrocodeEntryPoint)); - - Status = UpdateMicrocodeFlashRegion( - MicrocodeFmpPrivate, - TargetMicrocodeEntryPoint, - AlignedImage, - ImageSize, - LastAttemptStatus - ); - - FreePool(AlignedImage); - - return Status; -} - - diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h deleted file mode 100644 index 9dc306324e..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h +++ /dev/null @@ -1,494 +0,0 @@ -/** @file - Microcode update header file. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _MICROCODE_FMP_H_ -#define _MICROCODE_FMP_H_ - -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define MICROCODE_FMP_PRIVATE_DATA_SIGNATURE SIGNATURE_32('M', 'C', 'U', 'F') - -// -// Microcode FMP private data structure. -// - -typedef struct { - UINT32 LastAttemptVersion; - UINT32 LastAttemptStatus; -} MICROCODE_FMP_LAST_ATTEMPT_VARIABLE; - -typedef struct { - CPU_MICROCODE_HEADER *MicrocodeEntryPoint; - UINTN TotalSize; - BOOLEAN InUse; -} MICROCODE_INFO; - -typedef struct { - UINTN CpuIndex; - UINT32 ProcessorSignature; - UINT8 PlatformId; - UINT32 MicrocodeRevision; - UINTN MicrocodeIndex; -} PROCESSOR_INFO; - -typedef struct { - UINT64 Address; - UINT32 Revision; -} MICROCODE_LOAD_BUFFER; - -struct _MICROCODE_FMP_PRIVATE_DATA { - UINT32 Signature; - EFI_FIRMWARE_MANAGEMENT_PROTOCOL Fmp; - EFI_HANDLE Handle; - VOID *MicrocodePatchAddress; - UINTN MicrocodePatchRegionSize; - UINT8 DescriptorCount; - EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; - MICROCODE_INFO *MicrocodeInfo; - UINT32 PackageVersion; - CHAR16 *PackageVersionName; - MICROCODE_FMP_LAST_ATTEMPT_VARIABLE LastAttempt; - EFI_MP_SERVICES_PROTOCOL *MpService; - UINTN BspIndex; - UINTN ProcessorCount; - PROCESSOR_INFO *ProcessorInfo; -}; - -typedef struct _MICROCODE_FMP_PRIVATE_DATA MICROCODE_FMP_PRIVATE_DATA; - -#define MICROCODE_FMP_LAST_ATTEMPT_VARIABLE_NAME L"MicrocodeLastAttempVar" - -/** - Returns a pointer to the MICROCODE_FMP_PRIVATE_DATA structure from the input a as Fmp. - - If the signatures matches, then a pointer to the data structure that contains - a specified field of that data structure is returned. - - @param a Pointer to the field specified by ServiceBinding within - a data structure of type MICROCODE_FMP_PRIVATE_DATA. - -**/ -#define MICROCODE_FMP_PRIVATE_DATA_FROM_FMP(a) \ - CR ( \ - (a), \ - MICROCODE_FMP_PRIVATE_DATA, \ - Fmp, \ - MICROCODE_FMP_PRIVATE_DATA_SIGNATURE \ - ) - -/** - Get Microcode Region. - - @param[out] MicrocodePatchAddress The address of Microcode - @param[out] MicrocodePatchRegionSize The region size of Microcode - - @retval TRUE The Microcode region is returned. - @retval FALSE No Microcode region. -**/ -BOOLEAN -GetMicrocodeRegion ( - OUT VOID **MicrocodePatchAddress, - OUT UINTN *MicrocodePatchRegionSize - ); - -/** - Collect processor information. - The function prototype for invoking a function on an Application Processor. - - @param[in,out] Buffer The pointer to private data buffer. -**/ -VOID -EFIAPI -CollectProcessorInfo ( - IN OUT VOID *Buffer - ); - -/** - Get current Microcode information. - - The ProcessorInformation (BspIndex/ProcessorCount/ProcessorInfo) - in MicrocodeFmpPrivate must be initialized. - - The MicrocodeInformation (DescriptorCount/ImageDescriptor/MicrocodeInfo) - in MicrocodeFmpPrivate may not be avaiable in this function. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] DescriptorCount The count of Microcode ImageDescriptor allocated. - @param[out] ImageDescriptor Microcode ImageDescriptor - @param[out] MicrocodeInfo Microcode information - - @return Microcode count -**/ -UINTN -GetMicrocodeInfo ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN UINTN DescriptorCount, OPTIONAL - OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor, OPTIONAL - OUT MICROCODE_INFO *MicrocodeInfo OPTIONAL - ); - -/** - Verify Microcode. - - Caution: This function may receive untrusted input. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in bytes. - @param[in] TryLoad Try to load Microcode or not. - @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more - details for the aborted operation. The buffer is allocated by this function - with AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - @param[in, out] TargetCpuIndex On input, the index of target CPU which tries to match the Microcode. (UINTN)-1 means to try all. - On output, the index of target CPU which matches the Microcode. - - @retval EFI_SUCCESS The Microcode image passes verification. - @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. - @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. - @retval EFI_UNSUPPORTED The Microcode ProcessorSignature or ProcessorFlags is incorrect. - @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. -**/ -EFI_STATUS -VerifyMicrocode ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN VOID *Image, - IN UINTN ImageSize, - IN BOOLEAN TryLoad, - OUT UINT32 *LastAttemptStatus, - OUT CHAR16 **AbortReason, OPTIONAL - IN OUT UINTN *TargetCpuIndex OPTIONAL - ); - -/** - Write Microcode. - - @param[in] MicrocodeFmpPrivate The Microcode driver private data - @param[in] Image The Microcode image buffer. - @param[in] ImageSize The size of Microcode image buffer in bytes. - @param[out] LastAttemptVersion The last attempt version, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] LastAttemptStatus The last attempt status, which will be recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more - details for the aborted operation. The buffer is allocated by this function - with AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - - @retval EFI_SUCCESS The Microcode image is written. - @retval EFI_VOLUME_CORRUPTED The Microcode image is corrupt. - @retval EFI_INCOMPATIBLE_VERSION The Microcode image version is incorrect. - @retval EFI_SECURITY_VIOLATION The Microcode image fails to load. - @retval EFI_WRITE_PROTECTED The flash device is read only. -**/ -EFI_STATUS -MicrocodeWrite ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate, - IN VOID *Image, - IN UINTN ImageSize, - OUT UINT32 *LastAttemptVersion, - OUT UINT32 *LastAttemptStatus, - OUT CHAR16 **AbortReason - ); - -/** - Dump private information. - - @param[in] MicrocodeFmpPrivate private data structure. -**/ -VOID -DumpPrivateInfo ( - IN MICROCODE_FMP_PRIVATE_DATA *MicrocodeFmpPrivate - ); - -/** - Returns information about the current firmware image(s) of the device. - - This function allows a copy of the current firmware image to be created and saved. - The saved copy could later been used, for example, in firmware image recovery or rollback. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer. - On input, this is the size of the buffer allocated by the caller. - On output, it is the size of the buffer returned by the firmware - if the buffer was large enough, or the size of the buffer needed - to contain the image(s) information if the buffer was too small. - @param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s) - information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs. - @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number - associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] DescriptorCount A pointer to the location in which firmware returns the number of - descriptors or firmware images within this device. - @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes, - of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR. - @param[out] PackageVersion A version number that represents all the firmware images in the device. - The format is vendor specific and new version must have a greater value - than the old version. If PackageVersion is not supported, the value is - 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison - is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates - that package version update is in progress. - @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the - package version name. The buffer is allocated by this function with - AllocatePool(), and it is the caller's responsibility to free it with a call - to FreePool(). - - @retval EFI_SUCCESS The device was successfully updated with the new image. - @retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size - needed to hold the image(s) information is returned in ImageInfoSize. - @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL. - @retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image. - -**/ -EFI_STATUS -EFIAPI -FmpGetImageInfo ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN OUT UINTN *ImageInfoSize, - IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo, - OUT UINT32 *DescriptorVersion, - OUT UINT8 *DescriptorCount, - OUT UINTN *DescriptorSize, - OUT UINT32 *PackageVersion, - OUT CHAR16 **PackageVersionName - ); - -/** - Retrieves a copy of the current firmware image of the device. - - This function allows a copy of the current firmware image to be created and saved. - The saved copy could later been used, for example, in firmware image recovery or rollback. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. - The number is between 1 and DescriptorCount. - @param[in,out] Image Points to the buffer where the current image is copied to. - @param[in,out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes. - On return, points to the length of the image, in bytes. - - @retval EFI_SUCCESS The device was successfully updated with the new image. - @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the - image. The current buffer size needed to hold the image is returned - in ImageSize. - @retval EFI_INVALID_PARAMETER The Image was NULL. - @retval EFI_NOT_FOUND The current image is not copied to the buffer. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpGetImage ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN UINT8 ImageIndex, - IN OUT VOID *Image, - IN OUT UINTN *ImageSize - ); - -/** - Updates the firmware image of the device. - - This function updates the hardware with the new firmware image. - This function returns EFI_UNSUPPORTED if the firmware image is not updatable. - If the firmware image is updatable, the function should perform the following minimal validations - before proceeding to do the firmware image update. - - Validate the image authentication if image has attribute - IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns - EFI_SECURITY_VIOLATION if the validation fails. - - Validate the image is a supported image for this device. The function returns EFI_ABORTED if - the image is unsupported. The function can optionally provide more detailed information on - why the image is not a supported image. - - Validate the data from VendorCode if not null. Image validation must be performed before - VendorCode data validation. VendorCode data is ignored or considered invalid if image - validation failed. The function returns EFI_ABORTED if the data is invalid. - - VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if - the caller did not specify the policy or use the default policy. As an example, vendor can implement - a policy to allow an option to force a firmware image update when the abort reason is due to the new - firmware image version is older than the current firmware image version or bad image checksum. - Sensitive operations such as those wiping the entire firmware image and render the device to be - non-functional should be encoded in the image itself rather than passed with the VendorCode. - AbortReason enables vendor to have the option to provide a more detailed description of the abort - reason to the caller. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. - The number is between 1 and DescriptorCount. - @param[in] Image Points to the new image. - @param[in] ImageSize Size of the new image in bytes. - @param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy. - Null indicates the caller did not specify the policy or use the default policy. - @param[in] Progress A function used by the driver to report the progress of the firmware update. - @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more - details for the aborted operation. The buffer is allocated by this function - with AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - - @retval EFI_SUCCESS The device was successfully updated with the new image. - @retval EFI_ABORTED The operation is aborted. - @retval EFI_INVALID_PARAMETER The Image was NULL. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpSetImage ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN UINT8 ImageIndex, - IN CONST VOID *Image, - IN UINTN ImageSize, - IN CONST VOID *VendorCode, - IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, - OUT CHAR16 **AbortReason - ); - -/** - Checks if the firmware image is valid for the device. - - This function allows firmware update application to validate the firmware image without - invoking the SetImage() first. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] ImageIndex A unique number identifying the firmware image(s) within the device. - The number is between 1 and DescriptorCount. - @param[in] Image Points to the new image. - @param[in] ImageSize Size of the new image in bytes. - @param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides, - if available, additional information if the image is invalid. - - @retval EFI_SUCCESS The image was successfully checked. - @retval EFI_INVALID_PARAMETER The Image was NULL. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpCheckImage ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN UINT8 ImageIndex, - IN CONST VOID *Image, - IN UINTN ImageSize, - OUT UINT32 *ImageUpdatable - ); - -/** - Returns information about the firmware package. - - This function returns package information. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[out] PackageVersion A version number that represents all the firmware images in the device. - The format is vendor specific and new version must have a greater value - than the old version. If PackageVersion is not supported, the value is - 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version - comparison is to be performed using PackageVersionName. A value of - 0xFFFFFFFD indicates that package version update is in progress. - @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing - the package version name. The buffer is allocated by this function with - AllocatePool(), and it is the caller's responsibility to free it with a - call to FreePool(). - @param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of - package version name. A value of 0 indicates the device does not support - update of package version name. Length is the number of Unicode characters, - including the terminating null character. - @param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute - Definitions' for possible returned values of this parameter. A value of 1 - indicates the attribute is supported and the current setting value is - indicated in AttributesSetting. A value of 0 indicates the attribute is not - supported and the current setting value in AttributesSetting is meaningless. - @param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned - values of this parameter - - @retval EFI_SUCCESS The package information was successfully returned. - @retval EFI_UNSUPPORTED The operation is not supported. - -**/ -EFI_STATUS -EFIAPI -FmpGetPackageInfo ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - OUT UINT32 *PackageVersion, - OUT CHAR16 **PackageVersionName, - OUT UINT32 *PackageVersionNameMaxLen, - OUT UINT64 *AttributesSupported, - OUT UINT64 *AttributesSetting - ); - -/** - Updates information about the firmware package. - - This function updates package information. - This function returns EFI_UNSUPPORTED if the package information is not updatable. - VendorCode enables vendor to implement vendor-specific package information update policy. - Null if the caller did not specify this policy or use the default policy. - - @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. - @param[in] Image Points to the authentication image. - Null if authentication is not required. - @param[in] ImageSize Size of the authentication image in bytes. - 0 if authentication is not required. - @param[in] VendorCode This enables vendor to implement vendor-specific firmware - image update policy. - Null indicates the caller did not specify this policy or use - the default policy. - @param[in] PackageVersion The new package version. - @param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing - the package version name. - The string length is equal to or less than the value returned in - PackageVersionNameMaxLen. - - @retval EFI_SUCCESS The device was successfully updated with the new package - information. - @retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value - returned in PackageVersionNameMaxLen. - @retval EFI_UNSUPPORTED The operation is not supported. - @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -FmpSetPackageInfo ( - IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, - IN CONST VOID *Image, - IN UINTN ImageSize, - IN CONST VOID *VendorCode, - IN UINT32 PackageVersion, - IN CONST CHAR16 *PackageVersionName - ); - -#endif - diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf deleted file mode 100644 index 55797cf132..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf +++ /dev/null @@ -1,71 +0,0 @@ -## @file -# Microcode FMP update driver. -# -# Produce FMP instance to update Microcode. -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = MicrocodeUpdateDxe - MODULE_UNI_FILE = MicrocodeUpdateDxe.uni - FILE_GUID = 0565365C-2FE1-4F88-B3BE-624C04623A20 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = MicrocodeFmpMain - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = X64 -# - -[Sources] - MicrocodeUpdate.h - MicrocodeFmp.c - MicrocodeUpdate.c - -[Packages] - MdePkg/MdePkg.dec - UefiCpuPkg/UefiCpuPkg.dec - -[LibraryClasses] - BaseLib - UefiLib - BaseMemoryLib - DebugLib - PcdLib - MemoryAllocationLib - UefiBootServicesTableLib - HobLib - UefiRuntimeServicesTableLib - UefiDriverEntryPoint - MicrocodeFlashAccessLib - -[Guids] - gMicrocodeFmpImageTypeIdGuid ## CONSUMES ## GUID - -[Protocols] - gEfiFirmwareManagementProtocolGuid ## PRODUCES - gEfiMpServiceProtocolGuid ## CONSUMES - -[Pcd] - gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES - -[Depex] - gEfiVariableArchProtocolGuid AND - gEfiMpServiceProtocolGuid - -[UserExtensions.TianoCore."ExtraFiles"] - MicrocodeUpdateDxeExtra.uni - diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni deleted file mode 100644 index 1b0d4941dc..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// Microcode FMP update driver. -// -// Produce FMP instance to update Microcode. -// -// Copyright (c) 2016, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Microcode FMP update driver." - -#string STR_MODULE_DESCRIPTION #language en-US "Produce FMP instance to update Microcode." diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni deleted file mode 100644 index b667f12f5c..0000000000 --- a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// MicrocodeUpdateDxe Localized Strings and Content -// -// Copyright (c) 2016, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"MicrocodeUpdate DXE Driver" - - diff --git a/UefiCpuPkg/Include/Guid/MicrocodeFmp.h b/UefiCpuPkg/Include/Guid/MicrocodeFmp.h deleted file mode 100644 index 88a19538c8..0000000000 --- a/UefiCpuPkg/Include/Guid/MicrocodeFmp.h +++ /dev/null @@ -1,21 +0,0 @@ -/** @file - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __MICROCODE_FMP_GUID_H__ -#define __MICROCODE_FMP_GUID_H__ - -#define MICROCODE_FMP_IMAGE_TYPE_ID_GUID { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } } - -extern EFI_GUID gMicrocodeFmpImageTypeIdGuid; - -#endif diff --git a/UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h b/UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h deleted file mode 100644 index 0dfc3ef376..0000000000 --- a/UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h +++ /dev/null @@ -1,39 +0,0 @@ -/** @file - Microcode flash device access library. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#ifndef __MICROCODE_FLASH_ACCESS_LIB_H__ -#define __MICROCODE_FLASH_ACCESS_LIB_H__ - -/** - Perform microcode write opreation. - - @param[in] FlashAddress The address of flash device to be accessed. - @param[in] Buffer The pointer to the data buffer. - @param[in] Length The length of data buffer in bytes. - - @retval EFI_SUCCESS The operation returns successfully. - @retval EFI_WRITE_PROTECTED The flash device is read only. - @retval EFI_UNSUPPORTED The flash device access is unsupported. - @retval EFI_INVALID_PARAMETER The input parameter is not valid. -**/ -EFI_STATUS -EFIAPI -MicrocodeFlashWrite ( - IN EFI_PHYSICAL_ADDRESS FlashAddress, - IN VOID *Buffer, - IN UINTN Length - ); - -#endif diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 3bd8740c98..d2965ba14c 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -59,17 +59,10 @@ ## MpInitLib|Include/Library/MpInitLib.h - ## @libraryclass Provides services to access Microcode region on flash device. - # - MicrocodeFlashAccessLib|Include/Library/MicrocodeFlashAccessLib.h - [Guids] gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} gMsegSmramGuid = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }} - ## Include/Guid/MicrocodeFmp.h - gMicrocodeFmpImageTypeIdGuid = { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } } - ## Include/Guid/CpuFeaturesSetDone.h gEdkiiCpuFeaturesSetDoneGuid = { 0xa82485ce, 0xad6b, 0x4101, { 0x99, 0xd3, 0xe1, 0x35, 0x8c, 0x9e, 0x7e, 0x37 }} diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 41cf809559..d9a3d2d654 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -61,7 +61,6 @@ SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf - MicrocodeFlashAccessLib|UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf [LibraryClasses.common.SEC] @@ -152,7 +151,6 @@ SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf } UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf - UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf [BuildOptions] *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES