public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH V8 0/7] Add MicrocodeUpdate support.
@ 2016-11-02 14:07 Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 1/7] UefiCpuPkg/Include: Add Microcode FMP definition Jiewen Yao
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Feng Tian, Star Zeng, Michael D Kinney, Liming Gao, Chao Zhang,
	Jeff Fan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 11825 bytes --]

==Below is V8 description==
1) MdeModulePkg/dec: 
set gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid
to 0 as default.
2) SignedCapsulePkg/dec:
set gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid
to 0 as default.
3) QuarkPlatformPkg: Set CAPSULE_ENABLE/RECOVERY_ENABLE to FALSE as default.
4) All: rename EFI_D_* => DEBUG_*

==Below is V7 description==
1) MdeModulePkg/MdeModulePkg.dec: refine status code comment.
2) UefiCpuPkg: Move Microcode capsule related conent to Feature/capsule dir.
3) Vlv2TbltDevicePkg: Add MICOCODE_CAPSULE_ENABLE macro.

Only series 1, 3, 5 are sent for update review.
The other series are unchanged.

==Below is V6 description==
1) MdeModulePkg/CapsuleApp: Fix -D issue.
2) MdeModulePkg/DEC: Cleanup Capsule related StatusCode.
3) UefiCpuPkg: Remove MicrocodeUpdateApp
4) UefiCpuPkg: Add Microcode FMP build sample

Only series 1 and 3 are sent for update review.
The other series are unchanged.

==Below is V5 description==
1) MdeModulePkg/CapsuleApp: Remove [NR]. Add more description.
2) MdeModulePkg/DEC: Update StatusCode to OEM region.
3) MdeModulePkg/DxeCapsuleLib: Use NULL ProcessCapsules()
for runtime lib, because it is not needed for runtime.
4) MdeModulePkg/FmpAuthenticationLib: Add more description.
5) SignedCapsulePkg/DEC: Add data structure description
for PcdEdkiiSystemFirmwareImageDescriptor.
6) SignedCapsulePkg/DEC: Add Pkcs7 and Rsa2048 Key file PCD.
These 2 PCD are moved from platform pkg to SignedCapsulePkg.
7) QuarkPlatformPkg/FDF: Refine order of capsule section.
8) Fix typo and coding style issue.

Below items are defered to other patch series, because
the tool and library are not ready yet.

A) MdeModulePkg/DxeCapsuleLib: separate BMP parsing logic
to another library.
That is very good suggestion, and we agree it is a right direction.
I discussed with the owner of image decoder.
We prefer adding a generic library class to convert
the image data to GOP BLT buffer. It supports *any* image format,
not only BMP. The owner of image decoder will drive the new design.
I filed https://bugzilla.tianocore.org/show_bug.cgi?id=175 to track that.
I suggest we just keep the current solution as a temp solution and
migrate to the new one once it is ready later.

B) PlatformPkg/Bds: Move test key check logic to generic part.
This is very good suggestion and we are discussing with Tool
team to add such detection at build time and set a PCD to indicate that.
The generic code can use this PCD to know if there is a test key.
I filed https://bugzilla.tianocore.org/show_bug.cgi?id=185 to track that.
Adding such check in the generic code is very complicated, so current
temporary solution is to let platform BDS do such check.
The platform BDS will be cleaned up, once the tool is ready.

==Below is V4 description==
1) SecurityPkg - Refine AuthenticateFmpImage() API to let caller
input PublicKeyData and PublicKeyDataLength, instead of PCD.
The benefit is that then this API can be used for a platform
which stores PublicKeyData in anywhere other than PCD.
2) SecurityPkg - Use OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)
for better understanding the code.
3) MdeModulePkg - Update CapsuleApp to let it consume
ShellParameters protocol to get Argc and Argv.
4) UefiCpuPkg - Update MicrocodeCapsuleApp to let it consume
ShellParameters protocol to get Argc and Argv.
5) QuarkPlatformPkg - Merge QuarkCapsule.fdf to Quark.fdf.

==Below is V3 description==
1) We move all EDKII related capsule definition to SignedCapsulePkg.
MdeModulePkg only contains FmAuthenticationLib and CapsuleApp,
because they are generic and follow UEFI specification on FMP/ESRT
and Microsoft platform firmware update document.
Any capsule implementation can use them.

Here is full library classes:
MdeModulePkg:
	FmpAuthenticationLib.h: new lib - follow UEFI spec. (*)
		Verify FMP signature of FMP Capsule
	CapsuleLib.h: new API ¨C ProcessCapsules()
		It processes all the capsules. Remove duplicated code in platform BDS.
UefiCpuPkg:
	MicrocodeFlashAccessLib.h: Update Microcode region.
SignedCapsulePkg:
	EdkiiSystemCapsuleLib.h ¨C Library for EDKII system FMP.
	IniParsingLib.h ¨C Library for INI file parsing.
	PlatformFlashAccessLib.h ¨C Library for write flash.

2) We will submit 5 series.
Series 1: Generic Update (MdeModulePkg/SecurityPkg)
	DxeCapsuleLib
	FmAuthenticationLib (*)
	CapsuleApp (*)
Series 2: EDKII Capsule (SignedCapsulePkg)
	IniParsingLib
	EdkiiSystemCapsuleLib
	PlatformFlashAccessLib
	SystemFirmwareUpdate driver
	RecoveryModuleLoadPei driver
Series 3: Microcode Update (UefiCpuPkg)
	MicrocodeFlashAccessLib
	MicrocodeUpdate driver.
Series 4: Quark update
Series 5: Vlv2 update

3) DxeCapsuleLib: Move code that performs authentication and parsing of
the capsule format into the implementation of the FMP Protocol.
We move the dispatch FV code from CapsuleLib to SystemFirmwareReport.efi.
SystemFirmwareReport.efi supports SetImage() to verify and dispatch the
SystemFirmwareUpdate.efi, then pass thru SetImage() request to
SystemFirmwareUpdate.efi.

Now the DxeCapsuleLib is very clean and it does not have any EDKII
capsule format knowledge.

4) DxeCapsuleLib: Fix issue where a reset may be too soon.
Defer reset to 2nd pass.

5) DxeCapsuleLib: Boot mode check is removed. 
Capsule should be populated to system table even boot mode is not BIOS_UPDATE.

5) FmAuthenticationLib: Add zero ImageSize check.

6) FmAuthenticationLib: Remove Authentication Library Registration.
Each FMP Producer needs to carry its own auth algoritms(s).
Now we have FmpAuthenticationLibPkcs7 and FmpAuthenticationLibRsa2048Sha256.
No registration is needed.

7) FmAuthenticationLib: Move MonotonicCount handling after Payload
We confirmed with USWG to process MonotonicCount after PayLoad.

==Below is V2 description==
The V2 series patch incorporated the feedback for V1.

There are 3 major updates.
1) BDS is update to display a warning message if TEST key
is used to sign recovery image or capsule image.
So a production BIOS should always use its own production singing
key for the capsule image generation. A production BIOS should
never use test key.
2) IniParsingLib is enhanced to do more sanity check for invalid
input. The detail data format is added in IniParsingLib.h header
file. If there is any vialation, the OpenInitFile() API will
return failure.
3) The *Bios* keyword is renamed to *SystemFirmware* in any
header file or c file data structure definition.

The rest is minor update, such as add help info, clean
up debug message, coding style.

==Below is V1 description==
This series patch provides sample on how to do signed capsule update
and recovery in EDKII.

This series patch is also checked into git@github.com:jyao1/edk2.git.

The feature includes:
1) Define EDKII signed system BIOS capsule format.
2) Provide EDKII signed system BIOS update sample.
3) Provide EDKII signed recovery sample.
4) Provide Microcode update sample for X86 system.
5) Update Quark to use new capsule/recovery solution.
6) Update Vlv2(MinnowMax) to use new capsule/recovery solution.

The signed capsule/recovery solution is in MdeModulePkg.
The capsule in IntelFrameworkModulePkg is deprecated.
The Microcode update solution is in UefiCpuPkg.

Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Jeff Fan <jeff.fan@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>

Jiewen Yao (7):
  UefiCpuPkg/Include: Add Microcode FMP definition.
  UefiCpuPkg/Include: Add MicrocodeFlashAccessLib header.
  UefiCpuPkg/UefiCpuPkg.dec: Add Microcode capsule related definition.
  UefiCpuPkg/MicrocodeFlashAccessLib: Add NULL MicrocodeFlashAccessLib.
  UefiCpuPkg/MicrocodeUpdate: Add MicrocodeUpdate component.
  UefiCpuPkg/MicrocodeUpdate: Add Microcode FMP build sample
  UefiCpuPkg/UefiCpuPkg.dsc: Add MicrocodeCapsule related component.

 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c   |  42 ++
 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf |  40 +
 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni |  21 +
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc                         |  32 +
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf                         |  32 +
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md                                       |  20 +
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf                         |  27 +
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc                         |  38 +
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf                         |  32 +
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md                                       |  33 +
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c                                   | 537 ++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c                                | 779 ++++++++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h                                | 403 ++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf                           |  68 ++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni                           |  21 +
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni                      |  20 +
 UefiCpuPkg/Include/Guid/MicrocodeFmp.h                                                         |  21 +
 UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h                                           |  39 +
 UefiCpuPkg/UefiCpuPkg.dec                                                                      |   7 +
 UefiCpuPkg/UefiCpuPkg.dsc                                                                      |   2 +
 20 files changed, 2214 insertions(+)
 create mode 100644 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c
 create mode 100644 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf
 create mode 100644 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni
 create mode 100644 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni
 create mode 100644 UefiCpuPkg/Include/Guid/MicrocodeFmp.h
 create mode 100644 UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h

-- 
2.7.4.windows.1



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH V8 1/7] UefiCpuPkg/Include: Add Microcode FMP definition.
  2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
@ 2016-11-02 14:07 ` Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 2/7] UefiCpuPkg/Include: Add MicrocodeFlashAccessLib header Jiewen Yao
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Jeff Fan, Feng Tian, Star Zeng, Michael D Kinney, Liming Gao,
	Chao Zhang

It defined ImageTypeId for Microcode.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
---
 UefiCpuPkg/Include/Guid/MicrocodeFmp.h | 21 ++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/UefiCpuPkg/Include/Guid/MicrocodeFmp.h b/UefiCpuPkg/Include/Guid/MicrocodeFmp.h
new file mode 100644
index 0000000..88a1953
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/MicrocodeFmp.h
@@ -0,0 +1,21 @@
+/** @file
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  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
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V8 2/7] UefiCpuPkg/Include: Add MicrocodeFlashAccessLib header.
  2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 1/7] UefiCpuPkg/Include: Add Microcode FMP definition Jiewen Yao
@ 2016-11-02 14:07 ` Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 3/7] UefiCpuPkg/UefiCpuPkg.dec: Add Microcode capsule related definition Jiewen Yao
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Jeff Fan, Feng Tian, Star Zeng, Michael D Kinney, Liming Gao,
	Chao Zhang

This library is used to abstract microcode flash region access.
This library is consumed by a microcode capsule update module.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
---
 UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h | 39 ++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h b/UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h
new file mode 100644
index 0000000..0dfc3ef
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/MicrocodeFlashAccessLib.h
@@ -0,0 +1,39 @@
+/** @file
+  Microcode flash device access library.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  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
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V8 3/7] UefiCpuPkg/UefiCpuPkg.dec: Add Microcode capsule related definition.
  2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 1/7] UefiCpuPkg/Include: Add Microcode FMP definition Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 2/7] UefiCpuPkg/Include: Add MicrocodeFlashAccessLib header Jiewen Yao
@ 2016-11-02 14:07 ` Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 4/7] UefiCpuPkg/MicrocodeFlashAccessLib: Add NULL MicrocodeFlashAccessLib Jiewen Yao
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Jeff Fan, Feng Tian, Star Zeng, Michael D Kinney, Liming Gao,
	Chao Zhang

1) Add Microcode capsule related GUID.
   gMicrocodeFmpImageTypeIdGuid
2) Add Microcode capsule related library.
   MicrocodeFlashAccessLib

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
---
 UefiCpuPkg/UefiCpuPkg.dec | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index 8674533..542704b 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -54,9 +54,16 @@
   ##
   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 }}
 
+  ## Include/Guid/MicrocodeFmp.h
+  gMicrocodeFmpImageTypeIdGuid      = { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } }
+
 [Protocols]
   ## Include/Protocol/SmmCpuService.h
   gEfiSmmCpuServiceProtocolGuid  = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V8 4/7] UefiCpuPkg/MicrocodeFlashAccessLib: Add NULL MicrocodeFlashAccessLib.
  2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
                   ` (2 preceding siblings ...)
  2016-11-02 14:07 ` [PATCH V8 3/7] UefiCpuPkg/UefiCpuPkg.dec: Add Microcode capsule related definition Jiewen Yao
@ 2016-11-02 14:07 ` Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 5/7] UefiCpuPkg/MicrocodeUpdate: Add MicrocodeUpdate component Jiewen Yao
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Jeff Fan, Feng Tian, Star Zeng, Michael D Kinney, Liming Gao,
	Chao Zhang

Add NULL instance to pass build.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
---
 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c   | 42 ++++++++++++++++++++
 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.inf | 40 +++++++++++++++++++
 UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.uni | 21 ++++++++++
 3 files changed, 103 insertions(+)

diff --git a/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c b/UefiCpuPkg/Feature/Capsule/Library/MicrocodeFlashAccessLibNull/MicrocodeFlashAccessLibNull.c
new file mode 100644
index 0000000..7a5ec15
--- /dev/null
+++ b/UefiCpuPkg/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.<BR>
+  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 <PiDxe.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/MicrocodeFlashAccessLib.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
+  )
+{
+  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
new file mode 100644
index 0000000..a4a47e0
--- /dev/null
+++ b/UefiCpuPkg/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.<BR>
+#  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
new file mode 100644
index 0000000..cc4195c
--- /dev/null
+++ b/UefiCpuPkg/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.<BR>
+//
+// 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."
+
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V8 5/7] UefiCpuPkg/MicrocodeUpdate: Add MicrocodeUpdate component.
  2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
                   ` (3 preceding siblings ...)
  2016-11-02 14:07 ` [PATCH V8 4/7] UefiCpuPkg/MicrocodeFlashAccessLib: Add NULL MicrocodeFlashAccessLib Jiewen Yao
@ 2016-11-02 14:07 ` Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 6/7] UefiCpuPkg/MicrocodeUpdate: Add Microcode FMP build sample Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 7/7] UefiCpuPkg/UefiCpuPkg.dsc: Add MicrocodeCapsule related component Jiewen Yao
  6 siblings, 0 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Jeff Fan, Feng Tian, Star Zeng, Michael D Kinney, Liming Gao,
	Chao Zhang

MicrocodeUpdate supports update Microcode region via UEFI FMP capsule.

MicrocodeUpdate SetImage() will perform the Microcode version,
ProcessorSignature/ProcessorFlag, and try to load microcode.
If and only if the Microcode is loaded successfully, and new Microcode
will be updated to system flash region.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
---
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c              | 537 ++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c           | 779 ++++++++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h           | 403 ++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf      |  68 ++
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni      |  21 +
 UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni |  20 +
 6 files changed, 1828 insertions(+)

diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c
new file mode 100644
index 0000000..df3563d
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeFmp.c
@@ -0,0 +1,537 @@
+/** @file
+  Produce FMP instance for Microcode.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  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;
+  EFI_STATUS                 Status;
+
+  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;
+  }
+
+  Status = MicrocodeRead(ImageIndex, (VOID *)Image, ImageSize);
+  return Status;
+}
+
+/**
+  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(ImageIndex, (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);
+  }
+
+  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 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(NULL, 0);
+
+  if (CurrentMicrocodeCount > MicrocodeFmpPrivate->DescriptorCount) {
+    if (MicrocodeFmpPrivate->ImageDescriptor != NULL) {
+      FreePool(MicrocodeFmpPrivate->ImageDescriptor);
+      MicrocodeFmpPrivate->ImageDescriptor = NULL;
+    }
+  } else {
+    ZeroMem(MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->DescriptorCount * sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR));
+  }
+
+  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;
+    }
+  }
+
+  CurrentMicrocodeCount = (UINT8)GetMicrocodeInfo(MicrocodeFmpPrivate->ImageDescriptor, MicrocodeFmpPrivate->DescriptorCount);
+  ASSERT(CurrentMicrocodeCount == MicrocodeFmpPrivate->DescriptorCount);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  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;
+
+  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));
+
+  Status = InitializeMicrocodeDescriptor(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
new file mode 100644
index 0000000..4b5c881
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.c
@@ -0,0 +1,779 @@
+/** @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.<BR>
+  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 UINT64   *MicrocodePatchAddress,
+  OUT UINT64   *MicrocodePatchRegionSize
+  )
+{
+  *MicrocodePatchAddress = PcdGet64(PcdCpuMicrocodePatchAddress);
+  *MicrocodePatchRegionSize = PcdGet64(PcdCpuMicrocodePatchRegionSize);
+
+  if ((*MicrocodePatchAddress == 0) || (*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();
+}
+
+/**
+  Get current Microcode information.
+
+  @param[out]  ImageDescriptor  Microcode ImageDescriptor
+  @param[in]   DescriptorCount  The count of Microcode ImageDescriptor allocated.
+
+  @return Microcode count
+**/
+UINTN
+GetMicrocodeInfo (
+  OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR  *ImageDescriptor, OPTIONAL
+  IN  UINTN                          DescriptorCount   OPTIONAL
+  )
+{
+  BOOLEAN                                 Result;
+  UINT64                                  MicrocodePatchAddress;
+  UINT64                                  MicrocodePatchRegionSize;
+  CPU_MICROCODE_HEADER                    *MicrocodeEntryPoint;
+  UINTN                                   MicrocodeEnd;
+  UINTN                                   TotalSize;
+  UINTN                                   Count;
+  UINT64                                  ImageAttributes;
+  UINT32                                  CurrentRevision;
+
+  Result = GetMicrocodeRegion(&MicrocodePatchAddress, &MicrocodePatchRegionSize);
+  if (!Result) {
+    DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n"));
+    return 0;
+  }
+  DEBUG((DEBUG_INFO, "Microcode Region - 0x%lx - 0x%lx\n", MicrocodePatchAddress, MicrocodePatchRegionSize));
+
+  Count = 0;
+  CurrentRevision = GetCurrentMicrocodeSignature();
+
+  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;
+      }
+
+      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 (CurrentRevision == MicrocodeEntryPoint->UpdateRevision) {
+          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;
+      }
+    } 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;
+}
+
+/**
+  Read Microcode.
+
+  @param[in]       ImageIndex The index of Microcode image.
+  @param[in, out]  Image      The Microcode image buffer.
+  @param[in, out]  ImageSize  The size of Microcode image buffer in bytes.
+
+  @retval EFI_SUCCESS    The Microcode image is read.
+  @retval EFI_NOT_FOUND  The Microcode image is not found.
+**/
+EFI_STATUS
+MicrocodeRead (
+  IN UINTN      ImageIndex,
+  IN OUT VOID   *Image,
+  IN OUT UINTN  *ImageSize
+  )
+{
+  BOOLEAN                                 Result;
+  UINT64                                  MicrocodePatchAddress;
+  UINT64                                  MicrocodePatchRegionSize;
+  CPU_MICROCODE_HEADER                    *MicrocodeEntryPoint;
+  UINTN                                   MicrocodeEnd;
+  UINTN                                   TotalSize;
+  UINTN                                   Count;
+
+  Result = GetMicrocodeRegion(&MicrocodePatchAddress, &MicrocodePatchRegionSize);
+  if (!Result) {
+    DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n"));
+    return EFI_NOT_FOUND;
+  }
+  DEBUG((DEBUG_INFO, "Microcode Region - 0x%lx - 0x%lx\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;
+      }
+
+    } 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 EFI_NOT_FOUND;
+}
+
+/**
+  Verify Microcode.
+
+  Caution: This function may receive untrusted input.
+
+  @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().
+
+  @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 VOID    *Image,
+  IN UINTN   ImageSize,
+  IN BOOLEAN TryLoad,
+  OUT UINT32 *LastAttemptStatus,
+  OUT CHAR16 **AbortReason
+  )
+{
+  UINTN                                   Index;
+  CPU_MICROCODE_HEADER                    *MicrocodeEntryPoint;
+  UINTN                                   TotalSize;
+  UINTN                                   DataSize;
+  UINT32                                  CurrentRevision;
+  UINT32                                  CurrentProcessorSignature;
+  UINT8                                   CurrentPlatformId;
+  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
+  //
+  CorrectMicrocode = FALSE;
+  CurrentProcessorSignature = GetCurrentProcessorSignature();
+  CurrentPlatformId = GetCurrentPlatformId();
+  if ((MicrocodeEntryPoint->ProcessorSignature.Uint32 != CurrentProcessorSignature) ||
+      ((MicrocodeEntryPoint->ProcessorFlags & (1 << CurrentPlatformId)) == 0)) {
+    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
+                //
+                if ((ExtendedTable->ProcessorSignature.Uint32 == CurrentProcessorSignature) &&
+                    (ExtendedTable->ProcessorFlag & (1 << CurrentPlatformId))) {
+                  //
+                  // Find one
+                  //
+                  CorrectMicrocode = TRUE;
+                  break;
+                }
+              }
+              ExtendedTable++;
+            }
+          }
+        }
+      }
+    }
+    if (!CorrectMicrocode) {
+      DEBUG((DEBUG_ERROR, "VerifyMicrocode - fail on CurrentProcessorSignature/ProcessorFlags\n"));
+      *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION;
+      if (AbortReason != NULL) {
+        if (MicrocodeEntryPoint->ProcessorSignature.Uint32 != CurrentProcessorSignature) {
+          *AbortReason = AllocateCopyPool(sizeof(L"UnsupportedProcessSignature"), L"UnsupportedProcessSignature");
+        } else {
+          *AbortReason = AllocateCopyPool(sizeof(L"UnsupportedProcessorFlags"), L"UnsupportedProcessorFlags");
+        }
+      }
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Check UpdateRevision
+  //
+  CurrentRevision = GetCurrentMicrocodeSignature();
+  if (MicrocodeEntryPoint->UpdateRevision < CurrentRevision) {
+    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 = LoadMicrocode((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 current Microcode in used.
+
+  @return current Microcode in used.
+**/
+VOID *
+GetCurrentMicrocodeInUse (
+  VOID
+  )
+{
+  BOOLEAN                                 Result;
+  EFI_STATUS                              Status;
+  UINT64                                  MicrocodePatchAddress;
+  UINT64                                  MicrocodePatchRegionSize;
+  CPU_MICROCODE_HEADER                    *MicrocodeEntryPoint;
+  UINTN                                   MicrocodeEnd;
+  UINTN                                   TotalSize;
+  UINTN                                   Count;
+  UINT32                                  AttemptStatus;
+
+  Result = GetMicrocodeRegion(&MicrocodePatchAddress, &MicrocodePatchRegionSize);
+  if (!Result) {
+    DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n"));
+    return NULL;
+  }
+  DEBUG((DEBUG_INFO, "Microcode Region - 0x%lx - 0x%lx\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;
+      }
+      Status = VerifyMicrocode(MicrocodeEntryPoint, TotalSize, FALSE, &AttemptStatus, NULL);
+      if (!EFI_ERROR(Status)) {
+        return MicrocodeEntryPoint;
+      }
+
+    } 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 NULL;
+}
+
+/**
+  Get current Microcode used region size.
+
+  @return current Microcode used region size.
+**/
+UINTN
+GetCurrentMicrocodeUsedRegionSize (
+  VOID
+  )
+{
+  BOOLEAN                                 Result;
+  UINT64                                  MicrocodePatchAddress;
+  UINT64                                  MicrocodePatchRegionSize;
+  CPU_MICROCODE_HEADER                    *MicrocodeEntryPoint;
+  UINTN                                   MicrocodeEnd;
+  UINTN                                   TotalSize;
+  UINTN                                   Count;
+  UINTN                                   MicrocodeUsedEnd;
+
+  Result = GetMicrocodeRegion(&MicrocodePatchAddress, &MicrocodePatchRegionSize);
+  if (!Result) {
+    DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n"));
+    return 0;
+  }
+  DEBUG((DEBUG_INFO, "Microcode Region - 0x%lx - 0x%lx\n", MicrocodePatchAddress, MicrocodePatchRegionSize));
+
+  MicrocodeUsedEnd = (UINTN)MicrocodePatchAddress;
+  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;
+      }
+
+    } 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);
+    MicrocodeUsedEnd = (UINTN)MicrocodeEntryPoint;
+
+    //
+    // Get the next patch.
+    //
+    MicrocodeEntryPoint = (CPU_MICROCODE_HEADER *)(((UINTN)MicrocodeEntryPoint) + TotalSize);
+  } while (((UINTN)MicrocodeEntryPoint < MicrocodeEnd));
+
+  return MicrocodeUsedEnd - (UINTN)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;
+}
+
+/**
+  Write Microcode.
+
+  Caution: This function may receive untrusted input.
+
+  @param[in]   ImageIndex         The index of Microcode image.
+  @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  UINTN   ImageIndex,
+  IN  VOID    *Image,
+  IN  UINTN   ImageSize,
+  OUT UINT32  *LastAttemptVersion,
+  OUT UINT32  *LastAttemptStatus,
+  OUT CHAR16  **AbortReason
+  )
+{
+  BOOLEAN                                 Result;
+  EFI_STATUS                              Status;
+  UINT64                                  MicrocodePatchAddress;
+  UINT64                                  MicrocodePatchRegionSize;
+  CPU_MICROCODE_HEADER                    *CurrentMicrocodeEntryPoint;
+  UINTN                                   CurrentTotalSize;
+  UINTN                                   UsedRegionSize;
+  VOID                                    *AlignedImage;
+
+  Result = GetMicrocodeRegion(&MicrocodePatchAddress, &MicrocodePatchRegionSize);
+  if (!Result) {
+    DEBUG((DEBUG_ERROR, "Fail to get Microcode Region\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  CurrentTotalSize = 0;
+  CurrentMicrocodeEntryPoint = GetCurrentMicrocodeInUse();
+  if (CurrentMicrocodeEntryPoint != NULL) {
+    if (CurrentMicrocodeEntryPoint->DataSize == 0) {
+      CurrentTotalSize = 2048;
+    } else {
+      CurrentTotalSize = CurrentMicrocodeEntryPoint->TotalSize;
+    }
+  }
+
+  //
+  // MCU must be 16 bytes aligned
+  //
+  AlignedImage = AllocateCopyPool(ImageSize, Image);
+
+  *LastAttemptVersion = ((CPU_MICROCODE_HEADER *)Image)->UpdateRevision;
+  Status = VerifyMicrocode(AlignedImage, ImageSize, TRUE, LastAttemptStatus, AbortReason);
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "Fail to verify Microcode Region\n"));
+    FreePool(AlignedImage);
+    return Status;
+  }
+  DEBUG((DEBUG_INFO, "Pass VerifyMicrocode\n"));
+
+  if (CurrentTotalSize < ImageSize) {
+    UsedRegionSize = GetCurrentMicrocodeUsedRegionSize();
+    if (MicrocodePatchRegionSize - UsedRegionSize >= ImageSize) {
+      //
+      // Append
+      //
+      DEBUG((DEBUG_INFO, "Append new microcode\n"));
+      Status = UpdateMicrocode(MicrocodePatchAddress + UsedRegionSize, AlignedImage, ImageSize, LastAttemptStatus);
+    } else if (MicrocodePatchRegionSize >= ImageSize) {
+      //
+      // Ignor all others and just add this one from beginning.
+      //
+      DEBUG((DEBUG_INFO, "Add new microcode from beginning\n"));
+      Status = UpdateMicrocode(MicrocodePatchAddress, AlignedImage, ImageSize, LastAttemptStatus);
+    } else {
+      DEBUG((DEBUG_ERROR, "Microcode too big\n"));
+      *LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES;
+      Status = EFI_OUT_OF_RESOURCES;
+    }
+  } else {
+    //
+    // Replace
+    //
+    DEBUG((DEBUG_INFO, "Replace old microcode\n"));
+    Status = UpdateMicrocode((UINTN)CurrentMicrocodeEntryPoint, AlignedImage, ImageSize, LastAttemptStatus);
+  }
+
+  FreePool(AlignedImage);
+
+  return Status;
+}
+
+
diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h
new file mode 100644
index 0000000..77e8441
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdate.h
@@ -0,0 +1,403 @@
+/** @file
+  Microcode update header file.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  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 <PiDxe.h>
+
+#include <Guid/SystemResourceTable.h>
+#include <Guid/MicrocodeFmp.h>
+
+#include <Protocol/FirmwareManagement.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HobLib.h>
+#include <Library/MicrocodeFlashAccessLib.h>
+
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+#include <Register/Microcode.h>
+
+#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;
+
+struct _MICROCODE_FMP_PRIVATE_DATA {
+  UINT32                               Signature;
+  EFI_FIRMWARE_MANAGEMENT_PROTOCOL     Fmp;
+  EFI_HANDLE                           Handle;
+  UINT8                                DescriptorCount;
+  EFI_FIRMWARE_IMAGE_DESCRIPTOR        *ImageDescriptor;
+  UINT32                               PackageVersion;
+  CHAR16                               *PackageVersionName;
+  MICROCODE_FMP_LAST_ATTEMPT_VARIABLE  LastAttempt;
+};
+
+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 current Microcode information.
+
+  @param[out]  ImageDescriptor  Microcode ImageDescriptor
+  @param[in]   DescriptorCount  The count of Microcode ImageDescriptor allocated.
+
+  @return Microcode count
+**/
+UINTN
+GetMicrocodeInfo (
+  OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR  *ImageDescriptor, OPTIONAL
+  IN  UINTN                          DescriptorCount   OPTIONAL
+  );
+
+/**
+  Read Microcode.
+
+  @param[in]       ImageIndex The index of Microcode image.
+  @param[in, out]  Image      The Microcode image buffer.
+  @param[in, out]  ImageSize  The size of Microcode image buffer in bytes.
+
+  @retval EFI_SUCCESS    The Microcode image is read.
+  @retval EFI_NOT_FOUND  The Microcode image is not found.
+**/
+EFI_STATUS
+MicrocodeRead (
+  IN UINTN      ImageIndex,
+  IN OUT VOID   *Image,
+  IN OUT UINTN  *ImageSize
+  );
+
+/**
+  Write Microcode.
+
+  @param[in]   ImageIndex         The index of Microcode image.
+  @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 UINTN    ImageIndex,
+  IN VOID     *Image,
+  IN UINTN    ImageSize,
+  OUT UINT32  *LastAttemptVersion,
+  OUT UINT32  *LastAttemptStatus,
+  OUT CHAR16  **AbortReason
+  );
+
+/**
+  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
new file mode 100644
index 0000000..437d300
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf
@@ -0,0 +1,68 @@
+## @file
+# Microcode FMP update driver.
+#
+# Produce FMP instance to update Microcode.
+#
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#  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]
+  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
+
+[Protocols]
+  gEfiFirmwareManagementProtocolGuid            ## SOMTIMES_PRODUCE
+
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress            ## CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize         ## CONSUMES
+
+[Depex]
+  gEfiVariableArchProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  MicrocodeUpdateDxeExtra.uni
+
diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.uni
new file mode 100644
index 0000000..1b0d494
--- /dev/null
+++ b/UefiCpuPkg/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.<BR>
+//
+// 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
new file mode 100644
index 0000000..b667f12
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxeExtra.uni
@@ -0,0 +1,20 @@
+// /** @file
+// MicrocodeUpdateDxe Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// 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"
+
+
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V8 6/7] UefiCpuPkg/MicrocodeUpdate: Add Microcode FMP build sample
  2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
                   ` (4 preceding siblings ...)
  2016-11-02 14:07 ` [PATCH V8 5/7] UefiCpuPkg/MicrocodeUpdate: Add MicrocodeUpdate component Jiewen Yao
@ 2016-11-02 14:07 ` Jiewen Yao
  2016-11-02 14:07 ` [PATCH V8 7/7] UefiCpuPkg/UefiCpuPkg.dsc: Add MicrocodeCapsule related component Jiewen Yao
  6 siblings, 0 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Jeff Fan, Feng Tian, Star Zeng, Michael D Kinney, Liming Gao,
	Chao Zhang

This folder provides the sample build for Microcode FMP.
The DSC/FDF is to convert the Microcode binary/text to Microcode FMP.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
---
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc | 32 +++++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf | 32 +++++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/Readme.md               | 20 +++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Microcode/Microcode.inf | 27 ++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc | 38 ++++++++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf | 32 +++++++++++++++++
 UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/Readme.md               | 33 +++++++++++++++++
 7 files changed, 214 insertions(+)

diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc
new file mode 100644
index 0000000..b8ab08d
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.dsc
@@ -0,0 +1,32 @@
+## @file
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+#    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                  = <PlatformPkg>
+  PLATFORM_GUID                  = 6875FD33-602E-4EF9-9DF2-8BA7D8B7A7AF
+  PLATFORM_VERSION               = 0.1
+#
+# Uncomment the following line and update with your platform pkg name
+#
+#  FLASH_DEFINITION               = <PlatformPkg>/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf
+#
+# Uncomment the following line and update with your platform pkg name
+#
+#  OUTPUT_DIRECTORY               = Build/<PlatformPkg>
+  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
new file mode 100644
index 0000000..f171604
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf
@@ -0,0 +1,32 @@
+## @file
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+#    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)/<PlatformPkg>/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
new file mode 100644
index 0000000..9f81373
--- /dev/null
+++ b/UefiCpuPkg/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 `<Your Platform Package>/MicrocodeUpdatePdb`.
+
+2) Uncomment and update `FILE DATA` statement in `<Your Platform Package>/MicrocodeUpdatePdb/MicrocodeCapsulePdb.fdf` with path to a Microcode PDB file.  The PDB file can placed in `<Your Platform Package>/MicrocodeUpdatePdb` or any other path.
+
+`FILE DATA = <your Microcode PDB file path>`
+
+Uncomment and update `PLATFORM_NAME`, `FLASH_DEFINITION`, `OUTPUT_DIRECTORY` section in `<Your Platform Package>/MicrocodeUpdatePdb/MicrocodeCapsulePdb.dsc` with <Your Platform Package>.
+
+    PLATFORM_NAME                  = <Your Platform Package>
+    FLASH_DEFINITION               = <Your Platform Package>/MicrocodeCapsulePdb/MicrocodeCapsulePdb.fdf
+    OUTPUT_DIRECTORY               = Build/<Your Platform Package>
+
+3) Use EDK II build tools to generate the Microcode FMP Capsule
+
+`build -p <Your Platform Package>/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
new file mode 100644
index 0000000..81af841
--- /dev/null
+++ b/UefiCpuPkg/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.<BR>
+#  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
new file mode 100644
index 0000000..9b7e026
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc
@@ -0,0 +1,38 @@
+## @file
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+#    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                  = <PlatformPkg>
+  PLATFORM_GUID                  = 6875FD33-602E-4EF9-9DF2-8BA7D8B7A7AF
+  PLATFORM_VERSION               = 0.1
+#
+# Uncomment the following line and update with your platform pkg name
+#
+#  FLASH_DEFINITION               = <PlatformPkg>/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf
+#
+# Uncomment the following line and update with your platform pkg name
+#
+#  OUTPUT_DIRECTORY               = Build/<PlatformPkg>
+  SUPPORTED_ARCHITECTURES        = IA32|X64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+
+[Components]
+#
+# Uncomment the following line and update with path to Microcode INF file
+#
+#  <PlatformPkg>/MicrocodeCapsuleTxt/Microcode/Microcode.inf
diff --git a/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf
new file mode 100644
index 0000000..113693b
--- /dev/null
+++ b/UefiCpuPkg/Feature/Capsule/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf
@@ -0,0 +1,32 @@
+## @file
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+#    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
new file mode 100644
index 0000000..f7d7040
--- /dev/null
+++ b/UefiCpuPkg/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 `<Your Platform Package>/MicrocodeUpdateTxt`
+
+2) Copy microcode TXT file to`<Your Platform Package>/MicrocodeUpdateTxt/Microcode`
+
+3) Uncomment and update statement in `[Sources]` section of `<Your Platform Package>/MicrocodeUpdateTxt/Microcode/Microcode.inf` with name of Microcode TXT file copied in previous step.
+
+    [Sources]
+    <Your Microcode TXT file>
+
+Uncomment and update `FILE DATA` statement in `<Your Platform Package>/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.fdf` with path to a Microcode MCB file.  The MCB file is placed in `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/IA32/<Your Platform Package>/MicrocodeUpdateTxt/Microcode/Microcode/OUTPUT/`.
+
+`FILE DATA = <your Microcode MCB file path>`
+
+Uncomment and update `PLATFORM_NAME`, `FLASH_DEFINITION`, `OUTPUT_DIRECTORY` section in `<Your Platform Package>/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.dsc` with <Your Platform Package>.
+
+    PLATFORM_NAME                  = <Your Platform Package>
+    FLASH_DEFINITION               = <Your Platform Package>/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.fdf
+    OUTPUT_DIRECTORY               = Build/<Your Platform Package>
+
+Uncomment and update statement in `Components` section of `<Your Platform Package>/MicrocodeUpdateTxt/MicrocodeCapsuleTxt.dsc` with path to a Microcode INF file.
+
+    [Components]
+    <Your Microcode INF file>
+
+4) Use EDK II build tools to generate the Microcode FMP Capsule
+
+`build -p <Your Platform Package>/MicrocodeCapsuleTxt/MicrocodeCapsuleTxt.dsc`
+
+5) The generated Microcode FMP Capsule is found at `$(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/MicrocodeCapsule.Cap`
+
+
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH V8 7/7] UefiCpuPkg/UefiCpuPkg.dsc: Add MicrocodeCapsule related component.
  2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
                   ` (5 preceding siblings ...)
  2016-11-02 14:07 ` [PATCH V8 6/7] UefiCpuPkg/MicrocodeUpdate: Add Microcode FMP build sample Jiewen Yao
@ 2016-11-02 14:07 ` Jiewen Yao
  6 siblings, 0 replies; 8+ messages in thread
From: Jiewen Yao @ 2016-11-02 14:07 UTC (permalink / raw)
  To: edk2-devel
  Cc: Jeff Fan, Feng Tian, Star Zeng, Michael D Kinney, Liming Gao,
	Chao Zhang

Add Microcode capsule related component to check build.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
---
 UefiCpuPkg/UefiCpuPkg.dsc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
index bfe0fbd..624641f 100644
--- a/UefiCpuPkg/UefiCpuPkg.dsc
+++ b/UefiCpuPkg/UefiCpuPkg.dsc
@@ -61,6 +61,7 @@
   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
 
 [LibraryClasses.common.SEC]
   PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf
@@ -131,6 +132,7 @@
   UefiCpuPkg/SecCore/SecCore.inf
   UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+  UefiCpuPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf
 
 [BuildOptions]
   *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
-- 
2.7.4.windows.1



^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-11-02 14:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-02 14:07 [PATCH V8 0/7] Add MicrocodeUpdate support Jiewen Yao
2016-11-02 14:07 ` [PATCH V8 1/7] UefiCpuPkg/Include: Add Microcode FMP definition Jiewen Yao
2016-11-02 14:07 ` [PATCH V8 2/7] UefiCpuPkg/Include: Add MicrocodeFlashAccessLib header Jiewen Yao
2016-11-02 14:07 ` [PATCH V8 3/7] UefiCpuPkg/UefiCpuPkg.dec: Add Microcode capsule related definition Jiewen Yao
2016-11-02 14:07 ` [PATCH V8 4/7] UefiCpuPkg/MicrocodeFlashAccessLib: Add NULL MicrocodeFlashAccessLib Jiewen Yao
2016-11-02 14:07 ` [PATCH V8 5/7] UefiCpuPkg/MicrocodeUpdate: Add MicrocodeUpdate component Jiewen Yao
2016-11-02 14:07 ` [PATCH V8 6/7] UefiCpuPkg/MicrocodeUpdate: Add Microcode FMP build sample Jiewen Yao
2016-11-02 14:07 ` [PATCH V8 7/7] UefiCpuPkg/UefiCpuPkg.dsc: Add MicrocodeCapsule related component Jiewen Yao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox