[edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.

Marvin Häuser posted 1 patch 6 years, 7 months ago
Failed in applying to current master (apply log)
MdePkg/Include/Protocol/LegacySpiController.h    | 265 ++++++++++++++++++
MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
MdePkg/Include/Protocol/SpiConfiguration.h       | 293 ++++++++++++++++++++
MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
MdePkg/Include/Protocol/SpiIo.h                  | 292 +++++++++++++++++++
MdePkg/Include/Protocol/SpiNorFlash.h            | 289 +++++++++++++++++++
MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
MdePkg/MdePkg.dec                                |  31 +++
11 files changed, 1709 insertions(+)
[edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Marvin Häuser 6 years, 7 months ago
This commit adds header files for the SPI protocols introduced in the
UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.

EFI_SPI_TRANSACTION_TYPE assumes an enum with its members ordered the
way they are listed in the specification, as there are no values given
explicitely.
EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in the
specification was meant to be '1'.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
---
 MdePkg/Include/Protocol/LegacySpiController.h    | 265 ++++++++++++++++++
 MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
 MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
 MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
 MdePkg/Include/Protocol/SpiConfiguration.h       | 293 ++++++++++++++++++++
 MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
 MdePkg/Include/Protocol/SpiIo.h                  | 292 +++++++++++++++++++
 MdePkg/Include/Protocol/SpiNorFlash.h            | 289 +++++++++++++++++++
 MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
 MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
 MdePkg/MdePkg.dec                                |  31 +++
 11 files changed, 1709 insertions(+)

diff --git a/MdePkg/Include/Protocol/LegacySpiController.h b/MdePkg/Include/Protocol/LegacySpiController.h
new file mode 100644
index 000000000000..2d36eaefc0ee
--- /dev/null
+++ b/MdePkg/Include/Protocol/LegacySpiController.h
@@ -0,0 +1,265 @@
+/** @file
+  This file defines the Legacy SPI Controller Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
+#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
+
+///
+/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
+///       definition. This definition assumes it was supposed to be '1'.
+///
+/// Global ID for the Legacy SPI Controller Protocol
+///
+#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
+  { 0x39136fc7, 0x1a11, 0x49de,         \
+    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
+
+typedef
+struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
+EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
+
+/**
+  Set the erase block opcode.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The menu table contains SPI transaction opcodes which are accessible after
+  the legacy SPI flash controller's configuration is locked. The board layer
+  specifies the erase block size for the SPI NOR flash part. The SPI NOR flash
+  peripheral driver selects the erase block opcode which matches the erase
+  block size and uses this API to load the opcode into the opcode menu table.
+
+  @param[in] This              Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
+                               structure.
+  @param[in] EraseBlockOpcode  Erase block opcode to be placed into the opcode
+                               menu table.
+
+  @retval EFI_SUCCESS       The opcode menu table was updated
+  @retval EFI_ACCESS_ERROR  The SPI controller is locked
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
+  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
+  IN UINT8                                     EraseBlockOpcode
+  );
+
+/**
+  Set the write status prefix opcode.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The prefix table contains SPI transaction write prefix opcodes which are
+  accessible after the legacy SPI flash controller's configuration is locked.
+  The board layer specifies the write status prefix opcode for the SPI NOR
+  flash part. The SPI NOR flash peripheral driver uses this API to load the
+  opcode into the prefix table.
+
+  @param[in] This               Pointer to an
+                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
+  @param[in] WriteStatusPrefix  Prefix opcode for the write status command.
+
+  @retval EFI_SUCCESS       The prefix table was updated
+  @retval EFI_ACCESS_ERROR  The SPI controller is locked
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
+  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
+  IN UINT8                                     WriteStatusPrefix
+  );
+
+/**
+  Set the BIOS base address.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS base address works with the protect range registers to protect
+  portions of the SPI NOR flash from erase and write operat ions. The BIOS
+  calls this API prior to passing control to the OS loader.
+
+  @param[in] This             Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
+                              structure.
+  @param[in] BiosBaseAddress  The BIOS base address.
+
+  @retval EFI_SUCCESS            The BIOS base address was properly set
+  @retval EFI_ACCESS_ERROR       The SPI controller is locked
+  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater than
+                                 This->Maxi.mumOffset
+  @retval EFI_UNSUPPORTED        The BIOS base address was already set
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS) (
+  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
+  IN UINT32 BiosBaseAddress
+  );
+
+/**
+  Clear the SPI protect range registers.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS uses this routine to set an initial condition on the SPI protect
+  range registers.
+
+  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
+
+  @retval EFI_SUCCESS       The registers were successfully cleared
+  @retval EFI_ACCESS_ERROR  The SPI controller is locked
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT) (
+  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
+  );
+
+/**
+  Determine if the SPI range is protected.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS uses this routine to verify a range in the SPI is protected.
+
+  @param[in] This            Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
+                             structure.
+  @param[in] BiosAddress     Address within a 4 KiB block to start protecting.
+  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
+
+  @retval TRUE   The range is protected
+  @retval FALSE  The range is not protected
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
+  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
+  IN UINT32                                    BiosAddress,
+  IN UINT32                                    BlocksToProtect
+  );
+
+/**
+  Set the next protect range register.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS sets the protect range register to prevent write and erase
+  operations to a portion of the SPI NOR flash device.
+
+  @param[in] This             Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
+                              structure.
+  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
+  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
+
+  @retval EFI_SUCCESS            The register was successfully updated
+  @retval EFI_ACCESS_ERROR       The SPI controller is locked
+  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress, or
+                                 BlocksToProtect * 4 KiB
+                                   > This->MaximumRangeBytes, or
+                                 BiosAddress - This->BiosBaseAddress
+                                   + (BlocksToProtect * 4 KiB)
+                                     > This->MaximumRangeBytes
+  @retval EFI_OUT_OF_RESOURCES  No protect range register available
+  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the BIOS base
+                                address is not set
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
+  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
+  IN UINT32                                    BiosAddress,
+  IN UINT32                                    BlocksToProtect
+  );
+
+/**
+  Lock the SPI controller configuration.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine locks the SPI controller's configuration so that the software
+  is no longer able to update:
+  * Prefix table
+  * Opcode menu
+  * Opcode type table
+  * BIOS base address
+  * Protect range registers
+
+  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
+
+  @retval EFI_SUCCESS          The SPI controller was successfully locked
+  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER) (
+  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
+  );
+
+///
+/// Support the extra features of the legacy SPI flash controller.
+///
+struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
+  ///
+  /// Maximum offset from the BIOS base address that is able to be protected.
+  ///
+  UINT32                                                 MaximumOffset;
+
+  ///
+  /// Maximum number of bytes that can be protected by one range register.
+  ///
+  UINT32                                                 MaximumRangeBytes;
+
+  ///
+  /// The number of registers available for protecting the BIOS.
+  ///
+  UINT32                                                 RangeRegisterCount;
+
+  ///
+  /// Set the erase block opcode.
+  ///
+  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE  EraseBlockOpcode;
+
+  ///
+  /// Set the write status prefix opcode.
+  ///
+  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX WriteStatusPrefix;
+
+  ///
+  /// Set the BIOS base address.
+  ///
+  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS   BiosBaseAddress;
+
+  ///
+  /// Clear the SPI protect range registers.
+  ///
+  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT   ClearSpiProtect;
+
+  ///
+  /// Determine if the SPI range is protected.
+  ///
+  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED  IsRangeProtected;
+
+  ///
+  /// Set the next protect range register.
+  ///
+  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE  ProtectNextRange;
+
+  ///
+  /// Lock the SPI controller configuration.
+  ///
+  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER     LockController;
+};
+
+extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
+
+#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h b/MdePkg/Include/Protocol/LegacySpiFlash.h
new file mode 100644
index 000000000000..faa5f5724af7
--- /dev/null
+++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
@@ -0,0 +1,201 @@
+/** @file
+  This file defines the Legacy SPI Flash Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
+#define __SPI_CONFIGURATION_PROTOCOL_H__
+
+#include <Protocol/SpiNorFlash.h>
+
+///
+/// Global ID for the Legacy SPI Flash Protocol
+///
+#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
+  { 0xf01bed57, 0x04bc, 0x4f3f,             \
+    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
+
+typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL EFI_LEGACY_SPI_FLASH_PROTOCOL;
+
+/**
+  Set the BIOS base address.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS base address works with the protect range registers to protect
+  portions of the SPI NOR flash from erase and write operat ions.
+  The BIOS calls this API prior to passing control to the OS loader.
+
+  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
+                              structure.
+  @param[in] BiosBaseAddress  The BIOS base address.
+
+  @retval EFI_SUCCESS            The BIOS base address was properly set
+  @retval EFI_ACCESS_ERROR       The SPI controller is locked
+  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This->MaximumOffset
+  @retval EFI_UNSUPPORTED        The BIOS base address was already set or not a
+                                 legacy SPI host controller
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
+  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
+  IN UINT32                               BiosBaseAddress
+  );
+
+/**
+  Clear the SPI protect range registers.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS uses this routine to set an initial condition on the SPI protect
+  range registers.
+
+  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data structure.
+
+  @retval EFI_SUCCESS       The registers were successfully cleared
+  @retval EFI_ACCESS_ERROR  The SPI controller is locked
+  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
+  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
+  );
+
+/**
+  Determine if the SPI range is protected.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS uses this routine to verify a range in the SPI is protected.
+
+  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
+                              structure.
+  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
+  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
+
+  @retval TRUE   The range is protected
+  @retval FALSE  The range is not protected
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
+  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
+  IN UINT32                               BiosAddress,
+  IN UINT32                               BlocksToProtect
+  );
+
+/**
+  Set the next protect range register.
+
+  This routine must be called at or below TPL_NOTIFY.
+  The BIOS sets the protect range register to prevent write and erase
+  operations to a portion of the SPI NOR flash device.
+
+  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
+                              structure.
+  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
+  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
+
+  @retval EFI_SUCCESS            The register was successfully updated
+  @retval EFI_ACCESS_ERROR       The SPI controller is locked
+  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress, or
+  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
+                                   > This->MaximumRangeBytes, or
+                                 BiosAddress - This->BiosBaseAddress
+                                   + (BlocksToProtect * 4 KiB)
+                                     > This->MaximumRangeBytes
+  @retval EFI_OUT_OF_RESOURCES   No protect range register available
+  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the BIOS
+                                 base address is not set Not a legacy SPI host
+                                 controller
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE) (
+  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
+  IN UINT32                               BiosAddress,
+  IN UINT32                               BlocksToProtect
+  );
+
+/**
+  Lock the SPI controller configuration.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine locks the SPI controller's configuration so that the software is
+  no longer able to update:
+  * Prefix table
+  * Opcode menu
+  * Opcode type table
+  * BIOS base address
+  * Protect range registers
+
+  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data structure.
+
+  @retval EFI_SUCCESS          The SPI controller was successfully locked
+  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
+  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
+  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
+  );
+
+///
+/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the EFI_SPI_NOR_FLASH_PROTOCOL
+/// with APls to support the legacy SPI flash controller.
+///
+struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
+  ///
+  /// This protocol manipulates the SPI NOR flash parts using a common set of
+  /// commands.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
+
+  //
+  // Legacy flash (SPI host) controller support
+  //
+
+  ///
+  /// Set the BIOS base address.
+  ///
+  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS  BiosBaseAddress;
+
+  ///
+  /// Clear the SPI protect range registers.
+  ///
+  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT  ClearSpiProtect;
+
+  ///
+  /// Determine if the SPI range is protected.
+  ///
+  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED IsRangeProtected;
+
+  ///
+  /// Set the next protect range register.
+  ///
+  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE ProtectNextRange;
+
+  ///
+  /// Lock the SPI controller configuration.
+  ///
+  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER    LockController;
+};
+
+extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
+
+#endif // __SPI_CONFIGURATION_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h b/MdePkg/Include/Protocol/LegacySpiSmmController.h
new file mode 100644
index 000000000000..6d8d557cefff
--- /dev/null
+++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
@@ -0,0 +1,36 @@
+/** @file
+  This file defines the Legacy SPI SMM Controler Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
+#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
+
+#include <Protocol/LegacySpiController.h>
+
+///
+/// Global ID for the Legacy SPI SMM Controller Protocol
+///
+#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
+  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
+    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
+
+typedef
+struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
+EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
+
+extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
+
+#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
new file mode 100644
index 000000000000..a604a22f901f
--- /dev/null
+++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
@@ -0,0 +1,36 @@
+/** @file
+  This file defines the Legacy SPI SMM Flash Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
+#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
+
+#include <Protocol/LegacySpiFlash.h>
+
+///
+/// Global ID for the Legacy SPI SMM Flash Protocol
+///
+#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
+  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
+    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
+
+typedef
+struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
+EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
+
+extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
+
+#endif // __SPI_SMM_FLASH_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h b/MdePkg/Include/Protocol/SpiConfiguration.h
new file mode 100644
index 000000000000..3a602f67d7a6
--- /dev/null
+++ b/MdePkg/Include/Protocol/SpiConfiguration.h
@@ -0,0 +1,293 @@
+/** @file
+  This file defines the SPI Configuration Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
+#define __SPI_CONFIGURATION_PROTOCOL_H__
+
+///
+/// Global ID for the SPI Configuration Protocol
+///
+#define EFI_SPI_CONFIGURATION_GUID  \
+  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
+    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
+
+///
+/// Macros to easily specify frequencies in hertz, kilohertz and megahertz.
+///
+#define Hz(Frequency)   (Frequency)
+#define KHz(Frequency)  (1000 * Hz (Frequency))
+#define MHz(Frequency)  (1000 * KHz (Frequency))
+
+typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
+
+/**
+  Manipulate the chip select for a SPI device.
+
+  This routine must be called at or below TPL_NOTIFY.
+  Update the value of the chip select line for a SPI peripheral.
+  The SPI bus layer calls this routine either in the board layer or in the SPI
+  controller to manipulate the chip select pin at the start and end of a SPI
+  transaction.
+
+  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data structure
+                            describing the SPI peripheral whose chip select pin
+                            is to be manipulated. The routine may access the
+                            ChipSelectParameter field to gain sufficient
+                            context to complete the operation.
+  @param[in] PinValue       The value to be applied to the chip select line of
+                            the SPI peripheral.
+
+  @retval EFI_SUCCESS            The chip select was set successfully
+  @retval EFI_NOT_READY          Support for the chip select is not properly
+                                 initialized
+  @retval EFI_INVALID_PARAMETER  The SpiPeripheral->ChipSelectParameter value
+                                 is invalid
+  
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_CHIP_SELECT) (
+  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
+  IN BOOLEAN                   PinValue
+  );
+
+/**
+  Set up the clock generator to produce the correct clock frequency, phase and
+  polarity for a SPI chip.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine updates the clock generator to generate the correct frequency
+  and polarity for the SPI clock.
+
+  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure from
+                            which the routine can access the ClockParameter,
+                            ClockPhase and ClockPolarity fields. The routine
+                            also has access to the names for the SPI bus and
+                            chip which can be used during debugging.
+  @param[in] ClockHz        Pointer to the requested clock frequency. The clock
+                            generator will choose a supported clock frequency
+                            which is less then or equal to this value.
+                            Specify zero to turn the clock generator off.
+                            The actual clock frequency supported by the clock
+                            generator will be returned.
+
+  @retval EFI_SUCCESS      The clock was set up successfully
+  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
+                           frequency requested by CLockHz
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_SPI_CLOCK) (
+  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
+  IN UINT32                    *ClockHz
+  );
+
+///
+/// The EFI_SPI_PART data structure provides a description of a SPI part which
+/// is independent of the use on the board. This data is available directly
+/// from the part's datasheet and may be provided by the vendor.
+///
+typedef struct _EFI_SPI_PART {
+  ///
+  /// A Unicode string specifying the SPI chip vendor.
+  ///
+  CONST CHAR16 *Vendor;
+  
+  ///
+  /// A Unicode string specifying the SPI chip part number.
+  ///
+  CONST CHAR16 *PartNumber;
+
+  ///
+  /// The minimum SPI bus clock frequency used to access this chip. This value
+  /// may be specified in the chip's datasheet. If not, use the value of zero.
+  ///
+  UINT32       MinClockHz;
+
+  ///
+  /// The maximum SPI bus clock frequency used to access this chip. This value
+  /// is found in the chip's datasheet.
+  ///
+  UINT32       MaxClockHz;
+
+  ///
+  /// Specify the polarity of the chip select pin. This value can be found in
+  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip select
+  ///and FALSE when a zero asserts the chip select.
+  ///
+  BOOLEAN      ChipSelectPolarity;
+} EFI_SPI_PART;
+
+///
+/// The EFI_SPI_BUS data structure provides the connection details between the
+/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which controls that
+/// SPI bus. This data structure also describes the details of how the clock is
+/// generated for that SPI bus. Finally this data structure provides the list
+/// of physical SPI devices which are attached to the SPI bus.
+///
+typedef struct _EFI_SPI_BUS {
+  ///
+  /// A Unicode string describing the SPI bus
+  ///
+  CONST CHAR16                   *FriendlyName;
+
+  ///
+  /// Address of the first EFI_SPI_PERIPHERAL data structure connected to this
+  /// bus. Specify NULL if there are no SPI peripherals connected to this bus.
+  ///
+  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
+
+  ///
+  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which uniquely
+  /// describes the SPI controller.
+  ///
+  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
+
+  ///
+  /// Address of the routine which controls the clock used by the SPI bus for
+  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
+  /// when this value is set to NULL.
+  ///
+  EFI_SPI_CLOCK                  Clock;
+
+  ///
+  /// Address of a data structure containing the additional values which
+  /// describe the necessary control for the clock. When Clock is NULL,
+  /// the declaration for this data structure is provided by the vendor of the
+  /// host's SPI controller driver. When Clock is not NULL, the declaration for
+  /// this data structure is provided by the board layer.
+  ///
+  VOID                           *ClockParameter;
+} EFI_SPI_BUS;
+
+///
+/// The EFI_SPI_PERIPHERAL data structure describes how a specific block of
+/// logic which is connected to the SPI bus. This data structure also selects
+/// which upper level driver is used to manipulate this SPI device.
+/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
+/// peripheral driver.
+///
+struct _EFI_SPI_PERIPHERAL {
+  ///
+  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify NULL if
+  /// the current data structure is the last one on the SPI bus.
+  ///
+  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
+
+  ///
+  /// A unicode string describing the function of the SPI part.
+  ///
+  CONST CHAR16             *FriendlyName;
+
+  ///
+  /// Address of a GUID provided by the vendor of the SPI peripheral driver.
+  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus driver uses
+  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and to
+  /// provide the connection points for the SPI peripheral drivers.
+  /// This reduces the comparison logic in the SPI peripheral driver's
+  /// Supported routine.
+  ///
+  CONST GUID               *SpiPeripheralDriverGuid;
+
+  ///
+  /// The address of an EFI_SPI_PART data structure which describes this chip.
+  ///
+  CONST EFI_SPI_PART       *SpiPart;
+  
+  ///
+  /// The maximum clock frequency is specified in the EFI_SPI_P ART. When this
+  /// this value is non-zero and less than the value in the EFI_SPI_PART then
+  /// this value is used for the maximum clock frequency for the SPI part.
+  ///
+  UINT32                   MaxClockHz;
+
+  ///
+  /// Specify the idle value of the clock as found in the datasheet.
+  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
+  /// clock's idle value is high.
+  ///
+  BOOLEAN                  ClockPolarity;
+
+  ///
+  /// Specify the clock delay after chip select. Specify zero (0) to delay an
+  /// entire clock cycle or one (1) to delay only half a clock cycle.
+  ///
+  BOOLEAN                  ClockPhase;
+
+  ///
+  /// SPI peripheral attributes, select zero or more of:
+  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI peripheral is wired to
+  ///   support a 2-bit data bus
+  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI peripheral is wired to
+  ///   support a 4-bit data bus
+  ///
+  UINT32                   Attributes;
+
+  ///
+  /// Address of a vendor specific data structure containing additional board 
+  /// configuration details related to the SPI chip. The SPI peripheral layer
+  /// uses this data structure when configuring the chip.
+  ///
+  CONST VOID               *ConfigurationData;
+
+  ///
+  /// The address of an EFI_SPI_BUS data structure which describes the SPI bus
+  /// to which this chip is connected.
+  ///
+  CONST EFI_SPI_BUS        *SpiBus;
+
+  ///
+  /// Address of the routine which controls the chip select pin for this SPI
+  /// peripheral. Call the SPI host controller's chip select routine when this
+  /// value is set to NULL.
+  ///
+  EFI_SPI_CHIP_SELECT      ChipSelect;
+
+  ///
+  /// Address of a data structure containing the additional values which
+  /// describe the necessary control for the chip select. When ChipSelect is
+  /// NULL, the declaration for this data structure is provided by the vendor
+  /// of the host's SPI controller driver. The vendor's documentation specifies
+  /// the necessary values to use for the chip select pin selection and
+  /// control. When Chipselect is not NULL, the declaration for this data
+  /// structure is provided by the board layer.
+  ///
+  VOID                     *ChipSelectParameter;
+};
+
+///
+/// Describe the details of the board's SPI busses to the SPI driver stack.
+/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to expose the data
+/// tables which describe the board's SPI busses, The SPI bus layer uses these
+/// tables to configure the clock, chip select and manage the SPI transactions
+/// on the SPI controllers.
+///
+typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
+  ///
+  /// The number of SPI busses on the board.
+  ///
+  UINT32                          BusCount;
+
+  ///
+  /// The address of an array of EFI_SPI_BUS data structure addresses.
+  ///
+  CONST EFI_SPI_BUS *CONST *CONST Buslist;
+} EFI_SPI_CONFIGURATION_PROTOCOL;
+
+extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
+
+#endif // __SPI_CONFIGURATION_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/SpiHc.h b/MdePkg/Include/Protocol/SpiHc.h
new file mode 100644
index 000000000000..13ad5f45225c
--- /dev/null
+++ b/MdePkg/Include/Protocol/SpiHc.h
@@ -0,0 +1,194 @@
+/** @file
+  This file defines the SPI Host Controller Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __SPI_HC_PROTOCOL_H__
+#define __SPI_HC_PROTOCOL_H__
+
+#include <Protocol/SpiConfiguration.h>
+#include <Protocol/SpiIo.h>
+
+///
+/// Global ID for the SPI Host Controller Protocol
+///
+#define EFI_SPI_HOST_GUID  \
+  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
+    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
+
+///
+/// EDK2-style name
+///
+#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
+
+typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
+
+/**
+  Assert or deassert the SPI chip select.
+
+  This routine is called at TPL_NOTIFY.
+  Update the value of the chip select line for a SPI peripheral. The SPI bus
+  layer calls this routine either in the board layer or in the SPI controller
+  to manipulate the chip select pin at the start and end of a SPI transaction.
+
+  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
+  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data structure
+                            describing the SPI peripheral whose chip select pin
+                            is to be manipulated. The routine may access the
+                            ChipSelectParameter field to gain sufficient
+                            context to complete the operati on.
+  @param[in] PinValue       The value to be applied to the chip select line of
+                            the SPI peripheral.
+
+  @retval EFI_SUCCESS            The chip select was set as requested
+  @retval EFI_NOT_READY          Support for the chip select is not properly
+                                 initialized
+  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its contents are
+                                 invalid
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
+  IN CONST EFI_SPI_HC_PROTOCOL  *This,
+  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
+  IN BOOLEAN                    PinValue
+  );
+
+/**
+  Set up the clock generator to produce the correct clock frequency, phase and
+  polarity for a SPI chip.
+
+  This routine is called at TPL_NOTIFY.
+  This routine updates the clock generator to generate the correct frequency
+  and polarity for the SPI clock.
+
+  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
+  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure from
+                            which the routine can access the ClockParameter,
+                            ClockPhase and ClockPolarity fields. The routine
+                            also has access to the names for the SPI bus and
+                            chip which can be used during debugging.
+  @param[in] ClockHz        Pointer to the requested clock frequency. The SPI
+                            host controller will choose a supported clock
+                            frequency which is less then or equal to this
+                            value. Specify zero to turn the clock generator
+                            off. The actual clock frequency supported by the
+                            SPI host controller will be returned.
+
+  @retval EFI_SUCCESS      The clock was set up successfully
+  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
+                           frequency requested by ClockHz
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
+  IN CONST EFI_SPI_HC_PROTOCOL  *This,
+  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
+  IN UINT32                      *ClockHz
+  );
+
+/**
+  Perform the SPI transaction on the SPI peripheral using the SPI host
+  controller.
+
+  This routine is called at TPL_NOTIFY.
+  This routine synchronously returns EFI_SUCCESS indicating that the
+  asynchronous SPI transaction was started. The routine then waits for
+  completion of the SPI transaction prior to returning the final transaction
+  status.
+
+  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
+  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION containing
+                             the description of the SPI transaction to perform.
+
+  @retval EFI_SUCCESS          The transaction completed successfully
+  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value is invalid,
+                               or the BusTransaction->ReadinBytes value is
+                               invalid
+  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type is
+                               unsupported
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
+  IN CONST EFI_SPI_HC_PROTOCOL  *This,
+  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
+  );
+
+///
+/// Support a SPI data transaction between the SPI controller and a SPI chip.
+///
+struct _EFI_SPI_HC_PROTOCOL {
+  ///
+  /// Host control attributes, may have zero or more of the following set:
+  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
+  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
+  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
+  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
+  ///   - The SPI host controller requires the transmit frame to be in most
+  ///     significant bits instead of least significant bits.The host driver
+  ///     will adjust the frames if necessary.
+  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
+  ///   - The SPI host controller places the receive frame to be in most
+  ///     significant bits instead of least significant bits.The host driver
+  ///     will adjust the frames to be in the least significant bits if
+  ///     necessary.
+  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
+  ///   - The SPI controller supports a 2 - bit data bus
+  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
+  ///   - The SPI controller supports a 4 - bit data bus
+  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
+  ///   - Transfer size includes the opcode byte
+  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
+  ///   - Transfer size includes the 3 address bytes
+  /// The SPI host controller must support full - duplex (receive while
+  /// sending) operation.The SPI host controller must support a 1 - bit bus
+  /// width.
+  ///
+  UINT32                          Attributes;
+
+  ///
+  /// Mask of frame sizes which the SPI host controller supports. Frame size of
+  /// N-bits is supported when bit N-1 is set. The host controller must support
+  /// a frame size of 8-bits.
+  ///
+  UINT32                          FrameSizeSupportMask;
+
+  ///
+  /// Maximum transfer size in bytes: 1 - Oxffffffff
+  ///
+  UINT32                          MaximumTransferBytes;
+
+  ///
+  /// Assert or deassert the SPI chip select.
+  ///
+  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
+
+  ///
+  /// Set up the clock generator to produce the correct clock frequency, phase
+  /// and polarity for a SPI chip.
+  ///
+  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
+
+  ///
+  /// Perform the SPI transaction on the SPI peripheral using the SPI host
+  /// controller.
+  ///
+  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
+};
+
+extern EFI_GUID gEfiSpiHcProtocolGuid;
+
+#endif // __SPI_HC_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/SpiIo.h b/MdePkg/Include/Protocol/SpiIo.h
new file mode 100644
index 000000000000..e481779acc58
--- /dev/null
+++ b/MdePkg/Include/Protocol/SpiIo.h
@@ -0,0 +1,292 @@
+/** @file
+  This file defines the SPI I/O Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __SPI_IO_PROTOCOL_H__
+#define __SPI_IO_PROTOCOL_H__
+
+#include <Protocol/LegacySpiController.h>
+#include <Protocol/SpiConfiguration.h>
+
+typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
+
+///
+/// Note: The UEFI PI 1.6 specification does not specify values for the
+///       members below. The order matches the specification.
+///
+typedef enum {
+  ///
+  /// Data flowing in both direction between the host and
+  /// SPI peripheral.ReadBytes must equal WriteBytes and both ReadBuffer and
+  /// WriteBuffer must be provided.
+  ///
+  SPI_TRANSACTION_FULL_DUPLEX,
+
+  ///
+  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
+  /// zero.WriteBytes must be non - zero and WriteBuffer must be provided.
+  ///
+  SPI_TRANSACTION_WRITE_ONLY,
+
+  ///
+  /// Data flowing from the SPI peripheral to the host.WriteBytes must be
+  /// zero.ReadBytes must be non - zero and ReadBuffer must be provided.
+  ///
+  SPI_TRANSACTION_READ_ONLY,
+
+  ///
+  /// Data first flowing from the host to the SPI peripheral and then data
+  /// flows from the SPI peripheral to the host.These types of operations get
+  /// used for SPI flash devices when control data (opcode, address) must be
+  /// passed to the SPI peripheral to specify the data to be read.
+  ///
+  SPI_TRANSACTION_WRITE_THEN_READ
+} EFI_SPI_TRANSACTION_TYPE;
+
+/**
+  Initiate a SPI transaction between the host and a SPI peripheral.
+  
+  This routine must be called at or below TPL_NOTIFY.
+  This routine works with the SPI bus layer to pass the SPI transaction to the
+  SPI controller for execution on the SPI bus. There are four types of
+  supported transactions supported by this routine:
+  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
+  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes = 0
+  * Read Only: ReadBuffer to receive data from SPI peripheral, WriteBytes = 0
+  * Write Then Read: WriteBuffer contains control data to write to SPI
+                     peripheral before data is placed into the ReadBuffer.
+                     Both WriteBytes and ReadBytes must be non-zero.
+
+  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
+  @param[in]  TransactionType   Type of SPI transaction.
+  @param[in]  DebugTransaction  Set TRUE only when debugging is desired.
+                                Debugging may be turned on for a single SPI
+                                transaction. Only this transaction will display
+                                debugging messages. All other transactions with
+                                this value set to FALSE will not display any
+                                debugging messages.
+  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
+                                the maximum clock frequency supported by the
+                                SPI controller and part. Specify a non-zero
+                                value only when a specific SPI transaction
+                                requires a reduced clock rate.
+  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
+  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
+  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
+                                Specify zero for read-only operations.
+  @param[in]  WriteBuffer       The buffer containing data to be sent from the
+                                host to the SPI chip. Specify NULL for read
+                                only operations.
+                                * Frame sizes 1-8 bits: UINT8 (one byte) per
+                                  frame
+                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
+                                  frame
+                                * Frame sizes 17-32 bits: UINT32 (four bytes)
+                                  per frame The transmit frame is in the least
+                                  significant N bits.
+  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
+                                Specify zero for write-only operations.
+  @param[out] ReadBuffer        The buffer to receeive data from the SPI chip
+                                during the transaction. Specify NULL for write
+                                only operations.
+                                * Frame sizes 1-8 bits: UINT8 (one byte) per
+                                  frame
+                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
+                                  frame
+                                * Frame sizes 17-32 bits: UINT32 (four bytes)
+                                  per frame The received frame is in the least
+                                  significant N bits.
+
+  @retval EFI_SUCCESS            The SPI transaction completed successfully
+  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
+  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
+  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
+                                 or BusWidth not supported by SPI peripheral or
+                                 SPI host controller,
+                                 or WriteBytes non-zero and WriteBuffer is
+                                 NULL,
+                                 or ReadBytes non-zero and ReadBuffer is NULL,
+                                 or ReadBuffer != WriteBuffer for full-duplex
+                                 type,
+                                 or WriteBuffer was NULL,
+                                 or TPL is too high
+  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI transaction
+  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the SPI bus
+                                 layer or the SPI host controller
+  @retval EFI_UNSUPPORTED        The SPI controller was not able to support
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
+  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
+  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
+  IN  BOOLEAN                    DebugTransaction,
+  IN  UINT32                     ClockHz OPTIONAL,
+  IN  UINT32                     BusWidth,
+  IN  UINT32                     FrameSize,
+  IN  UINT32                     WriteBytes,
+  IN  UINT8                      *WriteBuffer,
+  IN  UINT32                     ReadBytes,
+  OUT UINT8                      *ReadBuffer
+  );
+
+/**
+  Update the SPI peripheral associated with this SPI 10 instance.
+
+  Support socketed SPI parts by allowing the SPI peripheral driver to replace
+  the SPI peripheral after the connection is made. An example use is socketed
+  SPI NOR flash parts, where the size and parameters change depending upon
+  device is in the socket.
+
+  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
+  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL structure.
+
+  @retval EFI_SUCCESS            The SPI peripheral was updated successfully
+  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
+                                 or the SpiPeripheral->SpiBus is NULL,
+                                 or the SpiP eripheral - >SpiBus pointing at
+                                 wrong bus,
+                                 or the SpiP eripheral - >SpiPart is NULL
+
+**/
+typedef EFI_STATUS
+(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
+  IN CONST EFI_SPI_IO_PROTOCOL  *This,
+  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
+  );
+
+///
+/// The EFI_SPI_BUS_ TRANSACTION data structure contains the description of the
+/// SPI transaction to perform on the host controller.
+///
+typedef struct _EFI_SPI_BUS_TRANSACTION {
+  ///
+  /// Pointer to the SPI peripheral being manipulated.
+  ///
+  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
+
+  ///
+  /// Type of transaction specified by one of the EFI_SPI_TRANSACTION_TYPE
+  /// values.
+  ///
+  EFI_SPI_TRANSACTION_TYPE TransactionType;
+
+  ///
+  /// TRUE if the transaction is being debugged. Debugging may be turned on for
+  /// a single SPI transaction. Only this transaction will display debugging
+  /// messages. All other transactions with this value set to FALSE will not
+  /// display any debugging messages.
+  ///
+  BOOLEAN                  DebugTransaction;
+
+  ///
+  /// SPI bus width in bits: 1, 2, 4
+  ///
+  UINT32                   BusWidth;
+
+  ///
+  /// Frame size in bits, range: 1 - 32
+  ///
+  UINT32                   FrameSize;
+
+  ///
+  /// Length of the write buffer in bytes
+  ///
+  UINT32                   WriteBytes;
+
+  ///
+  /// Buffer containing data to send to the SPI peripheral
+  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
+  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
+  ///
+  UINT8                    *WriteBuffer;
+
+  ///
+  /// Length of the read buffer in bytes
+  ///
+  UINT32                   ReadBytes;
+
+  ///
+  /// Buffer to receive the data from the SPI peripheral
+  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
+  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
+  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
+  ///
+  UINT8                    *ReadBuffer;
+} EFI_SPI_BUS_TRANSACTION;
+
+///
+/// Support managed SPI data transactions between the SPI controller and a SPI
+/// chip.
+///
+struct _EFI_SPI_IO_PROTOCOL {
+  ///
+  /// Address of an EFI_SPI_PERIPHERAL data structure associated with this
+  /// protocol instance.
+  ///
+  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
+
+  ///
+  /// Address of the original EFI_SPI_PERIPHERAL data structure associated with
+  /// this protocol instance.
+  ///
+  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
+
+  ///
+  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of N-bits
+  /// is supported when bit N-1 is set. The host controller must support a
+  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted to
+  /// 8-bit frame sizes by the SPI bus layer if the frame size is not supported
+  /// by the SPI host controller.
+  ///
+  UINT32                                    FrameSizeSupportMask;
+
+  ///
+  /// Maximum transfer size in bytes: 1 - Oxffffffff
+  ///
+  UINT32                                    MaximumTransferBytes;
+
+  ///
+  /// Transaction attributes: One or more from:
+  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
+  ///   - The SPI host and peripheral supports a 2-bit data bus
+  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
+  ///   - The SPI host and peripheral supports a 4-bit data bus
+  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
+  ///   - Transfer size includes the opcode byte
+  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
+  ///   - Transfer size includes the 3 address bytes
+  ///
+  UINT32                                    Attributes;
+
+  ///
+  /// Pointer to legacy SPI controller protocol
+  ///
+  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *LegacySpiProtocol;
+
+  ///
+  /// Initiate a SPI transaction between the host and a SPI peripheral.
+  ///
+  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
+
+  ///
+  /// Update the SPI peripheral associated with this SPI 10 instance.
+  ///
+  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL UpdateSpiPeripheral;
+};
+
+#endif // __SPI_IO_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h b/MdePkg/Include/Protocol/SpiNorFlash.h
new file mode 100644
index 000000000000..93d2adaa860e
--- /dev/null
+++ b/MdePkg/Include/Protocol/SpiNorFlash.h
@@ -0,0 +1,289 @@
+/** @file
+  This file defines the SPI NOR Flash Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
+#define __SPI_NOR_FLASH_PROTOCOL_H__
+
+#include <Protocol/SpiConfiguration.h>
+
+///
+/// Global ID for the SPI NOR Flash Protocol
+///
+#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
+  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
+    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
+
+typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL EFI_SPI_NOR_FLASH_PROTOCOL;
+
+/**
+  Read the 3 byte manufacture and device ID from the SPI flash.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine reads the 3 byte manufacture and device ID from the flash part
+  filling the buffer provided.
+
+  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data structure.
+  @param[out] Buffer  Pointer to a 3 byte buffer to receive the manufacture and
+                      device ID.
+
+
+
+  @retval EFI_SUCCESS            The manufacture and device ID was read
+                                 successfully.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL
+  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
+  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
+  OUT UINT8                             *Buffer
+  );
+
+/**
+  Read data from the SPI flash.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine reads data from the SPI part in the buffer provided.
+
+  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
+                             structure.
+  @param[in]  FlashAddress   Address in the flash to start reading
+  @param[in]  LengthInBytes  Read length in bytes
+  @param[out] Buffer         Address of a buffer to receive the data
+
+  @retval EFI_SUCCESS            The data was read successfully.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
+                                 FlashAddress >= This->FlashSize, or
+                                 LengthInBytes > This->FlashSize - FlashAddress
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
+  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
+  IN  UINT32                            FlashAddress,
+  IN  UINT32                            LengthInBytes,
+  OUT UINT8                             *Buffer
+  );
+
+/**
+  Low frequency read data from the SPI flash.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine reads data from the SPI part in the buffer provided.
+
+  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
+                             structure.
+  @param[in]  FlashAddress   Address in the flash to start reading
+  @param[in]  LengthInBytes  Read length in bytes
+  @param[out] Buffer         Address of a buffer to receive the data
+
+  @retval EFI_SUCCESS            The data was read successfully.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
+                                 FlashAddress >= This->FlashSize, or
+                                 LengthInBytes > This->FlashSize - FlashAddress
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
+  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
+  IN  UINT32                            FlashAddress,
+  IN  UINT32                            LengthInBytes,
+  OUT UINT8                             *Buffer
+  );
+
+/**
+  Read the flash status register.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine reads the flash part status register.
+
+  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
+                             structure.
+  @param[in]  LengthInBytes  Number of status bytes to read.
+  @param[out] FlashStatus    Pointer to a buffer to receive the flash status.
+
+  @retval EFI_SUCCESS  The status register was read successfully.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
+  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
+  IN  UINT32                            LengthInBytes,
+  OUT UINT8                             *FlashStatus
+  );
+
+/**
+  Write the flash status register.
+
+  This routine must be called at or below TPL_N OTIFY.
+  This routine writes the flash part status register.
+
+  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
+                            structure.
+  @param[in] LengthInBytes  Number of status bytes to write.
+  @param[in] FlashStatus    Pointer to a buffer containing the new status.
+
+  @retval EFI_SUCCESS           The status write was successful.
+  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
+  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
+  IN UINT32                            LengthInBytes,
+  IN UINT8                             *FlashStatus
+  );
+
+/**
+  Write data to the SPI flash.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine breaks up the write operation as necessary to write the data to
+  the SPI part.
+
+  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
+                            structure.
+  @param[in] FlashAddress   Address in the flash to start writing
+  @param[in] LengthInBytes  Write length in bytes
+  @param[in] Buffer         Address of a buffer containing the data
+
+  @retval EFI_SUCCESS            The data was written successfully.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
+                                 FlashAddress >= This->FlashSize, or
+                                 LengthInBytes > This->FlashSize - FlashAddress
+  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy buffer.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
+  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
+  IN UINT32                            FlashAddress,
+  IN UINT32                            LengthInBytes,
+  IN UINT8                             *Buffer
+  );
+
+/**
+  Efficiently erases one or more 4KiB regions in the SPI flash.
+
+  This routine must be called at or below TPL_NOTIFY.
+  This routine uses a combination of 4 KiB and larger blocks to erase the
+  specified area.
+
+  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
+                           structure.
+  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
+  @param[in] BlockCount    Number of 4 KiB blocks to erase
+
+  @retval EFI_SUCCESS            The erase was completed successfully.
+  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
+                                 BlockCount * 4 KiB
+                                   > This->FlashSize - FlashAddress
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
+  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
+  IN UINT32                            FlashAddress,
+  IN UINT32                            BlockCount
+  );
+
+///
+/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral layer.
+/// This protocol manipulates the SPI NOR flash parts using a common set of
+/// commands. The board layer provides the interconnection and configuration
+/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
+/// configuration data to expose a generic interface which provides the
+/// following APls:
+/// * Read manufacture and device ID
+/// * Read data
+/// * Read data using low frequency
+/// * Read status
+/// * Write data
+/// * Erase 4 KiB blocks
+/// * Erase 32 or 64 KiB blocks
+/// * Write status
+/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set the security
+/// features on the legacy SPI flash controller.
+///
+struct _EFI_SPI_NOR_FLASH_PROTOCOL {
+  ///
+  /// Pointer to an EFI_SPI_PERIPHERAL data structure
+  ///
+  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
+
+  ///
+  /// Flash size in bytes
+  ///
+  UINT32                                  FlashSize;
+
+  ///
+  /// Manufacture and Device ID
+  ///
+  UINT8                                   Deviceid[3];
+
+  ///
+  /// Erase block size in bytes
+  ///
+  UINT32                                  EraseBlockBytes;
+
+  ///
+  /// Read the 3 byte manufacture and device ID from the SPI flash.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
+
+  ///
+  /// Read data from the SPI flash.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
+
+  ///
+  /// Low frequency read data from the SPI flash.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
+
+  ///
+  /// Read the flash status register.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
+
+  ///
+  /// Write the flash status register.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
+
+  ///
+  /// Write data to the SPI flash.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
+
+  ///
+  /// Efficiently erases one or more 4KiB regions in the SPI flash.
+  ///
+  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
+};
+
+extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
+
+#endif // __SPI_NOR_FLASH_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
new file mode 100644
index 000000000000..913d4cbb46aa
--- /dev/null
+++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
@@ -0,0 +1,36 @@
+/** @file
+  This file defines the SPI SMM Configuration Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
+#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
+
+#include <Protocol/SpiConfiguration.h>
+
+///
+/// Global ID for the SPI SMM Configuration Protocol
+///
+#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
+  { 0x995c6eca, 0x171b, 0x45fd,                  \
+    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
+
+typedef
+struct _EFI_SPI_CONFIGURATION_PROTOCOL
+EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
+
+extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
+
+#endif // __SPI_SMM_CONFIGURATION_H__
diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h b/MdePkg/Include/Protocol/SpiSmmHc.h
new file mode 100644
index 000000000000..91d2312b74b4
--- /dev/null
+++ b/MdePkg/Include/Protocol/SpiSmmHc.h
@@ -0,0 +1,36 @@
+/** @file
+  This file defines the SPI SMM Host Controller Protocol.
+
+  Copyright (c) 2017, 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.
+
+  @par Revision Reference:
+    This Protocol was introduced in UEFI PI Specification 1.6.
+
+**/
+
+#ifndef __SPI_SMM_HC_H__
+#define __SPI_SMM_HC_H__
+
+#include <Protocol/SpiHc.h>
+
+///
+/// Global ID for the SPI SMM Host Controller Protocol
+///
+#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
+  { 0xe9f02217, 0x2093, 0x4470,       \
+    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
+
+typedef
+struct _EFI_SPI_HC_PROTOCOL
+EFI_SPI_SMM_HC_PROTOCOL;
+
+extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
+
+#endif // __SPI_SMM_HC_H__
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 1867c54c3bc1..91af6c5c455c 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1246,6 +1246,37 @@ [Protocols]
   gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd, { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
 
   #
+  # Protocols defined in PI 1.6.
+  #
+
+  ## Include/Protocol/LegacySpiController.h
+  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de, { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
+
+  ## Include/Protocol/LegacySpiFlash.h
+  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
+
+  ## Include/Protocol/LegacySpiSmmController.h
+  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0, 0x4c8c, { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
+
+  ## Include/Protocol/LegacySpiSmmFlash.h
+  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0, { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
+
+  ## Include/Protocol/SpiConfiguration.h
+  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
+
+  ## Include/Protocol/SpiHc.h
+  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
+
+  ## Include/Protocol/SpiNorFlash.h
+  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
+
+  ## Include/Protocol/SpiSmmConfiguration.h
+  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b, 0x45fd, { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
+
+  ## Include/Protocol/SpiSmmHc.h
+  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
+
+  #
   # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
   #
 
-- 
2.12.2.windows.2

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Ni, Ruiyu 6 years, 7 months ago
Marvin,
Thank you for your contribution. We will need some time to review the definitions against PI Spec.
If there is a need to post V2, it might be better to separate the header files in different groups.
For example, LegacySpi group, SPI group, SMM SPI group.

Thanks/Ray

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Marvin Häuser
> Sent: Wednesday, September 6, 2017 5:21 PM
> To: edk2-devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Subject: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> This commit adds header files for the SPI protocols introduced in the
> UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.
> 
> EFI_SPI_TRANSACTION_TYPE assumes an enum with its members ordered
> the
> way they are listed in the specification, as there are no values given
> explicitely.
> EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in the
> specification was meant to be '1'.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
> ---
>  MdePkg/Include/Protocol/LegacySpiController.h    | 265
> ++++++++++++++++++
>  MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
>  MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
>  MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
>  MdePkg/Include/Protocol/SpiConfiguration.h       | 293
> ++++++++++++++++++++
>  MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
>  MdePkg/Include/Protocol/SpiIo.h                  | 292 +++++++++++++++++++
>  MdePkg/Include/Protocol/SpiNorFlash.h            | 289
> +++++++++++++++++++
>  MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
>  MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
>  MdePkg/MdePkg.dec                                |  31 +++
>  11 files changed, 1709 insertions(+)
> 
> diff --git a/MdePkg/Include/Protocol/LegacySpiController.h
> b/MdePkg/Include/Protocol/LegacySpiController.h
> new file mode 100644
> index 000000000000..2d36eaefc0ee
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiController.h
> @@ -0,0 +1,265 @@
> +/** @file
> +  This file defines the Legacy SPI Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> +#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> +
> +///
> +/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
> +///       definition. This definition assumes it was supposed to be '1'.
> +///
> +/// Global ID for the Legacy SPI Controller Protocol
> +///
> +#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
> +  { 0x39136fc7, 0x1a11, 0x49de,         \
> +    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
> +
> +/**
> +  Set the erase block opcode.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The menu table contains SPI transaction opcodes which are accessible
> after
> +  the legacy SPI flash controller's configuration is locked. The board layer
> +  specifies the erase block size for the SPI NOR flash part. The SPI NOR flash
> +  peripheral driver selects the erase block opcode which matches the erase
> +  block size and uses this API to load the opcode into the opcode menu table.
> +
> +  @param[in] This              Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                               structure.
> +  @param[in] EraseBlockOpcode  Erase block opcode to be placed into the
> opcode
> +                               menu table.
> +
> +  @retval EFI_SUCCESS       The opcode menu table was updated
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT8                                     EraseBlockOpcode
> +  );
> +
> +/**
> +  Set the write status prefix opcode.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The prefix table contains SPI transaction write prefix opcodes which are
> +  accessible after the legacy SPI flash controller's configuration is locked.
> +  The board layer specifies the write status prefix opcode for the SPI NOR
> +  flash part. The SPI NOR flash peripheral driver uses this API to load the
> +  opcode into the prefix table.
> +
> +  @param[in] This               Pointer to an
> +                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
> +  @param[in] WriteStatusPrefix  Prefix opcode for the write status
> command.
> +
> +  @retval EFI_SUCCESS       The prefix table was updated
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT8                                     WriteStatusPrefix
> +  );
> +
> +/**
> +  Set the BIOS base address.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS base address works with the protect range registers to protect
> +  portions of the SPI NOR flash from erase and write operat ions. The BIOS
> +  calls this API prior to passing control to the OS loader.
> +
> +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                              structure.
> +  @param[in] BiosBaseAddress  The BIOS base address.
> +
> +  @retval EFI_SUCCESS            The BIOS base address was properly set
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater than
> +                                 This->Maxi.mumOffset
> +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS)
> (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32 BiosBaseAddress
> +  );
> +
> +/**
> +  Clear the SPI protect range registers.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to set an initial condition on the SPI protect
> +  range registers.
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> structure.
> +
> +  @retval EFI_SUCCESS       The registers were successfully cleared
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT)
> (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> +  );
> +
> +/**
> +  Determine if the SPI range is protected.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to verify a range in the SPI is protected.
> +
> +  @param[in] This            Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                             structure.
> +  @param[in] BiosAddress     Address within a 4 KiB block to start protecting.
> +  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval TRUE   The range is protected
> +  @retval FALSE  The range is not protected
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32                                    BiosAddress,
> +  IN UINT32                                    BlocksToProtect
> +  );
> +
> +/**
> +  Set the next protect range register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS sets the protect range register to prevent write and erase
> +  operations to a portion of the SPI NOR flash device.
> +
> +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval EFI_SUCCESS            The register was successfully updated
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress,
> or
> +                                 BlocksToProtect * 4 KiB
> +                                   > This->MaximumRangeBytes, or
> +                                 BiosAddress - This->BiosBaseAddress
> +                                   + (BlocksToProtect * 4 KiB)
> +                                     > This->MaximumRangeBytes
> +  @retval EFI_OUT_OF_RESOURCES  No protect range register available
> +  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the
> BIOS base
> +                                address is not set
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32                                    BiosAddress,
> +  IN UINT32                                    BlocksToProtect
> +  );
> +
> +/**
> +  Lock the SPI controller configuration.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine locks the SPI controller's configuration so that the software
> +  is no longer able to update:
> +  * Prefix table
> +  * Opcode menu
> +  * Opcode type table
> +  * BIOS base address
> +  * Protect range registers
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> structure.
> +
> +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> +  );
> +
> +///
> +/// Support the extra features of the legacy SPI flash controller.
> +///
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
> +  ///
> +  /// Maximum offset from the BIOS base address that is able to be
> protected.
> +  ///
> +  UINT32                                                 MaximumOffset;
> +
> +  ///
> +  /// Maximum number of bytes that can be protected by one range register.
> +  ///
> +  UINT32                                                 MaximumRangeBytes;
> +
> +  ///
> +  /// The number of registers available for protecting the BIOS.
> +  ///
> +  UINT32                                                 RangeRegisterCount;
> +
> +  ///
> +  /// Set the erase block opcode.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE
> EraseBlockOpcode;
> +
> +  ///
> +  /// Set the write status prefix opcode.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX
> WriteStatusPrefix;
> +
> +  ///
> +  /// Set the BIOS base address.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS
> BiosBaseAddress;
> +
> +  ///
> +  /// Clear the SPI protect range registers.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT
> ClearSpiProtect;
> +
> +  ///
> +  /// Determine if the SPI range is protected.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED
> IsRangeProtected;
> +
> +  ///
> +  /// Set the next protect range register.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE
> ProtectNextRange;
> +
> +  ///
> +  /// Lock the SPI controller configuration.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER
> LockController;
> +};
> +
> +extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
> +
> +#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h
> b/MdePkg/Include/Protocol/LegacySpiFlash.h
> new file mode 100644
> index 000000000000..faa5f5724af7
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
> @@ -0,0 +1,201 @@
> +/** @file
> +  This file defines the Legacy SPI Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_CONFIGURATION_PROTOCOL_H__
> +
> +#include <Protocol/SpiNorFlash.h>
> +
> +///
> +/// Global ID for the Legacy SPI Flash Protocol
> +///
> +#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
> +  { 0xf01bed57, 0x04bc, 0x4f3f,             \
> +    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> +
> +typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> EFI_LEGACY_SPI_FLASH_PROTOCOL;
> +
> +/**
> +  Set the BIOS base address.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS base address works with the protect range registers to protect
> +  portions of the SPI NOR flash from erase and write operat ions.
> +  The BIOS calls this API prior to passing control to the OS loader.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosBaseAddress  The BIOS base address.
> +
> +  @retval EFI_SUCCESS            The BIOS base address was properly set
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This-
> >MaximumOffset
> +  @retval EFI_UNSUPPORTED        The BIOS base address was already set or
> not a
> +                                 legacy SPI host controller
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosBaseAddress
> +  );
> +
> +/**
> +  Clear the SPI protect range registers.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to set an initial condition on the SPI protect
> +  range registers.
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> structure.
> +
> +  @retval EFI_SUCCESS       The registers were successfully cleared
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> +  );
> +
> +/**
> +  Determine if the SPI range is protected.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to verify a range in the SPI is protected.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval TRUE   The range is protected
> +  @retval FALSE  The range is not protected
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosAddress,
> +  IN UINT32                               BlocksToProtect
> +  );
> +
> +/**
> +  Set the next protect range register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS sets the protect range register to prevent write and erase
> +  operations to a portion of the SPI NOR flash device.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval EFI_SUCCESS            The register was successfully updated
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress,
> or
> +  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
> +                                   > This->MaximumRangeBytes, or
> +                                 BiosAddress - This->BiosBaseAddress
> +                                   + (BlocksToProtect * 4 KiB)
> +                                     > This->MaximumRangeBytes
> +  @retval EFI_OUT_OF_RESOURCES   No protect range register available
> +  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the
> BIOS
> +                                 base address is not set Not a legacy SPI host
> +                                 controller
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosAddress,
> +  IN UINT32                               BlocksToProtect
> +  );
> +
> +/**
> +  Lock the SPI controller configuration.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine locks the SPI controller's configuration so that the software is
> +  no longer able to update:
> +  * Prefix table
> +  * Opcode menu
> +  * Opcode type table
> +  * BIOS base address
> +  * Protect range registers
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> structure.
> +
> +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> +  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> +  );
> +
> +///
> +/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the
> EFI_SPI_NOR_FLASH_PROTOCOL
> +/// with APls to support the legacy SPI flash controller.
> +///
> +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
> +  ///
> +  /// This protocol manipulates the SPI NOR flash parts using a common set
> of
> +  /// commands.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
> +
> +  //
> +  // Legacy flash (SPI host) controller support
> +  //
> +
> +  ///
> +  /// Set the BIOS base address.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS
> BiosBaseAddress;
> +
> +  ///
> +  /// Clear the SPI protect range registers.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT
> ClearSpiProtect;
> +
> +  ///
> +  /// Determine if the SPI range is protected.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED
> IsRangeProtected;
> +
> +  ///
> +  /// Set the next protect range register.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE
> ProtectNextRange;
> +
> +  ///
> +  /// Lock the SPI controller configuration.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER    LockController;
> +};
> +
> +extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
> +
> +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h
> b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> new file mode 100644
> index 000000000000..6d8d557cefff
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the Legacy SPI SMM Controler Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> +#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiController.h>
> +
> +///
> +/// Global ID for the Legacy SPI SMM Controller Protocol
> +///
> +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> +  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> +    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
> +
> +extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
> +
> +#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> new file mode 100644
> index 000000000000..a604a22f901f
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the Legacy SPI SMM Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> +#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiFlash.h>
> +
> +///
> +/// Global ID for the Legacy SPI SMM Flash Protocol
> +///
> +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> +  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
> +    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> +EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
> +
> +extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
> +
> +#endif // __SPI_SMM_FLASH_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h
> b/MdePkg/Include/Protocol/SpiConfiguration.h
> new file mode 100644
> index 000000000000..3a602f67d7a6
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiConfiguration.h
> @@ -0,0 +1,293 @@
> +/** @file
> +  This file defines the SPI Configuration Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_CONFIGURATION_PROTOCOL_H__
> +
> +///
> +/// Global ID for the SPI Configuration Protocol
> +///
> +#define EFI_SPI_CONFIGURATION_GUID  \
> +  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
> +    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> +
> +///
> +/// Macros to easily specify frequencies in hertz, kilohertz and megahertz.
> +///
> +#define Hz(Frequency)   (Frequency)
> +#define KHz(Frequency)  (1000 * Hz (Frequency))
> +#define MHz(Frequency)  (1000 * KHz (Frequency))
> +
> +typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
> +
> +/**
> +  Manipulate the chip select for a SPI device.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  Update the value of the chip select line for a SPI peripheral.
> +  The SPI bus layer calls this routine either in the board layer or in the SPI
> +  controller to manipulate the chip select pin at the start and end of a SPI
> +  transaction.
> +
> +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> structure
> +                            describing the SPI peripheral whose chip select pin
> +                            is to be manipulated. The routine may access the
> +                            ChipSelectParameter field to gain sufficient
> +                            context to complete the operation.
> +  @param[in] PinValue       The value to be applied to the chip select line of
> +                            the SPI peripheral.
> +
> +  @retval EFI_SUCCESS            The chip select was set successfully
> +  @retval EFI_NOT_READY          Support for the chip select is not properly
> +                                 initialized
> +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral-
> >ChipSelectParameter value
> +                                 is invalid
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_CHIP_SELECT) (
> +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> +  IN BOOLEAN                   PinValue
> +  );
> +
> +/**
> +  Set up the clock generator to produce the correct clock frequency, phase
> and
> +  polarity for a SPI chip.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine updates the clock generator to generate the correct
> frequency
> +  and polarity for the SPI clock.
> +
> +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure
> from
> +                            which the routine can access the ClockParameter,
> +                            ClockPhase and ClockPolarity fields. The routine
> +                            also has access to the names for the SPI bus and
> +                            chip which can be used during debugging.
> +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> clock
> +                            generator will choose a supported clock frequency
> +                            which is less then or equal to this value.
> +                            Specify zero to turn the clock generator off.
> +                            The actual clock frequency supported by the clock
> +                            generator will be returned.
> +
> +  @retval EFI_SUCCESS      The clock was set up successfully
> +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
> +                           frequency requested by CLockHz
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_CLOCK) (
> +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> +  IN UINT32                    *ClockHz
> +  );
> +
> +///
> +/// The EFI_SPI_PART data structure provides a description of a SPI part
> which
> +/// is independent of the use on the board. This data is available directly
> +/// from the part's datasheet and may be provided by the vendor.
> +///
> +typedef struct _EFI_SPI_PART {
> +  ///
> +  /// A Unicode string specifying the SPI chip vendor.
> +  ///
> +  CONST CHAR16 *Vendor;
> +
> +  ///
> +  /// A Unicode string specifying the SPI chip part number.
> +  ///
> +  CONST CHAR16 *PartNumber;
> +
> +  ///
> +  /// The minimum SPI bus clock frequency used to access this chip. This
> value
> +  /// may be specified in the chip's datasheet. If not, use the value of zero.
> +  ///
> +  UINT32       MinClockHz;
> +
> +  ///
> +  /// The maximum SPI bus clock frequency used to access this chip. This
> value
> +  /// is found in the chip's datasheet.
> +  ///
> +  UINT32       MaxClockHz;
> +
> +  ///
> +  /// Specify the polarity of the chip select pin. This value can be found in
> +  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip
> select
> +  ///and FALSE when a zero asserts the chip select.
> +  ///
> +  BOOLEAN      ChipSelectPolarity;
> +} EFI_SPI_PART;
> +
> +///
> +/// The EFI_SPI_BUS data structure provides the connection details
> between the
> +/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which controls
> that
> +/// SPI bus. This data structure also describes the details of how the clock is
> +/// generated for that SPI bus. Finally this data structure provides the list
> +/// of physical SPI devices which are attached to the SPI bus.
> +///
> +typedef struct _EFI_SPI_BUS {
> +  ///
> +  /// A Unicode string describing the SPI bus
> +  ///
> +  CONST CHAR16                   *FriendlyName;
> +
> +  ///
> +  /// Address of the first EFI_SPI_PERIPHERAL data structure connected to
> this
> +  /// bus. Specify NULL if there are no SPI peripherals connected to this bus.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
> +
> +  ///
> +  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which
> uniquely
> +  /// describes the SPI controller.
> +  ///
> +  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
> +
> +  ///
> +  /// Address of the routine which controls the clock used by the SPI bus for
> +  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
> +  /// when this value is set to NULL.
> +  ///
> +  EFI_SPI_CLOCK                  Clock;
> +
> +  ///
> +  /// Address of a data structure containing the additional values which
> +  /// describe the necessary control for the clock. When Clock is NULL,
> +  /// the declaration for this data structure is provided by the vendor of the
> +  /// host's SPI controller driver. When Clock is not NULL, the declaration for
> +  /// this data structure is provided by the board layer.
> +  ///
> +  VOID                           *ClockParameter;
> +} EFI_SPI_BUS;
> +
> +///
> +/// The EFI_SPI_PERIPHERAL data structure describes how a specific block
> of
> +/// logic which is connected to the SPI bus. This data structure also selects
> +/// which upper level driver is used to manipulate this SPI device.
> +/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
> +/// peripheral driver.
> +///
> +struct _EFI_SPI_PERIPHERAL {
> +  ///
> +  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify NULL
> if
> +  /// the current data structure is the last one on the SPI bus.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
> +
> +  ///
> +  /// A unicode string describing the function of the SPI part.
> +  ///
> +  CONST CHAR16             *FriendlyName;
> +
> +  ///
> +  /// Address of a GUID provided by the vendor of the SPI peripheral driver.
> +  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus driver
> uses
> +  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and to
> +  /// provide the connection points for the SPI peripheral drivers.
> +  /// This reduces the comparison logic in the SPI peripheral driver's
> +  /// Supported routine.
> +  ///
> +  CONST GUID               *SpiPeripheralDriverGuid;
> +
> +  ///
> +  /// The address of an EFI_SPI_PART data structure which describes this
> chip.
> +  ///
> +  CONST EFI_SPI_PART       *SpiPart;
> +
> +  ///
> +  /// The maximum clock frequency is specified in the EFI_SPI_P ART. When
> this
> +  /// this value is non-zero and less than the value in the EFI_SPI_PART then
> +  /// this value is used for the maximum clock frequency for the SPI part.
> +  ///
> +  UINT32                   MaxClockHz;
> +
> +  ///
> +  /// Specify the idle value of the clock as found in the datasheet.
> +  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
> +  /// clock's idle value is high.
> +  ///
> +  BOOLEAN                  ClockPolarity;
> +
> +  ///
> +  /// Specify the clock delay after chip select. Specify zero (0) to delay an
> +  /// entire clock cycle or one (1) to delay only half a clock cycle.
> +  ///
> +  BOOLEAN                  ClockPhase;
> +
> +  ///
> +  /// SPI peripheral attributes, select zero or more of:
> +  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI
> peripheral is wired to
> +  ///   support a 2-bit data bus
> +  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI
> peripheral is wired to
> +  ///   support a 4-bit data bus
> +  ///
> +  UINT32                   Attributes;
> +
> +  ///
> +  /// Address of a vendor specific data structure containing additional board
> +  /// configuration details related to the SPI chip. The SPI peripheral layer
> +  /// uses this data structure when configuring the chip.
> +  ///
> +  CONST VOID               *ConfigurationData;
> +
> +  ///
> +  /// The address of an EFI_SPI_BUS data structure which describes the SPI
> bus
> +  /// to which this chip is connected.
> +  ///
> +  CONST EFI_SPI_BUS        *SpiBus;
> +
> +  ///
> +  /// Address of the routine which controls the chip select pin for this SPI
> +  /// peripheral. Call the SPI host controller's chip select routine when this
> +  /// value is set to NULL.
> +  ///
> +  EFI_SPI_CHIP_SELECT      ChipSelect;
> +
> +  ///
> +  /// Address of a data structure containing the additional values which
> +  /// describe the necessary control for the chip select. When ChipSelect is
> +  /// NULL, the declaration for this data structure is provided by the vendor
> +  /// of the host's SPI controller driver. The vendor's documentation
> specifies
> +  /// the necessary values to use for the chip select pin selection and
> +  /// control. When Chipselect is not NULL, the declaration for this data
> +  /// structure is provided by the board layer.
> +  ///
> +  VOID                     *ChipSelectParameter;
> +};
> +
> +///
> +/// Describe the details of the board's SPI busses to the SPI driver stack.
> +/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to
> expose the data
> +/// tables which describe the board's SPI busses, The SPI bus layer uses
> these
> +/// tables to configure the clock, chip select and manage the SPI
> transactions
> +/// on the SPI controllers.
> +///
> +typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
> +  ///
> +  /// The number of SPI busses on the board.
> +  ///
> +  UINT32                          BusCount;
> +
> +  ///
> +  /// The address of an array of EFI_SPI_BUS data structure addresses.
> +  ///
> +  CONST EFI_SPI_BUS *CONST *CONST Buslist;
> +} EFI_SPI_CONFIGURATION_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
> +
> +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiHc.h
> b/MdePkg/Include/Protocol/SpiHc.h
> new file mode 100644
> index 000000000000..13ad5f45225c
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiHc.h
> @@ -0,0 +1,194 @@
> +/** @file
> +  This file defines the SPI Host Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_HC_PROTOCOL_H__
> +#define __SPI_HC_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +#include <Protocol/SpiIo.h>
> +
> +///
> +/// Global ID for the SPI Host Controller Protocol
> +///
> +#define EFI_SPI_HOST_GUID  \
> +  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
> +    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> +
> +///
> +/// EDK2-style name
> +///
> +#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
> +
> +typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
> +
> +/**
> +  Assert or deassert the SPI chip select.
> +
> +  This routine is called at TPL_NOTIFY.
> +  Update the value of the chip select line for a SPI peripheral. The SPI bus
> +  layer calls this routine either in the board layer or in the SPI controller
> +  to manipulate the chip select pin at the start and end of a SPI transaction.
> +
> +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> structure
> +                            describing the SPI peripheral whose chip select pin
> +                            is to be manipulated. The routine may access the
> +                            ChipSelectParameter field to gain sufficient
> +                            context to complete the operati on.
> +  @param[in] PinValue       The value to be applied to the chip select line of
> +                            the SPI peripheral.
> +
> +  @retval EFI_SUCCESS            The chip select was set as requested
> +  @retval EFI_NOT_READY          Support for the chip select is not properly
> +                                 initialized
> +  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its contents
> are
> +                                 invalid
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> +  IN BOOLEAN                    PinValue
> +  );
> +
> +/**
> +  Set up the clock generator to produce the correct clock frequency, phase
> and
> +  polarity for a SPI chip.
> +
> +  This routine is called at TPL_NOTIFY.
> +  This routine updates the clock generator to generate the correct
> frequency
> +  and polarity for the SPI clock.
> +
> +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure
> from
> +                            which the routine can access the ClockParameter,
> +                            ClockPhase and ClockPolarity fields. The routine
> +                            also has access to the names for the SPI bus and
> +                            chip which can be used during debugging.
> +  @param[in] ClockHz        Pointer to the requested clock frequency. The SPI
> +                            host controller will choose a supported clock
> +                            frequency which is less then or equal to this
> +                            value. Specify zero to turn the clock generator
> +                            off. The actual clock frequency supported by the
> +                            SPI host controller will be returned.
> +
> +  @retval EFI_SUCCESS      The clock was set up successfully
> +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
> +                           frequency requested by ClockHz
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> +  IN UINT32                      *ClockHz
> +  );
> +
> +/**
> +  Perform the SPI transaction on the SPI peripheral using the SPI host
> +  controller.
> +
> +  This routine is called at TPL_NOTIFY.
> +  This routine synchronously returns EFI_SUCCESS indicating that the
> +  asynchronous SPI transaction was started. The routine then waits for
> +  completion of the SPI transaction prior to returning the final transaction
> +  status.
> +
> +  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION
> containing
> +                             the description of the SPI transaction to perform.
> +
> +  @retval EFI_SUCCESS          The transaction completed successfully
> +  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value is
> invalid,
> +                               or the BusTransaction->ReadinBytes value is
> +                               invalid
> +  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type is
> +                               unsupported
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
> +  );
> +
> +///
> +/// Support a SPI data transaction between the SPI controller and a SPI chip.
> +///
> +struct _EFI_SPI_HC_PROTOCOL {
> +  ///
> +  /// Host control attributes, may have zero or more of the following set:
> +  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> +  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> +  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> +  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> +  ///   - The SPI host controller requires the transmit frame to be in most
> +  ///     significant bits instead of least significant bits.The host driver
> +  ///     will adjust the frames if necessary.
> +  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
> +  ///   - The SPI host controller places the receive frame to be in most
> +  ///     significant bits instead of least significant bits.The host driver
> +  ///     will adjust the frames to be in the least significant bits if
> +  ///     necessary.
> +  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
> +  ///   - The SPI controller supports a 2 - bit data bus
> +  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> +  ///   - The SPI controller supports a 4 - bit data bus
> +  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> +  ///   - Transfer size includes the opcode byte
> +  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> +  ///   - Transfer size includes the 3 address bytes
> +  /// The SPI host controller must support full - duplex (receive while
> +  /// sending) operation.The SPI host controller must support a 1 - bit bus
> +  /// width.
> +  ///
> +  UINT32                          Attributes;
> +
> +  ///
> +  /// Mask of frame sizes which the SPI host controller supports. Frame size
> of
> +  /// N-bits is supported when bit N-1 is set. The host controller must
> support
> +  /// a frame size of 8-bits.
> +  ///
> +  UINT32                          FrameSizeSupportMask;
> +
> +  ///
> +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> +  ///
> +  UINT32                          MaximumTransferBytes;
> +
> +  ///
> +  /// Assert or deassert the SPI chip select.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
> +
> +  ///
> +  /// Set up the clock generator to produce the correct clock frequency,
> phase
> +  /// and polarity for a SPI chip.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
> +
> +  ///
> +  /// Perform the SPI transaction on the SPI peripheral using the SPI host
> +  /// controller.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
> +};
> +
> +extern EFI_GUID gEfiSpiHcProtocolGuid;
> +
> +#endif // __SPI_HC_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiIo.h
> b/MdePkg/Include/Protocol/SpiIo.h
> new file mode 100644
> index 000000000000..e481779acc58
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiIo.h
> @@ -0,0 +1,292 @@
> +/** @file
> +  This file defines the SPI I/O Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_IO_PROTOCOL_H__
> +#define __SPI_IO_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiController.h>
> +#include <Protocol/SpiConfiguration.h>
> +
> +typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> +
> +///
> +/// Note: The UEFI PI 1.6 specification does not specify values for the
> +///       members below. The order matches the specification.
> +///
> +typedef enum {
> +  ///
> +  /// Data flowing in both direction between the host and
> +  /// SPI peripheral.ReadBytes must equal WriteBytes and both ReadBuffer
> and
> +  /// WriteBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_FULL_DUPLEX,
> +
> +  ///
> +  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> +  /// zero.WriteBytes must be non - zero and WriteBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_WRITE_ONLY,
> +
> +  ///
> +  /// Data flowing from the SPI peripheral to the host.WriteBytes must be
> +  /// zero.ReadBytes must be non - zero and ReadBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_READ_ONLY,
> +
> +  ///
> +  /// Data first flowing from the host to the SPI peripheral and then data
> +  /// flows from the SPI peripheral to the host.These types of operations get
> +  /// used for SPI flash devices when control data (opcode, address) must be
> +  /// passed to the SPI peripheral to specify the data to be read.
> +  ///
> +  SPI_TRANSACTION_WRITE_THEN_READ
> +} EFI_SPI_TRANSACTION_TYPE;
> +
> +/**
> +  Initiate a SPI transaction between the host and a SPI peripheral.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine works with the SPI bus layer to pass the SPI transaction to the
> +  SPI controller for execution on the SPI bus. There are four types of
> +  supported transactions supported by this routine:
> +  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> +  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes = 0
> +  * Read Only: ReadBuffer to receive data from SPI peripheral, WriteBytes =
> 0
> +  * Write Then Read: WriteBuffer contains control data to write to SPI
> +                     peripheral before data is placed into the ReadBuffer.
> +                     Both WriteBytes and ReadBytes must be non-zero.
> +
> +  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
> +  @param[in]  TransactionType   Type of SPI transaction.
> +  @param[in]  DebugTransaction  Set TRUE only when debugging is desired.
> +                                Debugging may be turned on for a single SPI
> +                                transaction. Only this transaction will display
> +                                debugging messages. All other transactions with
> +                                this value set to FALSE will not display any
> +                                debugging messages.
> +  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
> +                                the maximum clock frequency supported by the
> +                                SPI controller and part. Specify a non-zero
> +                                value only when a specific SPI transaction
> +                                requires a reduced clock rate.
> +  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
> +  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
> +  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
> +                                Specify zero for read-only operations.
> +  @param[in]  WriteBuffer       The buffer containing data to be sent from the
> +                                host to the SPI chip. Specify NULL for read
> +                                only operations.
> +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> +                                  frame
> +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> +                                  frame
> +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> +                                  per frame The transmit frame is in the least
> +                                  significant N bits.
> +  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
> +                                Specify zero for write-only operations.
> +  @param[out] ReadBuffer        The buffer to receeive data from the SPI chip
> +                                during the transaction. Specify NULL for write
> +                                only operations.
> +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> +                                  frame
> +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> +                                  frame
> +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> +                                  per frame The received frame is in the least
> +                                  significant N bits.
> +
> +  @retval EFI_SUCCESS            The SPI transaction completed successfully
> +  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
> +  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
> +  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
> +                                 or BusWidth not supported by SPI peripheral or
> +                                 SPI host controller,
> +                                 or WriteBytes non-zero and WriteBuffer is
> +                                 NULL,
> +                                 or ReadBytes non-zero and ReadBuffer is NULL,
> +                                 or ReadBuffer != WriteBuffer for full-duplex
> +                                 type,
> +                                 or WriteBuffer was NULL,
> +                                 or TPL is too high
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI transaction
> +  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the SPI
> bus
> +                                 layer or the SPI host controller
> +  @retval EFI_UNSUPPORTED        The SPI controller was not able to support
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> +  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
> +  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
> +  IN  BOOLEAN                    DebugTransaction,
> +  IN  UINT32                     ClockHz OPTIONAL,
> +  IN  UINT32                     BusWidth,
> +  IN  UINT32                     FrameSize,
> +  IN  UINT32                     WriteBytes,
> +  IN  UINT8                      *WriteBuffer,
> +  IN  UINT32                     ReadBytes,
> +  OUT UINT8                      *ReadBuffer
> +  );
> +
> +/**
> +  Update the SPI peripheral associated with this SPI 10 instance.
> +
> +  Support socketed SPI parts by allowing the SPI peripheral driver to replace
> +  the SPI peripheral after the connection is made. An example use is
> socketed
> +  SPI NOR flash parts, where the size and parameters change depending
> upon
> +  device is in the socket.
> +
> +  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
> +  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL structure.
> +
> +  @retval EFI_SUCCESS            The SPI peripheral was updated successfully
> +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
> +                                 or the SpiPeripheral->SpiBus is NULL,
> +                                 or the SpiP eripheral - >SpiBus pointing at
> +                                 wrong bus,
> +                                 or the SpiP eripheral - >SpiPart is NULL
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> +  IN CONST EFI_SPI_IO_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
> +  );
> +
> +///
> +/// The EFI_SPI_BUS_ TRANSACTION data structure contains the
> description of the
> +/// SPI transaction to perform on the host controller.
> +///
> +typedef struct _EFI_SPI_BUS_TRANSACTION {
> +  ///
> +  /// Pointer to the SPI peripheral being manipulated.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> +
> +  ///
> +  /// Type of transaction specified by one of the
> EFI_SPI_TRANSACTION_TYPE
> +  /// values.
> +  ///
> +  EFI_SPI_TRANSACTION_TYPE TransactionType;
> +
> +  ///
> +  /// TRUE if the transaction is being debugged. Debugging may be turned
> on for
> +  /// a single SPI transaction. Only this transaction will display debugging
> +  /// messages. All other transactions with this value set to FALSE will not
> +  /// display any debugging messages.
> +  ///
> +  BOOLEAN                  DebugTransaction;
> +
> +  ///
> +  /// SPI bus width in bits: 1, 2, 4
> +  ///
> +  UINT32                   BusWidth;
> +
> +  ///
> +  /// Frame size in bits, range: 1 - 32
> +  ///
> +  UINT32                   FrameSize;
> +
> +  ///
> +  /// Length of the write buffer in bytes
> +  ///
> +  UINT32                   WriteBytes;
> +
> +  ///
> +  /// Buffer containing data to send to the SPI peripheral
> +  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> +  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> +  ///
> +  UINT8                    *WriteBuffer;
> +
> +  ///
> +  /// Length of the read buffer in bytes
> +  ///
> +  UINT32                   ReadBytes;
> +
> +  ///
> +  /// Buffer to receive the data from the SPI peripheral
> +  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> +  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> +  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> +  ///
> +  UINT8                    *ReadBuffer;
> +} EFI_SPI_BUS_TRANSACTION;
> +
> +///
> +/// Support managed SPI data transactions between the SPI controller and a
> SPI
> +/// chip.
> +///
> +struct _EFI_SPI_IO_PROTOCOL {
> +  ///
> +  /// Address of an EFI_SPI_PERIPHERAL data structure associated with this
> +  /// protocol instance.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
> +
> +  ///
> +  /// Address of the original EFI_SPI_PERIPHERAL data structure associated
> with
> +  /// this protocol instance.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
> +
> +  ///
> +  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of N-
> bits
> +  /// is supported when bit N-1 is set. The host controller must support a
> +  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted to
> +  /// 8-bit frame sizes by the SPI bus layer if the frame size is not supported
> +  /// by the SPI host controller.
> +  ///
> +  UINT32                                    FrameSizeSupportMask;
> +
> +  ///
> +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> +  ///
> +  UINT32                                    MaximumTransferBytes;
> +
> +  ///
> +  /// Transaction attributes: One or more from:
> +  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> +  ///   - The SPI host and peripheral supports a 2-bit data bus
> +  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> +  ///   - The SPI host and peripheral supports a 4-bit data bus
> +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> +  ///   - Transfer size includes the opcode byte
> +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> +  ///   - Transfer size includes the 3 address bytes
> +  ///
> +  UINT32                                    Attributes;
> +
> +  ///
> +  /// Pointer to legacy SPI controller protocol
> +  ///
> +  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *LegacySpiProtocol;
> +
> +  ///
> +  /// Initiate a SPI transaction between the host and a SPI peripheral.
> +  ///
> +  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
> +
> +  ///
> +  /// Update the SPI peripheral associated with this SPI 10 instance.
> +  ///
> +  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL UpdateSpiPeripheral;
> +};
> +
> +#endif // __SPI_IO_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h
> b/MdePkg/Include/Protocol/SpiNorFlash.h
> new file mode 100644
> index 000000000000..93d2adaa860e
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiNorFlash.h
> @@ -0,0 +1,289 @@
> +/** @file
> +  This file defines the SPI NOR Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
> +#define __SPI_NOR_FLASH_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +
> +///
> +/// Global ID for the SPI NOR Flash Protocol
> +///
> +#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
> +  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
> +    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> +
> +typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL
> EFI_SPI_NOR_FLASH_PROTOCOL;
> +
> +/**
> +  Read the 3 byte manufacture and device ID from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads the 3 byte manufacture and device ID from the flash
> part
> +  filling the buffer provided.
> +
> +  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> structure.
> +  @param[out] Buffer  Pointer to a 3 byte buffer to receive the manufacture
> and
> +                      device ID.
> +
> +
> +
> +  @retval EFI_SUCCESS            The manufacture and device ID was read
> +                                 successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL
> +  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Read data from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads data from the SPI part in the buffer provided.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  FlashAddress   Address in the flash to start reading
> +  @param[in]  LengthInBytes  Read length in bytes
> +  @param[out] Buffer         Address of a buffer to receive the data
> +
> +  @retval EFI_SUCCESS            The data was read successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            FlashAddress,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Low frequency read data from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads data from the SPI part in the buffer provided.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  FlashAddress   Address in the flash to start reading
> +  @param[in]  LengthInBytes  Read length in bytes
> +  @param[out] Buffer         Address of a buffer to receive the data
> +
> +  @retval EFI_SUCCESS            The data was read successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            FlashAddress,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Read the flash status register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads the flash part status register.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  LengthInBytes  Number of status bytes to read.
> +  @param[out] FlashStatus    Pointer to a buffer to receive the flash status.
> +
> +  @retval EFI_SUCCESS  The status register was read successfully.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *FlashStatus
> +  );
> +
> +/**
> +  Write the flash status register.
> +
> +  This routine must be called at or below TPL_N OTIFY.
> +  This routine writes the flash part status register.
> +
> +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                            structure.
> +  @param[in] LengthInBytes  Number of status bytes to write.
> +  @param[in] FlashStatus    Pointer to a buffer containing the new status.
> +
> +  @retval EFI_SUCCESS           The status write was successful.
> +  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            LengthInBytes,
> +  IN UINT8                             *FlashStatus
> +  );
> +
> +/**
> +  Write data to the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine breaks up the write operation as necessary to write the data
> to
> +  the SPI part.
> +
> +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                            structure.
> +  @param[in] FlashAddress   Address in the flash to start writing
> +  @param[in] LengthInBytes  Write length in bytes
> +  @param[in] Buffer         Address of a buffer containing the data
> +
> +  @retval EFI_SUCCESS            The data was written successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            FlashAddress,
> +  IN UINT32                            LengthInBytes,
> +  IN UINT8                             *Buffer
> +  );
> +
> +/**
> +  Efficiently erases one or more 4KiB regions in the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine uses a combination of 4 KiB and larger blocks to erase the
> +  specified area.
> +
> +  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                           structure.
> +  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
> +  @param[in] BlockCount    Number of 4 KiB blocks to erase
> +
> +  @retval EFI_SUCCESS            The erase was completed successfully.
> +  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
> +                                 BlockCount * 4 KiB
> +                                   > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            FlashAddress,
> +  IN UINT32                            BlockCount
> +  );
> +
> +///
> +/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral layer.
> +/// This protocol manipulates the SPI NOR flash parts using a common set of
> +/// commands. The board layer provides the interconnection and
> configuration
> +/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
> +/// configuration data to expose a generic interface which provides the
> +/// following APls:
> +/// * Read manufacture and device ID
> +/// * Read data
> +/// * Read data using low frequency
> +/// * Read status
> +/// * Write data
> +/// * Erase 4 KiB blocks
> +/// * Erase 32 or 64 KiB blocks
> +/// * Write status
> +/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set the
> security
> +/// features on the legacy SPI flash controller.
> +///
> +struct _EFI_SPI_NOR_FLASH_PROTOCOL {
> +  ///
> +  /// Pointer to an EFI_SPI_PERIPHERAL data structure
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
> +
> +  ///
> +  /// Flash size in bytes
> +  ///
> +  UINT32                                  FlashSize;
> +
> +  ///
> +  /// Manufacture and Device ID
> +  ///
> +  UINT8                                   Deviceid[3];
> +
> +  ///
> +  /// Erase block size in bytes
> +  ///
> +  UINT32                                  EraseBlockBytes;
> +
> +  ///
> +  /// Read the 3 byte manufacture and device ID from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
> +
> +  ///
> +  /// Read data from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
> +
> +  ///
> +  /// Low frequency read data from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
> +
> +  ///
> +  /// Read the flash status register.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
> +
> +  ///
> +  /// Write the flash status register.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
> +
> +  ///
> +  /// Write data to the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
> +
> +  ///
> +  /// Efficiently erases one or more 4KiB regions in the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
> +};
> +
> +extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
> +
> +#endif // __SPI_NOR_FLASH_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> new file mode 100644
> index 000000000000..913d4cbb46aa
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the SPI SMM Configuration Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +
> +///
> +/// Global ID for the SPI SMM Configuration Protocol
> +///
> +#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
> +  { 0x995c6eca, 0x171b, 0x45fd,                  \
> +    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> +
> +typedef
> +struct _EFI_SPI_CONFIGURATION_PROTOCOL
> +EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
> +
> +#endif // __SPI_SMM_CONFIGURATION_H__
> diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h
> b/MdePkg/Include/Protocol/SpiSmmHc.h
> new file mode 100644
> index 000000000000..91d2312b74b4
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiSmmHc.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the SPI SMM Host Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_SMM_HC_H__
> +#define __SPI_SMM_HC_H__
> +
> +#include <Protocol/SpiHc.h>
> +
> +///
> +/// Global ID for the SPI SMM Host Controller Protocol
> +///
> +#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
> +  { 0xe9f02217, 0x2093, 0x4470,       \
> +    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> +
> +typedef
> +struct _EFI_SPI_HC_PROTOCOL
> +EFI_SPI_SMM_HC_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
> +
> +#endif // __SPI_SMM_HC_H__
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 1867c54c3bc1..91af6c5c455c 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -1246,6 +1246,37 @@ [Protocols]
>    gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd,
> { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
> 
>    #
> +  # Protocols defined in PI 1.6.
> +  #
> +
> +  ## Include/Protocol/LegacySpiController.h
> +  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de,
> { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> +
> +  ## Include/Protocol/LegacySpiFlash.h
> +  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, { 0x96,
> 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> +
> +  ## Include/Protocol/LegacySpiSmmController.h
> +  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0, 0x4c8c,
> { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> +
> +  ## Include/Protocol/LegacySpiSmmFlash.h
> +  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0,
> { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> +
> +  ## Include/Protocol/SpiConfiguration.h
> +  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, { 0xb3,
> 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> +
> +  ## Include/Protocol/SpiHc.h
> +  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3, 0x99,
> 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> +
> +  ## Include/Protocol/SpiNorFlash.h
> +  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, { 0x85,
> 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> +
> +  ## Include/Protocol/SpiSmmConfiguration.h
> +  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b, 0x45fd,
> { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> +
> +  ## Include/Protocol/SpiSmmHc.h
> +  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, { 0x8a,
> 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> +
> +  #
>    # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
>    #
> 
> --
> 2.12.2.windows.2
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Bi, Dandan 6 years, 7 months ago
Hi Marvin,

Thank you for your contribution. I am reviewing this patch now. Currently I just take a look at the SMM SPI part and find:

1. There is a typo in LegacySpiSmmController.h
The definition should be EFI_LEGACY_SPI_SMM_CONTROLLER_GUID, not EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID.
Typo:
#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
And it should  be:
#define EFI_LEGACY_SPI_SMM_CONTROLLER_GUID \
{ 0x62331b78, 0xd8d0, 0x4c8c, { 0x8c, 0xcb, 0xd2, 0x7d, \ 0xfe, 0x32, 0xdb, 0x9b }}

2. EFI_SPI_SMM_NOR_FLASH_PROTOCOL definition seems to be missing.

I will review the remaining part. It may take some time. Sorry for the delay in my response

Thanks,
Dandan

-----Original Message-----
From: Ni, Ruiyu 
Sent: Thursday, September 7, 2017 3:13 PM
To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-devel@lists.01.org
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Bi, Dandan <dandan.bi@intel.com>
Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.

Marvin,
Thank you for your contribution. We will need some time to review the definitions against PI Spec.
If there is a need to post V2, it might be better to separate the header files in different groups.
For example, LegacySpi group, SPI group, SMM SPI group.

Thanks/Ray

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Marvin Häuser
> Sent: Wednesday, September 6, 2017 5:21 PM
> To: edk2-devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Subject: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> This commit adds header files for the SPI protocols introduced in the
> UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.
> 
> EFI_SPI_TRANSACTION_TYPE assumes an enum with its members ordered
> the
> way they are listed in the specification, as there are no values given
> explicitely.
> EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in the
> specification was meant to be '1'.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
> ---
>  MdePkg/Include/Protocol/LegacySpiController.h    | 265
> ++++++++++++++++++
>  MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
>  MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
>  MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
>  MdePkg/Include/Protocol/SpiConfiguration.h       | 293
> ++++++++++++++++++++
>  MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
>  MdePkg/Include/Protocol/SpiIo.h                  | 292 +++++++++++++++++++
>  MdePkg/Include/Protocol/SpiNorFlash.h            | 289
> +++++++++++++++++++
>  MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
>  MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
>  MdePkg/MdePkg.dec                                |  31 +++
>  11 files changed, 1709 insertions(+)
> 
> diff --git a/MdePkg/Include/Protocol/LegacySpiController.h
> b/MdePkg/Include/Protocol/LegacySpiController.h
> new file mode 100644
> index 000000000000..2d36eaefc0ee
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiController.h
> @@ -0,0 +1,265 @@
> +/** @file
> +  This file defines the Legacy SPI Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> +#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> +
> +///
> +/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
> +///       definition. This definition assumes it was supposed to be '1'.
> +///
> +/// Global ID for the Legacy SPI Controller Protocol
> +///
> +#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
> +  { 0x39136fc7, 0x1a11, 0x49de,         \
> +    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
> +
> +/**
> +  Set the erase block opcode.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The menu table contains SPI transaction opcodes which are accessible
> after
> +  the legacy SPI flash controller's configuration is locked. The board layer
> +  specifies the erase block size for the SPI NOR flash part. The SPI NOR flash
> +  peripheral driver selects the erase block opcode which matches the erase
> +  block size and uses this API to load the opcode into the opcode menu table.
> +
> +  @param[in] This              Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                               structure.
> +  @param[in] EraseBlockOpcode  Erase block opcode to be placed into the
> opcode
> +                               menu table.
> +
> +  @retval EFI_SUCCESS       The opcode menu table was updated
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT8                                     EraseBlockOpcode
> +  );
> +
> +/**
> +  Set the write status prefix opcode.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The prefix table contains SPI transaction write prefix opcodes which are
> +  accessible after the legacy SPI flash controller's configuration is locked.
> +  The board layer specifies the write status prefix opcode for the SPI NOR
> +  flash part. The SPI NOR flash peripheral driver uses this API to load the
> +  opcode into the prefix table.
> +
> +  @param[in] This               Pointer to an
> +                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
> +  @param[in] WriteStatusPrefix  Prefix opcode for the write status
> command.
> +
> +  @retval EFI_SUCCESS       The prefix table was updated
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT8                                     WriteStatusPrefix
> +  );
> +
> +/**
> +  Set the BIOS base address.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS base address works with the protect range registers to protect
> +  portions of the SPI NOR flash from erase and write operat ions. The BIOS
> +  calls this API prior to passing control to the OS loader.
> +
> +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                              structure.
> +  @param[in] BiosBaseAddress  The BIOS base address.
> +
> +  @retval EFI_SUCCESS            The BIOS base address was properly set
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater than
> +                                 This->Maxi.mumOffset
> +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS)
> (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32 BiosBaseAddress
> +  );
> +
> +/**
> +  Clear the SPI protect range registers.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to set an initial condition on the SPI protect
> +  range registers.
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> structure.
> +
> +  @retval EFI_SUCCESS       The registers were successfully cleared
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT)
> (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> +  );
> +
> +/**
> +  Determine if the SPI range is protected.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to verify a range in the SPI is protected.
> +
> +  @param[in] This            Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                             structure.
> +  @param[in] BiosAddress     Address within a 4 KiB block to start protecting.
> +  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval TRUE   The range is protected
> +  @retval FALSE  The range is not protected
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32                                    BiosAddress,
> +  IN UINT32                                    BlocksToProtect
> +  );
> +
> +/**
> +  Set the next protect range register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS sets the protect range register to prevent write and erase
> +  operations to a portion of the SPI NOR flash device.
> +
> +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval EFI_SUCCESS            The register was successfully updated
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress,
> or
> +                                 BlocksToProtect * 4 KiB
> +                                   > This->MaximumRangeBytes, or
> +                                 BiosAddress - This->BiosBaseAddress
> +                                   + (BlocksToProtect * 4 KiB)
> +                                     > This->MaximumRangeBytes
> +  @retval EFI_OUT_OF_RESOURCES  No protect range register available
> +  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the
> BIOS base
> +                                address is not set
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32                                    BiosAddress,
> +  IN UINT32                                    BlocksToProtect
> +  );
> +
> +/**
> +  Lock the SPI controller configuration.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine locks the SPI controller's configuration so that the software
> +  is no longer able to update:
> +  * Prefix table
> +  * Opcode menu
> +  * Opcode type table
> +  * BIOS base address
> +  * Protect range registers
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> structure.
> +
> +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> +  );
> +
> +///
> +/// Support the extra features of the legacy SPI flash controller.
> +///
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
> +  ///
> +  /// Maximum offset from the BIOS base address that is able to be
> protected.
> +  ///
> +  UINT32                                                 MaximumOffset;
> +
> +  ///
> +  /// Maximum number of bytes that can be protected by one range register.
> +  ///
> +  UINT32                                                 MaximumRangeBytes;
> +
> +  ///
> +  /// The number of registers available for protecting the BIOS.
> +  ///
> +  UINT32                                                 RangeRegisterCount;
> +
> +  ///
> +  /// Set the erase block opcode.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE
> EraseBlockOpcode;
> +
> +  ///
> +  /// Set the write status prefix opcode.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX
> WriteStatusPrefix;
> +
> +  ///
> +  /// Set the BIOS base address.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS
> BiosBaseAddress;
> +
> +  ///
> +  /// Clear the SPI protect range registers.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT
> ClearSpiProtect;
> +
> +  ///
> +  /// Determine if the SPI range is protected.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED
> IsRangeProtected;
> +
> +  ///
> +  /// Set the next protect range register.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE
> ProtectNextRange;
> +
> +  ///
> +  /// Lock the SPI controller configuration.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER
> LockController;
> +};
> +
> +extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
> +
> +#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h
> b/MdePkg/Include/Protocol/LegacySpiFlash.h
> new file mode 100644
> index 000000000000..faa5f5724af7
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
> @@ -0,0 +1,201 @@
> +/** @file
> +  This file defines the Legacy SPI Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_CONFIGURATION_PROTOCOL_H__
> +
> +#include <Protocol/SpiNorFlash.h>
> +
> +///
> +/// Global ID for the Legacy SPI Flash Protocol
> +///
> +#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
> +  { 0xf01bed57, 0x04bc, 0x4f3f,             \
> +    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> +
> +typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> EFI_LEGACY_SPI_FLASH_PROTOCOL;
> +
> +/**
> +  Set the BIOS base address.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS base address works with the protect range registers to protect
> +  portions of the SPI NOR flash from erase and write operat ions.
> +  The BIOS calls this API prior to passing control to the OS loader.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosBaseAddress  The BIOS base address.
> +
> +  @retval EFI_SUCCESS            The BIOS base address was properly set
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This-
> >MaximumOffset
> +  @retval EFI_UNSUPPORTED        The BIOS base address was already set or
> not a
> +                                 legacy SPI host controller
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosBaseAddress
> +  );
> +
> +/**
> +  Clear the SPI protect range registers.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to set an initial condition on the SPI protect
> +  range registers.
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> structure.
> +
> +  @retval EFI_SUCCESS       The registers were successfully cleared
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> +  );
> +
> +/**
> +  Determine if the SPI range is protected.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to verify a range in the SPI is protected.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval TRUE   The range is protected
> +  @retval FALSE  The range is not protected
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosAddress,
> +  IN UINT32                               BlocksToProtect
> +  );
> +
> +/**
> +  Set the next protect range register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS sets the protect range register to prevent write and erase
> +  operations to a portion of the SPI NOR flash device.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval EFI_SUCCESS            The register was successfully updated
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress,
> or
> +  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
> +                                   > This->MaximumRangeBytes, or
> +                                 BiosAddress - This->BiosBaseAddress
> +                                   + (BlocksToProtect * 4 KiB)
> +                                     > This->MaximumRangeBytes
> +  @retval EFI_OUT_OF_RESOURCES   No protect range register available
> +  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the
> BIOS
> +                                 base address is not set Not a legacy SPI host
> +                                 controller
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosAddress,
> +  IN UINT32                               BlocksToProtect
> +  );
> +
> +/**
> +  Lock the SPI controller configuration.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine locks the SPI controller's configuration so that the software is
> +  no longer able to update:
> +  * Prefix table
> +  * Opcode menu
> +  * Opcode type table
> +  * BIOS base address
> +  * Protect range registers
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> structure.
> +
> +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> +  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> +  );
> +
> +///
> +/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the
> EFI_SPI_NOR_FLASH_PROTOCOL
> +/// with APls to support the legacy SPI flash controller.
> +///
> +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
> +  ///
> +  /// This protocol manipulates the SPI NOR flash parts using a common set
> of
> +  /// commands.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
> +
> +  //
> +  // Legacy flash (SPI host) controller support
> +  //
> +
> +  ///
> +  /// Set the BIOS base address.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS
> BiosBaseAddress;
> +
> +  ///
> +  /// Clear the SPI protect range registers.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT
> ClearSpiProtect;
> +
> +  ///
> +  /// Determine if the SPI range is protected.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED
> IsRangeProtected;
> +
> +  ///
> +  /// Set the next protect range register.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE
> ProtectNextRange;
> +
> +  ///
> +  /// Lock the SPI controller configuration.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER    LockController;
> +};
> +
> +extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
> +
> +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h
> b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> new file mode 100644
> index 000000000000..6d8d557cefff
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the Legacy SPI SMM Controler Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> +#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiController.h>
> +
> +///
> +/// Global ID for the Legacy SPI SMM Controller Protocol
> +///
> +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> +  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> +    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
> +
> +extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
> +
> +#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> new file mode 100644
> index 000000000000..a604a22f901f
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the Legacy SPI SMM Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> +#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiFlash.h>
> +
> +///
> +/// Global ID for the Legacy SPI SMM Flash Protocol
> +///
> +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> +  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
> +    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> +EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
> +
> +extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
> +
> +#endif // __SPI_SMM_FLASH_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h
> b/MdePkg/Include/Protocol/SpiConfiguration.h
> new file mode 100644
> index 000000000000..3a602f67d7a6
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiConfiguration.h
> @@ -0,0 +1,293 @@
> +/** @file
> +  This file defines the SPI Configuration Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_CONFIGURATION_PROTOCOL_H__
> +
> +///
> +/// Global ID for the SPI Configuration Protocol
> +///
> +#define EFI_SPI_CONFIGURATION_GUID  \
> +  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
> +    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> +
> +///
> +/// Macros to easily specify frequencies in hertz, kilohertz and megahertz.
> +///
> +#define Hz(Frequency)   (Frequency)
> +#define KHz(Frequency)  (1000 * Hz (Frequency))
> +#define MHz(Frequency)  (1000 * KHz (Frequency))
> +
> +typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
> +
> +/**
> +  Manipulate the chip select for a SPI device.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  Update the value of the chip select line for a SPI peripheral.
> +  The SPI bus layer calls this routine either in the board layer or in the SPI
> +  controller to manipulate the chip select pin at the start and end of a SPI
> +  transaction.
> +
> +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> structure
> +                            describing the SPI peripheral whose chip select pin
> +                            is to be manipulated. The routine may access the
> +                            ChipSelectParameter field to gain sufficient
> +                            context to complete the operation.
> +  @param[in] PinValue       The value to be applied to the chip select line of
> +                            the SPI peripheral.
> +
> +  @retval EFI_SUCCESS            The chip select was set successfully
> +  @retval EFI_NOT_READY          Support for the chip select is not properly
> +                                 initialized
> +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral-
> >ChipSelectParameter value
> +                                 is invalid
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_CHIP_SELECT) (
> +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> +  IN BOOLEAN                   PinValue
> +  );
> +
> +/**
> +  Set up the clock generator to produce the correct clock frequency, phase
> and
> +  polarity for a SPI chip.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine updates the clock generator to generate the correct
> frequency
> +  and polarity for the SPI clock.
> +
> +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure
> from
> +                            which the routine can access the ClockParameter,
> +                            ClockPhase and ClockPolarity fields. The routine
> +                            also has access to the names for the SPI bus and
> +                            chip which can be used during debugging.
> +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> clock
> +                            generator will choose a supported clock frequency
> +                            which is less then or equal to this value.
> +                            Specify zero to turn the clock generator off.
> +                            The actual clock frequency supported by the clock
> +                            generator will be returned.
> +
> +  @retval EFI_SUCCESS      The clock was set up successfully
> +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
> +                           frequency requested by CLockHz
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_CLOCK) (
> +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> +  IN UINT32                    *ClockHz
> +  );
> +
> +///
> +/// The EFI_SPI_PART data structure provides a description of a SPI part
> which
> +/// is independent of the use on the board. This data is available directly
> +/// from the part's datasheet and may be provided by the vendor.
> +///
> +typedef struct _EFI_SPI_PART {
> +  ///
> +  /// A Unicode string specifying the SPI chip vendor.
> +  ///
> +  CONST CHAR16 *Vendor;
> +
> +  ///
> +  /// A Unicode string specifying the SPI chip part number.
> +  ///
> +  CONST CHAR16 *PartNumber;
> +
> +  ///
> +  /// The minimum SPI bus clock frequency used to access this chip. This
> value
> +  /// may be specified in the chip's datasheet. If not, use the value of zero.
> +  ///
> +  UINT32       MinClockHz;
> +
> +  ///
> +  /// The maximum SPI bus clock frequency used to access this chip. This
> value
> +  /// is found in the chip's datasheet.
> +  ///
> +  UINT32       MaxClockHz;
> +
> +  ///
> +  /// Specify the polarity of the chip select pin. This value can be found in
> +  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip
> select
> +  ///and FALSE when a zero asserts the chip select.
> +  ///
> +  BOOLEAN      ChipSelectPolarity;
> +} EFI_SPI_PART;
> +
> +///
> +/// The EFI_SPI_BUS data structure provides the connection details
> between the
> +/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which controls
> that
> +/// SPI bus. This data structure also describes the details of how the clock is
> +/// generated for that SPI bus. Finally this data structure provides the list
> +/// of physical SPI devices which are attached to the SPI bus.
> +///
> +typedef struct _EFI_SPI_BUS {
> +  ///
> +  /// A Unicode string describing the SPI bus
> +  ///
> +  CONST CHAR16                   *FriendlyName;
> +
> +  ///
> +  /// Address of the first EFI_SPI_PERIPHERAL data structure connected to
> this
> +  /// bus. Specify NULL if there are no SPI peripherals connected to this bus.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
> +
> +  ///
> +  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which
> uniquely
> +  /// describes the SPI controller.
> +  ///
> +  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
> +
> +  ///
> +  /// Address of the routine which controls the clock used by the SPI bus for
> +  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
> +  /// when this value is set to NULL.
> +  ///
> +  EFI_SPI_CLOCK                  Clock;
> +
> +  ///
> +  /// Address of a data structure containing the additional values which
> +  /// describe the necessary control for the clock. When Clock is NULL,
> +  /// the declaration for this data structure is provided by the vendor of the
> +  /// host's SPI controller driver. When Clock is not NULL, the declaration for
> +  /// this data structure is provided by the board layer.
> +  ///
> +  VOID                           *ClockParameter;
> +} EFI_SPI_BUS;
> +
> +///
> +/// The EFI_SPI_PERIPHERAL data structure describes how a specific block
> of
> +/// logic which is connected to the SPI bus. This data structure also selects
> +/// which upper level driver is used to manipulate this SPI device.
> +/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
> +/// peripheral driver.
> +///
> +struct _EFI_SPI_PERIPHERAL {
> +  ///
> +  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify NULL
> if
> +  /// the current data structure is the last one on the SPI bus.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
> +
> +  ///
> +  /// A unicode string describing the function of the SPI part.
> +  ///
> +  CONST CHAR16             *FriendlyName;
> +
> +  ///
> +  /// Address of a GUID provided by the vendor of the SPI peripheral driver.
> +  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus driver
> uses
> +  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and to
> +  /// provide the connection points for the SPI peripheral drivers.
> +  /// This reduces the comparison logic in the SPI peripheral driver's
> +  /// Supported routine.
> +  ///
> +  CONST GUID               *SpiPeripheralDriverGuid;
> +
> +  ///
> +  /// The address of an EFI_SPI_PART data structure which describes this
> chip.
> +  ///
> +  CONST EFI_SPI_PART       *SpiPart;
> +
> +  ///
> +  /// The maximum clock frequency is specified in the EFI_SPI_P ART. When
> this
> +  /// this value is non-zero and less than the value in the EFI_SPI_PART then
> +  /// this value is used for the maximum clock frequency for the SPI part.
> +  ///
> +  UINT32                   MaxClockHz;
> +
> +  ///
> +  /// Specify the idle value of the clock as found in the datasheet.
> +  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
> +  /// clock's idle value is high.
> +  ///
> +  BOOLEAN                  ClockPolarity;
> +
> +  ///
> +  /// Specify the clock delay after chip select. Specify zero (0) to delay an
> +  /// entire clock cycle or one (1) to delay only half a clock cycle.
> +  ///
> +  BOOLEAN                  ClockPhase;
> +
> +  ///
> +  /// SPI peripheral attributes, select zero or more of:
> +  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI
> peripheral is wired to
> +  ///   support a 2-bit data bus
> +  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI
> peripheral is wired to
> +  ///   support a 4-bit data bus
> +  ///
> +  UINT32                   Attributes;
> +
> +  ///
> +  /// Address of a vendor specific data structure containing additional board
> +  /// configuration details related to the SPI chip. The SPI peripheral layer
> +  /// uses this data structure when configuring the chip.
> +  ///
> +  CONST VOID               *ConfigurationData;
> +
> +  ///
> +  /// The address of an EFI_SPI_BUS data structure which describes the SPI
> bus
> +  /// to which this chip is connected.
> +  ///
> +  CONST EFI_SPI_BUS        *SpiBus;
> +
> +  ///
> +  /// Address of the routine which controls the chip select pin for this SPI
> +  /// peripheral. Call the SPI host controller's chip select routine when this
> +  /// value is set to NULL.
> +  ///
> +  EFI_SPI_CHIP_SELECT      ChipSelect;
> +
> +  ///
> +  /// Address of a data structure containing the additional values which
> +  /// describe the necessary control for the chip select. When ChipSelect is
> +  /// NULL, the declaration for this data structure is provided by the vendor
> +  /// of the host's SPI controller driver. The vendor's documentation
> specifies
> +  /// the necessary values to use for the chip select pin selection and
> +  /// control. When Chipselect is not NULL, the declaration for this data
> +  /// structure is provided by the board layer.
> +  ///
> +  VOID                     *ChipSelectParameter;
> +};
> +
> +///
> +/// Describe the details of the board's SPI busses to the SPI driver stack.
> +/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to
> expose the data
> +/// tables which describe the board's SPI busses, The SPI bus layer uses
> these
> +/// tables to configure the clock, chip select and manage the SPI
> transactions
> +/// on the SPI controllers.
> +///
> +typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
> +  ///
> +  /// The number of SPI busses on the board.
> +  ///
> +  UINT32                          BusCount;
> +
> +  ///
> +  /// The address of an array of EFI_SPI_BUS data structure addresses.
> +  ///
> +  CONST EFI_SPI_BUS *CONST *CONST Buslist;
> +} EFI_SPI_CONFIGURATION_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
> +
> +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiHc.h
> b/MdePkg/Include/Protocol/SpiHc.h
> new file mode 100644
> index 000000000000..13ad5f45225c
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiHc.h
> @@ -0,0 +1,194 @@
> +/** @file
> +  This file defines the SPI Host Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_HC_PROTOCOL_H__
> +#define __SPI_HC_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +#include <Protocol/SpiIo.h>
> +
> +///
> +/// Global ID for the SPI Host Controller Protocol
> +///
> +#define EFI_SPI_HOST_GUID  \
> +  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
> +    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> +
> +///
> +/// EDK2-style name
> +///
> +#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
> +
> +typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
> +
> +/**
> +  Assert or deassert the SPI chip select.
> +
> +  This routine is called at TPL_NOTIFY.
> +  Update the value of the chip select line for a SPI peripheral. The SPI bus
> +  layer calls this routine either in the board layer or in the SPI controller
> +  to manipulate the chip select pin at the start and end of a SPI transaction.
> +
> +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> structure
> +                            describing the SPI peripheral whose chip select pin
> +                            is to be manipulated. The routine may access the
> +                            ChipSelectParameter field to gain sufficient
> +                            context to complete the operati on.
> +  @param[in] PinValue       The value to be applied to the chip select line of
> +                            the SPI peripheral.
> +
> +  @retval EFI_SUCCESS            The chip select was set as requested
> +  @retval EFI_NOT_READY          Support for the chip select is not properly
> +                                 initialized
> +  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its contents
> are
> +                                 invalid
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> +  IN BOOLEAN                    PinValue
> +  );
> +
> +/**
> +  Set up the clock generator to produce the correct clock frequency, phase
> and
> +  polarity for a SPI chip.
> +
> +  This routine is called at TPL_NOTIFY.
> +  This routine updates the clock generator to generate the correct
> frequency
> +  and polarity for the SPI clock.
> +
> +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure
> from
> +                            which the routine can access the ClockParameter,
> +                            ClockPhase and ClockPolarity fields. The routine
> +                            also has access to the names for the SPI bus and
> +                            chip which can be used during debugging.
> +  @param[in] ClockHz        Pointer to the requested clock frequency. The SPI
> +                            host controller will choose a supported clock
> +                            frequency which is less then or equal to this
> +                            value. Specify zero to turn the clock generator
> +                            off. The actual clock frequency supported by the
> +                            SPI host controller will be returned.
> +
> +  @retval EFI_SUCCESS      The clock was set up successfully
> +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
> +                           frequency requested by ClockHz
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> +  IN UINT32                      *ClockHz
> +  );
> +
> +/**
> +  Perform the SPI transaction on the SPI peripheral using the SPI host
> +  controller.
> +
> +  This routine is called at TPL_NOTIFY.
> +  This routine synchronously returns EFI_SUCCESS indicating that the
> +  asynchronous SPI transaction was started. The routine then waits for
> +  completion of the SPI transaction prior to returning the final transaction
> +  status.
> +
> +  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION
> containing
> +                             the description of the SPI transaction to perform.
> +
> +  @retval EFI_SUCCESS          The transaction completed successfully
> +  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value is
> invalid,
> +                               or the BusTransaction->ReadinBytes value is
> +                               invalid
> +  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type is
> +                               unsupported
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
> +  );
> +
> +///
> +/// Support a SPI data transaction between the SPI controller and a SPI chip.
> +///
> +struct _EFI_SPI_HC_PROTOCOL {
> +  ///
> +  /// Host control attributes, may have zero or more of the following set:
> +  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> +  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> +  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> +  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> +  ///   - The SPI host controller requires the transmit frame to be in most
> +  ///     significant bits instead of least significant bits.The host driver
> +  ///     will adjust the frames if necessary.
> +  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
> +  ///   - The SPI host controller places the receive frame to be in most
> +  ///     significant bits instead of least significant bits.The host driver
> +  ///     will adjust the frames to be in the least significant bits if
> +  ///     necessary.
> +  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
> +  ///   - The SPI controller supports a 2 - bit data bus
> +  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> +  ///   - The SPI controller supports a 4 - bit data bus
> +  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> +  ///   - Transfer size includes the opcode byte
> +  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> +  ///   - Transfer size includes the 3 address bytes
> +  /// The SPI host controller must support full - duplex (receive while
> +  /// sending) operation.The SPI host controller must support a 1 - bit bus
> +  /// width.
> +  ///
> +  UINT32                          Attributes;
> +
> +  ///
> +  /// Mask of frame sizes which the SPI host controller supports. Frame size
> of
> +  /// N-bits is supported when bit N-1 is set. The host controller must
> support
> +  /// a frame size of 8-bits.
> +  ///
> +  UINT32                          FrameSizeSupportMask;
> +
> +  ///
> +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> +  ///
> +  UINT32                          MaximumTransferBytes;
> +
> +  ///
> +  /// Assert or deassert the SPI chip select.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
> +
> +  ///
> +  /// Set up the clock generator to produce the correct clock frequency,
> phase
> +  /// and polarity for a SPI chip.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
> +
> +  ///
> +  /// Perform the SPI transaction on the SPI peripheral using the SPI host
> +  /// controller.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
> +};
> +
> +extern EFI_GUID gEfiSpiHcProtocolGuid;
> +
> +#endif // __SPI_HC_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiIo.h
> b/MdePkg/Include/Protocol/SpiIo.h
> new file mode 100644
> index 000000000000..e481779acc58
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiIo.h
> @@ -0,0 +1,292 @@
> +/** @file
> +  This file defines the SPI I/O Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_IO_PROTOCOL_H__
> +#define __SPI_IO_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiController.h>
> +#include <Protocol/SpiConfiguration.h>
> +
> +typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> +
> +///
> +/// Note: The UEFI PI 1.6 specification does not specify values for the
> +///       members below. The order matches the specification.
> +///
> +typedef enum {
> +  ///
> +  /// Data flowing in both direction between the host and
> +  /// SPI peripheral.ReadBytes must equal WriteBytes and both ReadBuffer
> and
> +  /// WriteBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_FULL_DUPLEX,
> +
> +  ///
> +  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> +  /// zero.WriteBytes must be non - zero and WriteBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_WRITE_ONLY,
> +
> +  ///
> +  /// Data flowing from the SPI peripheral to the host.WriteBytes must be
> +  /// zero.ReadBytes must be non - zero and ReadBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_READ_ONLY,
> +
> +  ///
> +  /// Data first flowing from the host to the SPI peripheral and then data
> +  /// flows from the SPI peripheral to the host.These types of operations get
> +  /// used for SPI flash devices when control data (opcode, address) must be
> +  /// passed to the SPI peripheral to specify the data to be read.
> +  ///
> +  SPI_TRANSACTION_WRITE_THEN_READ
> +} EFI_SPI_TRANSACTION_TYPE;
> +
> +/**
> +  Initiate a SPI transaction between the host and a SPI peripheral.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine works with the SPI bus layer to pass the SPI transaction to the
> +  SPI controller for execution on the SPI bus. There are four types of
> +  supported transactions supported by this routine:
> +  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> +  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes = 0
> +  * Read Only: ReadBuffer to receive data from SPI peripheral, WriteBytes =
> 0
> +  * Write Then Read: WriteBuffer contains control data to write to SPI
> +                     peripheral before data is placed into the ReadBuffer.
> +                     Both WriteBytes and ReadBytes must be non-zero.
> +
> +  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
> +  @param[in]  TransactionType   Type of SPI transaction.
> +  @param[in]  DebugTransaction  Set TRUE only when debugging is desired.
> +                                Debugging may be turned on for a single SPI
> +                                transaction. Only this transaction will display
> +                                debugging messages. All other transactions with
> +                                this value set to FALSE will not display any
> +                                debugging messages.
> +  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
> +                                the maximum clock frequency supported by the
> +                                SPI controller and part. Specify a non-zero
> +                                value only when a specific SPI transaction
> +                                requires a reduced clock rate.
> +  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
> +  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
> +  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
> +                                Specify zero for read-only operations.
> +  @param[in]  WriteBuffer       The buffer containing data to be sent from the
> +                                host to the SPI chip. Specify NULL for read
> +                                only operations.
> +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> +                                  frame
> +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> +                                  frame
> +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> +                                  per frame The transmit frame is in the least
> +                                  significant N bits.
> +  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
> +                                Specify zero for write-only operations.
> +  @param[out] ReadBuffer        The buffer to receeive data from the SPI chip
> +                                during the transaction. Specify NULL for write
> +                                only operations.
> +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> +                                  frame
> +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> +                                  frame
> +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> +                                  per frame The received frame is in the least
> +                                  significant N bits.
> +
> +  @retval EFI_SUCCESS            The SPI transaction completed successfully
> +  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
> +  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
> +  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
> +                                 or BusWidth not supported by SPI peripheral or
> +                                 SPI host controller,
> +                                 or WriteBytes non-zero and WriteBuffer is
> +                                 NULL,
> +                                 or ReadBytes non-zero and ReadBuffer is NULL,
> +                                 or ReadBuffer != WriteBuffer for full-duplex
> +                                 type,
> +                                 or WriteBuffer was NULL,
> +                                 or TPL is too high
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI transaction
> +  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the SPI
> bus
> +                                 layer or the SPI host controller
> +  @retval EFI_UNSUPPORTED        The SPI controller was not able to support
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> +  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
> +  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
> +  IN  BOOLEAN                    DebugTransaction,
> +  IN  UINT32                     ClockHz OPTIONAL,
> +  IN  UINT32                     BusWidth,
> +  IN  UINT32                     FrameSize,
> +  IN  UINT32                     WriteBytes,
> +  IN  UINT8                      *WriteBuffer,
> +  IN  UINT32                     ReadBytes,
> +  OUT UINT8                      *ReadBuffer
> +  );
> +
> +/**
> +  Update the SPI peripheral associated with this SPI 10 instance.
> +
> +  Support socketed SPI parts by allowing the SPI peripheral driver to replace
> +  the SPI peripheral after the connection is made. An example use is
> socketed
> +  SPI NOR flash parts, where the size and parameters change depending
> upon
> +  device is in the socket.
> +
> +  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
> +  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL structure.
> +
> +  @retval EFI_SUCCESS            The SPI peripheral was updated successfully
> +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
> +                                 or the SpiPeripheral->SpiBus is NULL,
> +                                 or the SpiP eripheral - >SpiBus pointing at
> +                                 wrong bus,
> +                                 or the SpiP eripheral - >SpiPart is NULL
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> +  IN CONST EFI_SPI_IO_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
> +  );
> +
> +///
> +/// The EFI_SPI_BUS_ TRANSACTION data structure contains the
> description of the
> +/// SPI transaction to perform on the host controller.
> +///
> +typedef struct _EFI_SPI_BUS_TRANSACTION {
> +  ///
> +  /// Pointer to the SPI peripheral being manipulated.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> +
> +  ///
> +  /// Type of transaction specified by one of the
> EFI_SPI_TRANSACTION_TYPE
> +  /// values.
> +  ///
> +  EFI_SPI_TRANSACTION_TYPE TransactionType;
> +
> +  ///
> +  /// TRUE if the transaction is being debugged. Debugging may be turned
> on for
> +  /// a single SPI transaction. Only this transaction will display debugging
> +  /// messages. All other transactions with this value set to FALSE will not
> +  /// display any debugging messages.
> +  ///
> +  BOOLEAN                  DebugTransaction;
> +
> +  ///
> +  /// SPI bus width in bits: 1, 2, 4
> +  ///
> +  UINT32                   BusWidth;
> +
> +  ///
> +  /// Frame size in bits, range: 1 - 32
> +  ///
> +  UINT32                   FrameSize;
> +
> +  ///
> +  /// Length of the write buffer in bytes
> +  ///
> +  UINT32                   WriteBytes;
> +
> +  ///
> +  /// Buffer containing data to send to the SPI peripheral
> +  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> +  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> +  ///
> +  UINT8                    *WriteBuffer;
> +
> +  ///
> +  /// Length of the read buffer in bytes
> +  ///
> +  UINT32                   ReadBytes;
> +
> +  ///
> +  /// Buffer to receive the data from the SPI peripheral
> +  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> +  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> +  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> +  ///
> +  UINT8                    *ReadBuffer;
> +} EFI_SPI_BUS_TRANSACTION;
> +
> +///
> +/// Support managed SPI data transactions between the SPI controller and a
> SPI
> +/// chip.
> +///
> +struct _EFI_SPI_IO_PROTOCOL {
> +  ///
> +  /// Address of an EFI_SPI_PERIPHERAL data structure associated with this
> +  /// protocol instance.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
> +
> +  ///
> +  /// Address of the original EFI_SPI_PERIPHERAL data structure associated
> with
> +  /// this protocol instance.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
> +
> +  ///
> +  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of N-
> bits
> +  /// is supported when bit N-1 is set. The host controller must support a
> +  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted to
> +  /// 8-bit frame sizes by the SPI bus layer if the frame size is not supported
> +  /// by the SPI host controller.
> +  ///
> +  UINT32                                    FrameSizeSupportMask;
> +
> +  ///
> +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> +  ///
> +  UINT32                                    MaximumTransferBytes;
> +
> +  ///
> +  /// Transaction attributes: One or more from:
> +  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> +  ///   - The SPI host and peripheral supports a 2-bit data bus
> +  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> +  ///   - The SPI host and peripheral supports a 4-bit data bus
> +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> +  ///   - Transfer size includes the opcode byte
> +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> +  ///   - Transfer size includes the 3 address bytes
> +  ///
> +  UINT32                                    Attributes;
> +
> +  ///
> +  /// Pointer to legacy SPI controller protocol
> +  ///
> +  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *LegacySpiProtocol;
> +
> +  ///
> +  /// Initiate a SPI transaction between the host and a SPI peripheral.
> +  ///
> +  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
> +
> +  ///
> +  /// Update the SPI peripheral associated with this SPI 10 instance.
> +  ///
> +  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL UpdateSpiPeripheral;
> +};
> +
> +#endif // __SPI_IO_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h
> b/MdePkg/Include/Protocol/SpiNorFlash.h
> new file mode 100644
> index 000000000000..93d2adaa860e
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiNorFlash.h
> @@ -0,0 +1,289 @@
> +/** @file
> +  This file defines the SPI NOR Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
> +#define __SPI_NOR_FLASH_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +
> +///
> +/// Global ID for the SPI NOR Flash Protocol
> +///
> +#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
> +  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
> +    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> +
> +typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL
> EFI_SPI_NOR_FLASH_PROTOCOL;
> +
> +/**
> +  Read the 3 byte manufacture and device ID from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads the 3 byte manufacture and device ID from the flash
> part
> +  filling the buffer provided.
> +
> +  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> structure.
> +  @param[out] Buffer  Pointer to a 3 byte buffer to receive the manufacture
> and
> +                      device ID.
> +
> +
> +
> +  @retval EFI_SUCCESS            The manufacture and device ID was read
> +                                 successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL
> +  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Read data from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads data from the SPI part in the buffer provided.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  FlashAddress   Address in the flash to start reading
> +  @param[in]  LengthInBytes  Read length in bytes
> +  @param[out] Buffer         Address of a buffer to receive the data
> +
> +  @retval EFI_SUCCESS            The data was read successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            FlashAddress,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Low frequency read data from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads data from the SPI part in the buffer provided.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  FlashAddress   Address in the flash to start reading
> +  @param[in]  LengthInBytes  Read length in bytes
> +  @param[out] Buffer         Address of a buffer to receive the data
> +
> +  @retval EFI_SUCCESS            The data was read successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            FlashAddress,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Read the flash status register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads the flash part status register.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  LengthInBytes  Number of status bytes to read.
> +  @param[out] FlashStatus    Pointer to a buffer to receive the flash status.
> +
> +  @retval EFI_SUCCESS  The status register was read successfully.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *FlashStatus
> +  );
> +
> +/**
> +  Write the flash status register.
> +
> +  This routine must be called at or below TPL_N OTIFY.
> +  This routine writes the flash part status register.
> +
> +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                            structure.
> +  @param[in] LengthInBytes  Number of status bytes to write.
> +  @param[in] FlashStatus    Pointer to a buffer containing the new status.
> +
> +  @retval EFI_SUCCESS           The status write was successful.
> +  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            LengthInBytes,
> +  IN UINT8                             *FlashStatus
> +  );
> +
> +/**
> +  Write data to the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine breaks up the write operation as necessary to write the data
> to
> +  the SPI part.
> +
> +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                            structure.
> +  @param[in] FlashAddress   Address in the flash to start writing
> +  @param[in] LengthInBytes  Write length in bytes
> +  @param[in] Buffer         Address of a buffer containing the data
> +
> +  @retval EFI_SUCCESS            The data was written successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            FlashAddress,
> +  IN UINT32                            LengthInBytes,
> +  IN UINT8                             *Buffer
> +  );
> +
> +/**
> +  Efficiently erases one or more 4KiB regions in the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine uses a combination of 4 KiB and larger blocks to erase the
> +  specified area.
> +
> +  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                           structure.
> +  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
> +  @param[in] BlockCount    Number of 4 KiB blocks to erase
> +
> +  @retval EFI_SUCCESS            The erase was completed successfully.
> +  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
> +                                 BlockCount * 4 KiB
> +                                   > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            FlashAddress,
> +  IN UINT32                            BlockCount
> +  );
> +
> +///
> +/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral layer.
> +/// This protocol manipulates the SPI NOR flash parts using a common set of
> +/// commands. The board layer provides the interconnection and
> configuration
> +/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
> +/// configuration data to expose a generic interface which provides the
> +/// following APls:
> +/// * Read manufacture and device ID
> +/// * Read data
> +/// * Read data using low frequency
> +/// * Read status
> +/// * Write data
> +/// * Erase 4 KiB blocks
> +/// * Erase 32 or 64 KiB blocks
> +/// * Write status
> +/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set the
> security
> +/// features on the legacy SPI flash controller.
> +///
> +struct _EFI_SPI_NOR_FLASH_PROTOCOL {
> +  ///
> +  /// Pointer to an EFI_SPI_PERIPHERAL data structure
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
> +
> +  ///
> +  /// Flash size in bytes
> +  ///
> +  UINT32                                  FlashSize;
> +
> +  ///
> +  /// Manufacture and Device ID
> +  ///
> +  UINT8                                   Deviceid[3];
> +
> +  ///
> +  /// Erase block size in bytes
> +  ///
> +  UINT32                                  EraseBlockBytes;
> +
> +  ///
> +  /// Read the 3 byte manufacture and device ID from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
> +
> +  ///
> +  /// Read data from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
> +
> +  ///
> +  /// Low frequency read data from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
> +
> +  ///
> +  /// Read the flash status register.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
> +
> +  ///
> +  /// Write the flash status register.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
> +
> +  ///
> +  /// Write data to the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
> +
> +  ///
> +  /// Efficiently erases one or more 4KiB regions in the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
> +};
> +
> +extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
> +
> +#endif // __SPI_NOR_FLASH_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> new file mode 100644
> index 000000000000..913d4cbb46aa
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the SPI SMM Configuration Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +
> +///
> +/// Global ID for the SPI SMM Configuration Protocol
> +///
> +#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
> +  { 0x995c6eca, 0x171b, 0x45fd,                  \
> +    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> +
> +typedef
> +struct _EFI_SPI_CONFIGURATION_PROTOCOL
> +EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
> +
> +#endif // __SPI_SMM_CONFIGURATION_H__
> diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h
> b/MdePkg/Include/Protocol/SpiSmmHc.h
> new file mode 100644
> index 000000000000..91d2312b74b4
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiSmmHc.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the SPI SMM Host Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_SMM_HC_H__
> +#define __SPI_SMM_HC_H__
> +
> +#include <Protocol/SpiHc.h>
> +
> +///
> +/// Global ID for the SPI SMM Host Controller Protocol
> +///
> +#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
> +  { 0xe9f02217, 0x2093, 0x4470,       \
> +    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> +
> +typedef
> +struct _EFI_SPI_HC_PROTOCOL
> +EFI_SPI_SMM_HC_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
> +
> +#endif // __SPI_SMM_HC_H__
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 1867c54c3bc1..91af6c5c455c 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -1246,6 +1246,37 @@ [Protocols]
>    gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd,
> { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
> 
>    #
> +  # Protocols defined in PI 1.6.
> +  #
> +
> +  ## Include/Protocol/LegacySpiController.h
> +  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de,
> { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> +
> +  ## Include/Protocol/LegacySpiFlash.h
> +  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, { 0x96,
> 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> +
> +  ## Include/Protocol/LegacySpiSmmController.h
> +  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0, 0x4c8c,
> { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> +
> +  ## Include/Protocol/LegacySpiSmmFlash.h
> +  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0,
> { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> +
> +  ## Include/Protocol/SpiConfiguration.h
> +  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, { 0xb3,
> 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> +
> +  ## Include/Protocol/SpiHc.h
> +  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3, 0x99,
> 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> +
> +  ## Include/Protocol/SpiNorFlash.h
> +  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, { 0x85,
> 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> +
> +  ## Include/Protocol/SpiSmmConfiguration.h
> +  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b, 0x45fd,
> { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> +
> +  ## Include/Protocol/SpiSmmHc.h
> +  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, { 0x8a,
> 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> +
> +  #
>    # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
>    #
> 
> --
> 2.12.2.windows.2
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Marvin Häuser 6 years, 7 months ago
Hey Dandan,

Sorry for the mistakes, I will send them a part of a V2 once you finished reviewing.
No problem for the delay, it's not high priority at all. Thanks for reviewing it!

There are problems within the specification regarding the SPI protocols anyway.
I wanted to report these, though I don't know where to. Andrew suggested to post to the FW/OS Forum,
though it is currently not available, so I'm awaiting response from the UEFI Forum administration.

Best regards,
Marvin.

> -----Original Message-----
> From: Bi, Dandan [mailto:dandan.bi@intel.com]
> Sent: Friday, September 15, 2017 10:22 AM
> To: Ni, Ruiyu <ruiyu.ni@intel.com>; Marvin Häuser
> <Marvin.Haeuser@outlook.com>; edk2-devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Hi Marvin,
> 
> Thank you for your contribution. I am reviewing this patch now. Currently I
> just take a look at the SMM SPI part and find:
> 
> 1. There is a typo in LegacySpiSmmController.h
> The definition should be EFI_LEGACY_SPI_SMM_CONTROLLER_GUID, not
> EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID.
> Typo:
> #define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
>   { 0x62331b78, 0xd8d0, 0x4c8c,                 \
>     { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> And it should  be:
> #define EFI_LEGACY_SPI_SMM_CONTROLLER_GUID \
> { 0x62331b78, 0xd8d0, 0x4c8c, { 0x8c, 0xcb, 0xd2, 0x7d, \ 0xfe, 0x32, 0xdb,
> 0x9b }}
> 
> 2. EFI_SPI_SMM_NOR_FLASH_PROTOCOL definition seems to be missing.
> 
> I will review the remaining part. It may take some time. Sorry for the delay in
> my response
> 
> Thanks,
> Dandan
> 
> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Thursday, September 7, 2017 3:13 PM
> To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-
> devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Bi, Dandan <dandan.bi@intel.com>
> Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Marvin,
> Thank you for your contribution. We will need some time to review the
> definitions against PI Spec.
> If there is a need to post V2, it might be better to separate the header files in
> different groups.
> For example, LegacySpi group, SPI group, SMM SPI group.
> 
> Thanks/Ray
> 
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Marvin Häuser
> > Sent: Wednesday, September 6, 2017 5:21 PM
> > To: edk2-devel@lists.01.org
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>
> > Subject: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > introduced in UEFI PI 1.6.
> >
> > This commit adds header files for the SPI protocols introduced in the
> > UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.
> >
> > EFI_SPI_TRANSACTION_TYPE assumes an enum with its members ordered
> > the
> > way they are listed in the specification, as there are no values given
> > explicitely.
> > EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in the
> > specification was meant to be '1'.
> >
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
> > ---
> >  MdePkg/Include/Protocol/LegacySpiController.h    | 265
> > ++++++++++++++++++
> >  MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
> >  MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
> >  MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
> >  MdePkg/Include/Protocol/SpiConfiguration.h       | 293
> > ++++++++++++++++++++
> >  MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
> >  MdePkg/Include/Protocol/SpiIo.h                  | 292 +++++++++++++++++++
> >  MdePkg/Include/Protocol/SpiNorFlash.h            | 289
> > +++++++++++++++++++
> >  MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
> >  MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
> >  MdePkg/MdePkg.dec                                |  31 +++
> >  11 files changed, 1709 insertions(+)
> >
> > diff --git a/MdePkg/Include/Protocol/LegacySpiController.h
> > b/MdePkg/Include/Protocol/LegacySpiController.h
> > new file mode 100644
> > index 000000000000..2d36eaefc0ee
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiController.h
> > @@ -0,0 +1,265 @@
> > +/** @file
> > +  This file defines the Legacy SPI Controller Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > +#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > +
> > +///
> > +/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
> > +///       definition. This definition assumes it was supposed to be '1'.
> > +///
> > +/// Global ID for the Legacy SPI Controller Protocol
> > +///
> > +#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
> > +  { 0x39136fc7, 0x1a11, 0x49de,         \
> > +    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > +
> > +typedef
> > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
> > +
> > +/**
> > +  Set the erase block opcode.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The menu table contains SPI transaction opcodes which are accessible
> > after
> > +  the legacy SPI flash controller's configuration is locked. The board layer
> > +  specifies the erase block size for the SPI NOR flash part. The SPI NOR
> flash
> > +  peripheral driver selects the erase block opcode which matches the
> erase
> > +  block size and uses this API to load the opcode into the opcode menu
> table.
> > +
> > +  @param[in] This              Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                               structure.
> > +  @param[in] EraseBlockOpcode  Erase block opcode to be placed into the
> > opcode
> > +                               menu table.
> > +
> > +  @retval EFI_SUCCESS       The opcode menu table was updated
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT8                                     EraseBlockOpcode
> > +  );
> > +
> > +/**
> > +  Set the write status prefix opcode.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The prefix table contains SPI transaction write prefix opcodes which are
> > +  accessible after the legacy SPI flash controller's configuration is locked.
> > +  The board layer specifies the write status prefix opcode for the SPI NOR
> > +  flash part. The SPI NOR flash peripheral driver uses this API to load the
> > +  opcode into the prefix table.
> > +
> > +  @param[in] This               Pointer to an
> > +                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
> > +  @param[in] WriteStatusPrefix  Prefix opcode for the write status
> > command.
> > +
> > +  @retval EFI_SUCCESS       The prefix table was updated
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT8                                     WriteStatusPrefix
> > +  );
> > +
> > +/**
> > +  Set the BIOS base address.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS base address works with the protect range registers to protect
> > +  portions of the SPI NOR flash from erase and write operat ions. The BIOS
> > +  calls this API prior to passing control to the OS loader.
> > +
> > +  @param[in] This             Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                              structure.
> > +  @param[in] BiosBaseAddress  The BIOS base address.
> > +
> > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater
> than
> > +                                 This->Maxi.mumOffset
> > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS)
> > (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT32 BiosBaseAddress
> > +  );
> > +
> > +/**
> > +  Clear the SPI protect range registers.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > +  range registers.
> > +
> > +  @param[in] This  Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > structure.
> > +
> > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT)
> > (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > +  );
> > +
> > +/**
> > +  Determine if the SPI range is protected.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > +
> > +  @param[in] This            Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                             structure.
> > +  @param[in] BiosAddress     Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval TRUE   The range is protected
> > +  @retval FALSE  The range is not protected
> > +
> > +**/
> > +typedef
> > +BOOLEAN
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT32                                    BiosAddress,
> > +  IN UINT32                                    BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Set the next protect range register.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS sets the protect range register to prevent write and erase
> > +  operations to a portion of the SPI NOR flash device.
> > +
> > +  @param[in] This             Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                              structure.
> > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval EFI_SUCCESS            The register was successfully updated
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> >BiosBaseAddress,
> > or
> > +                                 BlocksToProtect * 4 KiB
> > +                                   > This->MaximumRangeBytes, or
> > +                                 BiosAddress - This->BiosBaseAddress
> > +                                   + (BlocksToProtect * 4 KiB)
> > +                                     > This->MaximumRangeBytes
> > +  @retval EFI_OUT_OF_RESOURCES  No protect range register available
> > +  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the
> > BIOS base
> > +                                address is not set
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT32                                    BiosAddress,
> > +  IN UINT32                                    BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Lock the SPI controller configuration.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine locks the SPI controller's configuration so that the software
> > +  is no longer able to update:
> > +  * Prefix table
> > +  * Opcode menu
> > +  * Opcode type table
> > +  * BIOS base address
> > +  * Protect range registers
> > +
> > +  @param[in] This  Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > structure.
> > +
> > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER)
> (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > +  );
> > +
> > +///
> > +/// Support the extra features of the legacy SPI flash controller.
> > +///
> > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
> > +  ///
> > +  /// Maximum offset from the BIOS base address that is able to be
> > protected.
> > +  ///
> > +  UINT32                                                 MaximumOffset;
> > +
> > +  ///
> > +  /// Maximum number of bytes that can be protected by one range
> register.
> > +  ///
> > +  UINT32                                                 MaximumRangeBytes;
> > +
> > +  ///
> > +  /// The number of registers available for protecting the BIOS.
> > +  ///
> > +  UINT32                                                 RangeRegisterCount;
> > +
> > +  ///
> > +  /// Set the erase block opcode.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE
> > EraseBlockOpcode;
> > +
> > +  ///
> > +  /// Set the write status prefix opcode.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX
> > WriteStatusPrefix;
> > +
> > +  ///
> > +  /// Set the BIOS base address.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS
> > BiosBaseAddress;
> > +
> > +  ///
> > +  /// Clear the SPI protect range registers.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT
> > ClearSpiProtect;
> > +
> > +  ///
> > +  /// Determine if the SPI range is protected.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED
> > IsRangeProtected;
> > +
> > +  ///
> > +  /// Set the next protect range register.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE
> > ProtectNextRange;
> > +
> > +  ///
> > +  /// Lock the SPI controller configuration.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER
> > LockController;
> > +};
> > +
> > +extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
> > +
> > +#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h
> > b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > new file mode 100644
> > index 000000000000..faa5f5724af7
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > @@ -0,0 +1,201 @@
> > +/** @file
> > +  This file defines the Legacy SPI Flash Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiNorFlash.h>
> > +
> > +///
> > +/// Global ID for the Legacy SPI Flash Protocol
> > +///
> > +#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
> > +  { 0xf01bed57, 0x04bc, 0x4f3f,             \
> > +    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > +
> > +typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > EFI_LEGACY_SPI_FLASH_PROTOCOL;
> > +
> > +/**
> > +  Set the BIOS base address.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS base address works with the protect range registers to protect
> > +  portions of the SPI NOR flash from erase and write operat ions.
> > +  The BIOS calls this API prior to passing control to the OS loader.
> > +
> > +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> > data
> > +                              structure.
> > +  @param[in] BiosBaseAddress  The BIOS base address.
> > +
> > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This-
> > >MaximumOffset
> > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> or
> > not a
> > +                                 legacy SPI host controller
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > +  IN UINT32                               BiosBaseAddress
> > +  );
> > +
> > +/**
> > +  Clear the SPI protect range registers.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > +  range registers.
> > +
> > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> > structure.
> > +
> > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > +  );
> > +
> > +/**
> > +  Determine if the SPI range is protected.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > +
> > +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> > data
> > +                              structure.
> > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval TRUE   The range is protected
> > +  @retval FALSE  The range is not protected
> > +
> > +**/
> > +typedef
> > +BOOLEAN
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > +  IN UINT32                               BiosAddress,
> > +  IN UINT32                               BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Set the next protect range register.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS sets the protect range register to prevent write and erase
> > +  operations to a portion of the SPI NOR flash device.
> > +
> > +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> > data
> > +                              structure.
> > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval EFI_SUCCESS            The register was successfully updated
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> >BiosBaseAddress,
> > or
> > +  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
> > +                                   > This->MaximumRangeBytes, or
> > +                                 BiosAddress - This->BiosBaseAddress
> > +                                   + (BlocksToProtect * 4 KiB)
> > +                                     > This->MaximumRangeBytes
> > +  @retval EFI_OUT_OF_RESOURCES   No protect range register available
> > +  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the
> > BIOS
> > +                                 base address is not set Not a legacy SPI host
> > +                                 controller
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > +  IN UINT32                               BiosAddress,
> > +  IN UINT32                               BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Lock the SPI controller configuration.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine locks the SPI controller's configuration so that the software is
> > +  no longer able to update:
> > +  * Prefix table
> > +  * Opcode menu
> > +  * Opcode type table
> > +  * BIOS base address
> > +  * Protect range registers
> > +
> > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> > structure.
> > +
> > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > +  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > +  );
> > +
> > +///
> > +/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the
> > EFI_SPI_NOR_FLASH_PROTOCOL
> > +/// with APls to support the legacy SPI flash controller.
> > +///
> > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
> > +  ///
> > +  /// This protocol manipulates the SPI NOR flash parts using a common set
> > of
> > +  /// commands.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
> > +
> > +  //
> > +  // Legacy flash (SPI host) controller support
> > +  //
> > +
> > +  ///
> > +  /// Set the BIOS base address.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS
> > BiosBaseAddress;
> > +
> > +  ///
> > +  /// Clear the SPI protect range registers.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT
> > ClearSpiProtect;
> > +
> > +  ///
> > +  /// Determine if the SPI range is protected.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED
> > IsRangeProtected;
> > +
> > +  ///
> > +  /// Set the next protect range register.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE
> > ProtectNextRange;
> > +
> > +  ///
> > +  /// Lock the SPI controller configuration.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER
> LockController;
> > +};
> > +
> > +extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
> > +
> > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > new file mode 100644
> > index 000000000000..6d8d557cefff
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the Legacy SPI SMM Controler Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > +#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > +
> > +#include <Protocol/LegacySpiController.h>
> > +
> > +///
> > +/// Global ID for the Legacy SPI SMM Controller Protocol
> > +///
> > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > +  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> > +    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > +
> > +typedef
> > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
> > +
> > +#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > new file mode 100644
> > index 000000000000..a604a22f901f
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the Legacy SPI SMM Flash Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > +#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > +
> > +#include <Protocol/LegacySpiFlash.h>
> > +
> > +///
> > +/// Global ID for the Legacy SPI SMM Flash Protocol
> > +///
> > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > +  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
> > +    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > +
> > +typedef
> > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > +EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
> > +
> > +#endif // __SPI_SMM_FLASH_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h
> > b/MdePkg/Include/Protocol/SpiConfiguration.h
> > new file mode 100644
> > index 000000000000..3a602f67d7a6
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiConfiguration.h
> > @@ -0,0 +1,293 @@
> > +/** @file
> > +  This file defines the SPI Configuration Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > +
> > +///
> > +/// Global ID for the SPI Configuration Protocol
> > +///
> > +#define EFI_SPI_CONFIGURATION_GUID  \
> > +  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
> > +    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > +
> > +///
> > +/// Macros to easily specify frequencies in hertz, kilohertz and megahertz.
> > +///
> > +#define Hz(Frequency)   (Frequency)
> > +#define KHz(Frequency)  (1000 * Hz (Frequency))
> > +#define MHz(Frequency)  (1000 * KHz (Frequency))
> > +
> > +typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
> > +
> > +/**
> > +  Manipulate the chip select for a SPI device.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  Update the value of the chip select line for a SPI peripheral.
> > +  The SPI bus layer calls this routine either in the board layer or in the SPI
> > +  controller to manipulate the chip select pin at the start and end of a SPI
> > +  transaction.
> > +
> > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > structure
> > +                            describing the SPI peripheral whose chip select pin
> > +                            is to be manipulated. The routine may access the
> > +                            ChipSelectParameter field to gain sufficient
> > +                            context to complete the operation.
> > +  @param[in] PinValue       The value to be applied to the chip select line of
> > +                            the SPI peripheral.
> > +
> > +  @retval EFI_SUCCESS            The chip select was set successfully
> > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > +                                 initialized
> > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral-
> > >ChipSelectParameter value
> > +                                 is invalid
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_CHIP_SELECT) (
> > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > +  IN BOOLEAN                   PinValue
> > +  );
> > +
> > +/**
> > +  Set up the clock generator to produce the correct clock frequency, phase
> > and
> > +  polarity for a SPI chip.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine updates the clock generator to generate the correct
> > frequency
> > +  and polarity for the SPI clock.
> > +
> > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> structure
> > from
> > +                            which the routine can access the ClockParameter,
> > +                            ClockPhase and ClockPolarity fields. The routine
> > +                            also has access to the names for the SPI bus and
> > +                            chip which can be used during debugging.
> > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> > clock
> > +                            generator will choose a supported clock frequency
> > +                            which is less then or equal to this value.
> > +                            Specify zero to turn the clock generator off.
> > +                            The actual clock frequency supported by the clock
> > +                            generator will be returned.
> > +
> > +  @retval EFI_SUCCESS      The clock was set up successfully
> > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> the
> > +                           frequency requested by CLockHz
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_CLOCK) (
> > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > +  IN UINT32                    *ClockHz
> > +  );
> > +
> > +///
> > +/// The EFI_SPI_PART data structure provides a description of a SPI part
> > which
> > +/// is independent of the use on the board. This data is available directly
> > +/// from the part's datasheet and may be provided by the vendor.
> > +///
> > +typedef struct _EFI_SPI_PART {
> > +  ///
> > +  /// A Unicode string specifying the SPI chip vendor.
> > +  ///
> > +  CONST CHAR16 *Vendor;
> > +
> > +  ///
> > +  /// A Unicode string specifying the SPI chip part number.
> > +  ///
> > +  CONST CHAR16 *PartNumber;
> > +
> > +  ///
> > +  /// The minimum SPI bus clock frequency used to access this chip. This
> > value
> > +  /// may be specified in the chip's datasheet. If not, use the value of zero.
> > +  ///
> > +  UINT32       MinClockHz;
> > +
> > +  ///
> > +  /// The maximum SPI bus clock frequency used to access this chip. This
> > value
> > +  /// is found in the chip's datasheet.
> > +  ///
> > +  UINT32       MaxClockHz;
> > +
> > +  ///
> > +  /// Specify the polarity of the chip select pin. This value can be found in
> > +  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip
> > select
> > +  ///and FALSE when a zero asserts the chip select.
> > +  ///
> > +  BOOLEAN      ChipSelectPolarity;
> > +} EFI_SPI_PART;
> > +
> > +///
> > +/// The EFI_SPI_BUS data structure provides the connection details
> > between the
> > +/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which
> controls
> > that
> > +/// SPI bus. This data structure also describes the details of how the clock
> is
> > +/// generated for that SPI bus. Finally this data structure provides the list
> > +/// of physical SPI devices which are attached to the SPI bus.
> > +///
> > +typedef struct _EFI_SPI_BUS {
> > +  ///
> > +  /// A Unicode string describing the SPI bus
> > +  ///
> > +  CONST CHAR16                   *FriendlyName;
> > +
> > +  ///
> > +  /// Address of the first EFI_SPI_PERIPHERAL data structure connected to
> > this
> > +  /// bus. Specify NULL if there are no SPI peripherals connected to this
> bus.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
> > +
> > +  ///
> > +  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which
> > uniquely
> > +  /// describes the SPI controller.
> > +  ///
> > +  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
> > +
> > +  ///
> > +  /// Address of the routine which controls the clock used by the SPI bus
> for
> > +  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
> > +  /// when this value is set to NULL.
> > +  ///
> > +  EFI_SPI_CLOCK                  Clock;
> > +
> > +  ///
> > +  /// Address of a data structure containing the additional values which
> > +  /// describe the necessary control for the clock. When Clock is NULL,
> > +  /// the declaration for this data structure is provided by the vendor of
> the
> > +  /// host's SPI controller driver. When Clock is not NULL, the declaration
> for
> > +  /// this data structure is provided by the board layer.
> > +  ///
> > +  VOID                           *ClockParameter;
> > +} EFI_SPI_BUS;
> > +
> > +///
> > +/// The EFI_SPI_PERIPHERAL data structure describes how a specific block
> > of
> > +/// logic which is connected to the SPI bus. This data structure also selects
> > +/// which upper level driver is used to manipulate this SPI device.
> > +/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
> > +/// peripheral driver.
> > +///
> > +struct _EFI_SPI_PERIPHERAL {
> > +  ///
> > +  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify
> NULL
> > if
> > +  /// the current data structure is the last one on the SPI bus.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
> > +
> > +  ///
> > +  /// A unicode string describing the function of the SPI part.
> > +  ///
> > +  CONST CHAR16             *FriendlyName;
> > +
> > +  ///
> > +  /// Address of a GUID provided by the vendor of the SPI peripheral
> driver.
> > +  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus driver
> > uses
> > +  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and to
> > +  /// provide the connection points for the SPI peripheral drivers.
> > +  /// This reduces the comparison logic in the SPI peripheral driver's
> > +  /// Supported routine.
> > +  ///
> > +  CONST GUID               *SpiPeripheralDriverGuid;
> > +
> > +  ///
> > +  /// The address of an EFI_SPI_PART data structure which describes this
> > chip.
> > +  ///
> > +  CONST EFI_SPI_PART       *SpiPart;
> > +
> > +  ///
> > +  /// The maximum clock frequency is specified in the EFI_SPI_P ART.
> When
> > this
> > +  /// this value is non-zero and less than the value in the EFI_SPI_PART
> then
> > +  /// this value is used for the maximum clock frequency for the SPI part.
> > +  ///
> > +  UINT32                   MaxClockHz;
> > +
> > +  ///
> > +  /// Specify the idle value of the clock as found in the datasheet.
> > +  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
> > +  /// clock's idle value is high.
> > +  ///
> > +  BOOLEAN                  ClockPolarity;
> > +
> > +  ///
> > +  /// Specify the clock delay after chip select. Specify zero (0) to delay an
> > +  /// entire clock cycle or one (1) to delay only half a clock cycle.
> > +  ///
> > +  BOOLEAN                  ClockPhase;
> > +
> > +  ///
> > +  /// SPI peripheral attributes, select zero or more of:
> > +  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI
> > peripheral is wired to
> > +  ///   support a 2-bit data bus
> > +  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI
> > peripheral is wired to
> > +  ///   support a 4-bit data bus
> > +  ///
> > +  UINT32                   Attributes;
> > +
> > +  ///
> > +  /// Address of a vendor specific data structure containing additional
> board
> > +  /// configuration details related to the SPI chip. The SPI peripheral layer
> > +  /// uses this data structure when configuring the chip.
> > +  ///
> > +  CONST VOID               *ConfigurationData;
> > +
> > +  ///
> > +  /// The address of an EFI_SPI_BUS data structure which describes the SPI
> > bus
> > +  /// to which this chip is connected.
> > +  ///
> > +  CONST EFI_SPI_BUS        *SpiBus;
> > +
> > +  ///
> > +  /// Address of the routine which controls the chip select pin for this SPI
> > +  /// peripheral. Call the SPI host controller's chip select routine when this
> > +  /// value is set to NULL.
> > +  ///
> > +  EFI_SPI_CHIP_SELECT      ChipSelect;
> > +
> > +  ///
> > +  /// Address of a data structure containing the additional values which
> > +  /// describe the necessary control for the chip select. When ChipSelect is
> > +  /// NULL, the declaration for this data structure is provided by the
> vendor
> > +  /// of the host's SPI controller driver. The vendor's documentation
> > specifies
> > +  /// the necessary values to use for the chip select pin selection and
> > +  /// control. When Chipselect is not NULL, the declaration for this data
> > +  /// structure is provided by the board layer.
> > +  ///
> > +  VOID                     *ChipSelectParameter;
> > +};
> > +
> > +///
> > +/// Describe the details of the board's SPI busses to the SPI driver stack.
> > +/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to
> > expose the data
> > +/// tables which describe the board's SPI busses, The SPI bus layer uses
> > these
> > +/// tables to configure the clock, chip select and manage the SPI
> > transactions
> > +/// on the SPI controllers.
> > +///
> > +typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
> > +  ///
> > +  /// The number of SPI busses on the board.
> > +  ///
> > +  UINT32                          BusCount;
> > +
> > +  ///
> > +  /// The address of an array of EFI_SPI_BUS data structure addresses.
> > +  ///
> > +  CONST EFI_SPI_BUS *CONST *CONST Buslist;
> > +} EFI_SPI_CONFIGURATION_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
> > +
> > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiHc.h
> > b/MdePkg/Include/Protocol/SpiHc.h
> > new file mode 100644
> > index 000000000000..13ad5f45225c
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiHc.h
> > @@ -0,0 +1,194 @@
> > +/** @file
> > +  This file defines the SPI Host Controller Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_HC_PROTOCOL_H__
> > +#define __SPI_HC_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiConfiguration.h>
> > +#include <Protocol/SpiIo.h>
> > +
> > +///
> > +/// Global ID for the SPI Host Controller Protocol
> > +///
> > +#define EFI_SPI_HOST_GUID  \
> > +  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
> > +    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > +
> > +///
> > +/// EDK2-style name
> > +///
> > +#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
> > +
> > +typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
> > +
> > +/**
> > +  Assert or deassert the SPI chip select.
> > +
> > +  This routine is called at TPL_NOTIFY.
> > +  Update the value of the chip select line for a SPI peripheral. The SPI bus
> > +  layer calls this routine either in the board layer or in the SPI controller
> > +  to manipulate the chip select pin at the start and end of a SPI transaction.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > structure
> > +                            describing the SPI peripheral whose chip select pin
> > +                            is to be manipulated. The routine may access the
> > +                            ChipSelectParameter field to gain sufficient
> > +                            context to complete the operati on.
> > +  @param[in] PinValue       The value to be applied to the chip select line of
> > +                            the SPI peripheral.
> > +
> > +  @retval EFI_SUCCESS            The chip select was set as requested
> > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > +                                 initialized
> > +  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its contents
> > are
> > +                                 invalid
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
> > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > +  IN BOOLEAN                    PinValue
> > +  );
> > +
> > +/**
> > +  Set up the clock generator to produce the correct clock frequency, phase
> > and
> > +  polarity for a SPI chip.
> > +
> > +  This routine is called at TPL_NOTIFY.
> > +  This routine updates the clock generator to generate the correct
> > frequency
> > +  and polarity for the SPI clock.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> structure
> > from
> > +                            which the routine can access the ClockParameter,
> > +                            ClockPhase and ClockPolarity fields. The routine
> > +                            also has access to the names for the SPI bus and
> > +                            chip which can be used during debugging.
> > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> SPI
> > +                            host controller will choose a supported clock
> > +                            frequency which is less then or equal to this
> > +                            value. Specify zero to turn the clock generator
> > +                            off. The actual clock frequency supported by the
> > +                            SPI host controller will be returned.
> > +
> > +  @retval EFI_SUCCESS      The clock was set up successfully
> > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> the
> > +                           frequency requested by ClockHz
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
> > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > +  IN UINT32                      *ClockHz
> > +  );
> > +
> > +/**
> > +  Perform the SPI transaction on the SPI peripheral using the SPI host
> > +  controller.
> > +
> > +  This routine is called at TPL_NOTIFY.
> > +  This routine synchronously returns EFI_SUCCESS indicating that the
> > +  asynchronous SPI transaction was started. The routine then waits for
> > +  completion of the SPI transaction prior to returning the final transaction
> > +  status.
> > +
> > +  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > +  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION
> > containing
> > +                             the description of the SPI transaction to perform.
> > +
> > +  @retval EFI_SUCCESS          The transaction completed successfully
> > +  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value is
> > invalid,
> > +                               or the BusTransaction->ReadinBytes value is
> > +                               invalid
> > +  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type is
> > +                               unsupported
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > +  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
> > +  );
> > +
> > +///
> > +/// Support a SPI data transaction between the SPI controller and a SPI
> chip.
> > +///
> > +struct _EFI_SPI_HC_PROTOCOL {
> > +  ///
> > +  /// Host control attributes, may have zero or more of the following set:
> > +  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> > +  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> > +  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> > +  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > +  ///   - The SPI host controller requires the transmit frame to be in most
> > +  ///     significant bits instead of least significant bits.The host driver
> > +  ///     will adjust the frames if necessary.
> > +  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > +  ///   - The SPI host controller places the receive frame to be in most
> > +  ///     significant bits instead of least significant bits.The host driver
> > +  ///     will adjust the frames to be in the least significant bits if
> > +  ///     necessary.
> > +  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
> > +  ///   - The SPI controller supports a 2 - bit data bus
> > +  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> > +  ///   - The SPI controller supports a 4 - bit data bus
> > +  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> > +  ///   - Transfer size includes the opcode byte
> > +  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> > +  ///   - Transfer size includes the 3 address bytes
> > +  /// The SPI host controller must support full - duplex (receive while
> > +  /// sending) operation.The SPI host controller must support a 1 - bit bus
> > +  /// width.
> > +  ///
> > +  UINT32                          Attributes;
> > +
> > +  ///
> > +  /// Mask of frame sizes which the SPI host controller supports. Frame
> size
> > of
> > +  /// N-bits is supported when bit N-1 is set. The host controller must
> > support
> > +  /// a frame size of 8-bits.
> > +  ///
> > +  UINT32                          FrameSizeSupportMask;
> > +
> > +  ///
> > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > +  ///
> > +  UINT32                          MaximumTransferBytes;
> > +
> > +  ///
> > +  /// Assert or deassert the SPI chip select.
> > +  ///
> > +  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
> > +
> > +  ///
> > +  /// Set up the clock generator to produce the correct clock frequency,
> > phase
> > +  /// and polarity for a SPI chip.
> > +  ///
> > +  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
> > +
> > +  ///
> > +  /// Perform the SPI transaction on the SPI peripheral using the SPI host
> > +  /// controller.
> > +  ///
> > +  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
> > +};
> > +
> > +extern EFI_GUID gEfiSpiHcProtocolGuid;
> > +
> > +#endif // __SPI_HC_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiIo.h
> > b/MdePkg/Include/Protocol/SpiIo.h
> > new file mode 100644
> > index 000000000000..e481779acc58
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiIo.h
> > @@ -0,0 +1,292 @@
> > +/** @file
> > +  This file defines the SPI I/O Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_IO_PROTOCOL_H__
> > +#define __SPI_IO_PROTOCOL_H__
> > +
> > +#include <Protocol/LegacySpiController.h>
> > +#include <Protocol/SpiConfiguration.h>
> > +
> > +typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> > +
> > +///
> > +/// Note: The UEFI PI 1.6 specification does not specify values for the
> > +///       members below. The order matches the specification.
> > +///
> > +typedef enum {
> > +  ///
> > +  /// Data flowing in both direction between the host and
> > +  /// SPI peripheral.ReadBytes must equal WriteBytes and both
> ReadBuffer
> > and
> > +  /// WriteBuffer must be provided.
> > +  ///
> > +  SPI_TRANSACTION_FULL_DUPLEX,
> > +
> > +  ///
> > +  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> > +  /// zero.WriteBytes must be non - zero and WriteBuffer must be
> provided.
> > +  ///
> > +  SPI_TRANSACTION_WRITE_ONLY,
> > +
> > +  ///
> > +  /// Data flowing from the SPI peripheral to the host.WriteBytes must be
> > +  /// zero.ReadBytes must be non - zero and ReadBuffer must be
> provided.
> > +  ///
> > +  SPI_TRANSACTION_READ_ONLY,
> > +
> > +  ///
> > +  /// Data first flowing from the host to the SPI peripheral and then data
> > +  /// flows from the SPI peripheral to the host.These types of operations
> get
> > +  /// used for SPI flash devices when control data (opcode, address) must
> be
> > +  /// passed to the SPI peripheral to specify the data to be read.
> > +  ///
> > +  SPI_TRANSACTION_WRITE_THEN_READ
> > +} EFI_SPI_TRANSACTION_TYPE;
> > +
> > +/**
> > +  Initiate a SPI transaction between the host and a SPI peripheral.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine works with the SPI bus layer to pass the SPI transaction to
> the
> > +  SPI controller for execution on the SPI bus. There are four types of
> > +  supported transactions supported by this routine:
> > +  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> > +  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes = 0
> > +  * Read Only: ReadBuffer to receive data from SPI peripheral, WriteBytes
> =
> > 0
> > +  * Write Then Read: WriteBuffer contains control data to write to SPI
> > +                     peripheral before data is placed into the ReadBuffer.
> > +                     Both WriteBytes and ReadBytes must be non-zero.
> > +
> > +  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > +  @param[in]  TransactionType   Type of SPI transaction.
> > +  @param[in]  DebugTransaction  Set TRUE only when debugging is
> desired.
> > +                                Debugging may be turned on for a single SPI
> > +                                transaction. Only this transaction will display
> > +                                debugging messages. All other transactions with
> > +                                this value set to FALSE will not display any
> > +                                debugging messages.
> > +  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
> > +                                the maximum clock frequency supported by the
> > +                                SPI controller and part. Specify a non-zero
> > +                                value only when a specific SPI transaction
> > +                                requires a reduced clock rate.
> > +  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
> > +  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
> > +  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
> > +                                Specify zero for read-only operations.
> > +  @param[in]  WriteBuffer       The buffer containing data to be sent from
> the
> > +                                host to the SPI chip. Specify NULL for read
> > +                                only operations.
> > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > +                                  frame
> > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > +                                  frame
> > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > +                                  per frame The transmit frame is in the least
> > +                                  significant N bits.
> > +  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
> > +                                Specify zero for write-only operations.
> > +  @param[out] ReadBuffer        The buffer to receeive data from the SPI
> chip
> > +                                during the transaction. Specify NULL for write
> > +                                only operations.
> > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > +                                  frame
> > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > +                                  frame
> > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > +                                  per frame The received frame is in the least
> > +                                  significant N bits.
> > +
> > +  @retval EFI_SUCCESS            The SPI transaction completed successfully
> > +  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
> > +  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
> > +  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
> > +                                 or BusWidth not supported by SPI peripheral or
> > +                                 SPI host controller,
> > +                                 or WriteBytes non-zero and WriteBuffer is
> > +                                 NULL,
> > +                                 or ReadBytes non-zero and ReadBuffer is NULL,
> > +                                 or ReadBuffer != WriteBuffer for full-duplex
> > +                                 type,
> > +                                 or WriteBuffer was NULL,
> > +                                 or TPL is too high
> > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI
> transaction
> > +  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the
> SPI
> > bus
> > +                                 layer or the SPI host controller
> > +  @retval EFI_UNSUPPORTED        The SPI controller was not able to
> support
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> > +  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
> > +  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
> > +  IN  BOOLEAN                    DebugTransaction,
> > +  IN  UINT32                     ClockHz OPTIONAL,
> > +  IN  UINT32                     BusWidth,
> > +  IN  UINT32                     FrameSize,
> > +  IN  UINT32                     WriteBytes,
> > +  IN  UINT8                      *WriteBuffer,
> > +  IN  UINT32                     ReadBytes,
> > +  OUT UINT8                      *ReadBuffer
> > +  );
> > +
> > +/**
> > +  Update the SPI peripheral associated with this SPI 10 instance.
> > +
> > +  Support socketed SPI parts by allowing the SPI peripheral driver to
> replace
> > +  the SPI peripheral after the connection is made. An example use is
> > socketed
> > +  SPI NOR flash parts, where the size and parameters change depending
> > upon
> > +  device is in the socket.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > +  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL structure.
> > +
> > +  @retval EFI_SUCCESS            The SPI peripheral was updated successfully
> > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
> > +                                 or the SpiPeripheral->SpiBus is NULL,
> > +                                 or the SpiP eripheral - >SpiBus pointing at
> > +                                 wrong bus,
> > +                                 or the SpiP eripheral - >SpiPart is NULL
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> > +  IN CONST EFI_SPI_IO_PROTOCOL  *This,
> > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
> > +  );
> > +
> > +///
> > +/// The EFI_SPI_BUS_ TRANSACTION data structure contains the
> > description of the
> > +/// SPI transaction to perform on the host controller.
> > +///
> > +typedef struct _EFI_SPI_BUS_TRANSACTION {
> > +  ///
> > +  /// Pointer to the SPI peripheral being manipulated.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> > +
> > +  ///
> > +  /// Type of transaction specified by one of the
> > EFI_SPI_TRANSACTION_TYPE
> > +  /// values.
> > +  ///
> > +  EFI_SPI_TRANSACTION_TYPE TransactionType;
> > +
> > +  ///
> > +  /// TRUE if the transaction is being debugged. Debugging may be turned
> > on for
> > +  /// a single SPI transaction. Only this transaction will display debugging
> > +  /// messages. All other transactions with this value set to FALSE will not
> > +  /// display any debugging messages.
> > +  ///
> > +  BOOLEAN                  DebugTransaction;
> > +
> > +  ///
> > +  /// SPI bus width in bits: 1, 2, 4
> > +  ///
> > +  UINT32                   BusWidth;
> > +
> > +  ///
> > +  /// Frame size in bits, range: 1 - 32
> > +  ///
> > +  UINT32                   FrameSize;
> > +
> > +  ///
> > +  /// Length of the write buffer in bytes
> > +  ///
> > +  UINT32                   WriteBytes;
> > +
> > +  ///
> > +  /// Buffer containing data to send to the SPI peripheral
> > +  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > +  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > +  ///
> > +  UINT8                    *WriteBuffer;
> > +
> > +  ///
> > +  /// Length of the read buffer in bytes
> > +  ///
> > +  UINT32                   ReadBytes;
> > +
> > +  ///
> > +  /// Buffer to receive the data from the SPI peripheral
> > +  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > +  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > +  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> > +  ///
> > +  UINT8                    *ReadBuffer;
> > +} EFI_SPI_BUS_TRANSACTION;
> > +
> > +///
> > +/// Support managed SPI data transactions between the SPI controller
> and a
> > SPI
> > +/// chip.
> > +///
> > +struct _EFI_SPI_IO_PROTOCOL {
> > +  ///
> > +  /// Address of an EFI_SPI_PERIPHERAL data structure associated with
> this
> > +  /// protocol instance.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
> > +
> > +  ///
> > +  /// Address of the original EFI_SPI_PERIPHERAL data structure associated
> > with
> > +  /// this protocol instance.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
> > +
> > +  ///
> > +  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of N-
> > bits
> > +  /// is supported when bit N-1 is set. The host controller must support a
> > +  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted to
> > +  /// 8-bit frame sizes by the SPI bus layer if the frame size is not
> supported
> > +  /// by the SPI host controller.
> > +  ///
> > +  UINT32                                    FrameSizeSupportMask;
> > +
> > +  ///
> > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > +  ///
> > +  UINT32                                    MaximumTransferBytes;
> > +
> > +  ///
> > +  /// Transaction attributes: One or more from:
> > +  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> > +  ///   - The SPI host and peripheral supports a 2-bit data bus
> > +  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> > +  ///   - The SPI host and peripheral supports a 4-bit data bus
> > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> > +  ///   - Transfer size includes the opcode byte
> > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> > +  ///   - Transfer size includes the 3 address bytes
> > +  ///
> > +  UINT32                                    Attributes;
> > +
> > +  ///
> > +  /// Pointer to legacy SPI controller protocol
> > +  ///
> > +  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *LegacySpiProtocol;
> > +
> > +  ///
> > +  /// Initiate a SPI transaction between the host and a SPI peripheral.
> > +  ///
> > +  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
> > +
> > +  ///
> > +  /// Update the SPI peripheral associated with this SPI 10 instance.
> > +  ///
> > +  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL UpdateSpiPeripheral;
> > +};
> > +
> > +#endif // __SPI_IO_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h
> > b/MdePkg/Include/Protocol/SpiNorFlash.h
> > new file mode 100644
> > index 000000000000..93d2adaa860e
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiNorFlash.h
> > @@ -0,0 +1,289 @@
> > +/** @file
> > +  This file defines the SPI NOR Flash Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
> > +#define __SPI_NOR_FLASH_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiConfiguration.h>
> > +
> > +///
> > +/// Global ID for the SPI NOR Flash Protocol
> > +///
> > +#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
> > +  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
> > +    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > +
> > +typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL
> > EFI_SPI_NOR_FLASH_PROTOCOL;
> > +
> > +/**
> > +  Read the 3 byte manufacture and device ID from the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads the 3 byte manufacture and device ID from the flash
> > part
> > +  filling the buffer provided.
> > +
> > +  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> > structure.
> > +  @param[out] Buffer  Pointer to a 3 byte buffer to receive the
> manufacture
> > and
> > +                      device ID.
> > +
> > +
> > +
> > +  @retval EFI_SUCCESS            The manufacture and device ID was read
> > +                                 successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL
> > +  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  OUT UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Read data from the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads data from the SPI part in the buffer provided.
> > +
> > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                             structure.
> > +  @param[in]  FlashAddress   Address in the flash to start reading
> > +  @param[in]  LengthInBytes  Read length in bytes
> > +  @param[out] Buffer         Address of a buffer to receive the data
> > +
> > +  @retval EFI_SUCCESS            The data was read successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > +                                 FlashAddress >= This->FlashSize, or
> > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN  UINT32                            FlashAddress,
> > +  IN  UINT32                            LengthInBytes,
> > +  OUT UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Low frequency read data from the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads data from the SPI part in the buffer provided.
> > +
> > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                             structure.
> > +  @param[in]  FlashAddress   Address in the flash to start reading
> > +  @param[in]  LengthInBytes  Read length in bytes
> > +  @param[out] Buffer         Address of a buffer to receive the data
> > +
> > +  @retval EFI_SUCCESS            The data was read successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > +                                 FlashAddress >= This->FlashSize, or
> > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN  UINT32                            FlashAddress,
> > +  IN  UINT32                            LengthInBytes,
> > +  OUT UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Read the flash status register.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads the flash part status register.
> > +
> > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                             structure.
> > +  @param[in]  LengthInBytes  Number of status bytes to read.
> > +  @param[out] FlashStatus    Pointer to a buffer to receive the flash status.
> > +
> > +  @retval EFI_SUCCESS  The status register was read successfully.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN  UINT32                            LengthInBytes,
> > +  OUT UINT8                             *FlashStatus
> > +  );
> > +
> > +/**
> > +  Write the flash status register.
> > +
> > +  This routine must be called at or below TPL_N OTIFY.
> > +  This routine writes the flash part status register.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                            structure.
> > +  @param[in] LengthInBytes  Number of status bytes to write.
> > +  @param[in] FlashStatus    Pointer to a buffer containing the new status.
> > +
> > +  @retval EFI_SUCCESS           The status write was successful.
> > +  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
> > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN UINT32                            LengthInBytes,
> > +  IN UINT8                             *FlashStatus
> > +  );
> > +
> > +/**
> > +  Write data to the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine breaks up the write operation as necessary to write the data
> > to
> > +  the SPI part.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                            structure.
> > +  @param[in] FlashAddress   Address in the flash to start writing
> > +  @param[in] LengthInBytes  Write length in bytes
> > +  @param[in] Buffer         Address of a buffer containing the data
> > +
> > +  @retval EFI_SUCCESS            The data was written successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > +                                 FlashAddress >= This->FlashSize, or
> > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy buffer.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
> > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN UINT32                            FlashAddress,
> > +  IN UINT32                            LengthInBytes,
> > +  IN UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Efficiently erases one or more 4KiB regions in the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine uses a combination of 4 KiB and larger blocks to erase the
> > +  specified area.
> > +
> > +  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> > +                           structure.
> > +  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
> > +  @param[in] BlockCount    Number of 4 KiB blocks to erase
> > +
> > +  @retval EFI_SUCCESS            The erase was completed successfully.
> > +  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
> > +                                 BlockCount * 4 KiB
> > +                                   > This->FlashSize - FlashAddress
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
> > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN UINT32                            FlashAddress,
> > +  IN UINT32                            BlockCount
> > +  );
> > +
> > +///
> > +/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral layer.
> > +/// This protocol manipulates the SPI NOR flash parts using a common set
> of
> > +/// commands. The board layer provides the interconnection and
> > configuration
> > +/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
> > +/// configuration data to expose a generic interface which provides the
> > +/// following APls:
> > +/// * Read manufacture and device ID
> > +/// * Read data
> > +/// * Read data using low frequency
> > +/// * Read status
> > +/// * Write data
> > +/// * Erase 4 KiB blocks
> > +/// * Erase 32 or 64 KiB blocks
> > +/// * Write status
> > +/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set
> the
> > security
> > +/// features on the legacy SPI flash controller.
> > +///
> > +struct _EFI_SPI_NOR_FLASH_PROTOCOL {
> > +  ///
> > +  /// Pointer to an EFI_SPI_PERIPHERAL data structure
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
> > +
> > +  ///
> > +  /// Flash size in bytes
> > +  ///
> > +  UINT32                                  FlashSize;
> > +
> > +  ///
> > +  /// Manufacture and Device ID
> > +  ///
> > +  UINT8                                   Deviceid[3];
> > +
> > +  ///
> > +  /// Erase block size in bytes
> > +  ///
> > +  UINT32                                  EraseBlockBytes;
> > +
> > +  ///
> > +  /// Read the 3 byte manufacture and device ID from the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
> > +
> > +  ///
> > +  /// Read data from the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
> > +
> > +  ///
> > +  /// Low frequency read data from the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
> > +
> > +  ///
> > +  /// Read the flash status register.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
> > +
> > +  ///
> > +  /// Write the flash status register.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
> > +
> > +  ///
> > +  /// Write data to the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
> > +
> > +  ///
> > +  /// Efficiently erases one or more 4KiB regions in the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
> > +};
> > +
> > +extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
> > +
> > +#endif // __SPI_NOR_FLASH_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > new file mode 100644
> > index 000000000000..913d4cbb46aa
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the SPI SMM Configuration Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > +#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiConfiguration.h>
> > +
> > +///
> > +/// Global ID for the SPI SMM Configuration Protocol
> > +///
> > +#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
> > +  { 0x995c6eca, 0x171b, 0x45fd,                  \
> > +    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > +
> > +typedef
> > +struct _EFI_SPI_CONFIGURATION_PROTOCOL
> > +EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
> > +
> > +#endif // __SPI_SMM_CONFIGURATION_H__
> > diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h
> > b/MdePkg/Include/Protocol/SpiSmmHc.h
> > new file mode 100644
> > index 000000000000..91d2312b74b4
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiSmmHc.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the SPI SMM Host Controller Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_SMM_HC_H__
> > +#define __SPI_SMM_HC_H__
> > +
> > +#include <Protocol/SpiHc.h>
> > +
> > +///
> > +/// Global ID for the SPI SMM Host Controller Protocol
> > +///
> > +#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
> > +  { 0xe9f02217, 0x2093, 0x4470,       \
> > +    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > +
> > +typedef
> > +struct _EFI_SPI_HC_PROTOCOL
> > +EFI_SPI_SMM_HC_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
> > +
> > +#endif // __SPI_SMM_HC_H__
> > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> > index 1867c54c3bc1..91af6c5c455c 100644
> > --- a/MdePkg/MdePkg.dec
> > +++ b/MdePkg/MdePkg.dec
> > @@ -1246,6 +1246,37 @@ [Protocols]
> >    gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd,
> > { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
> >
> >    #
> > +  # Protocols defined in PI 1.6.
> > +  #
> > +
> > +  ## Include/Protocol/LegacySpiController.h
> > +  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de,
> > { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > +
> > +  ## Include/Protocol/LegacySpiFlash.h
> > +  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, {
> 0x96,
> > 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > +
> > +  ## Include/Protocol/LegacySpiSmmController.h
> > +  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0,
> 0x4c8c,
> > { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > +
> > +  ## Include/Protocol/LegacySpiSmmFlash.h
> > +  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0,
> > { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > +
> > +  ## Include/Protocol/SpiConfiguration.h
> > +  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, {
> 0xb3,
> > 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > +
> > +  ## Include/Protocol/SpiHc.h
> > +  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3,
> 0x99,
> > 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > +
> > +  ## Include/Protocol/SpiNorFlash.h
> > +  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, { 0x85,
> > 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > +
> > +  ## Include/Protocol/SpiSmmConfiguration.h
> > +  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b, 0x45fd,
> > { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > +
> > +  ## Include/Protocol/SpiSmmHc.h
> > +  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, { 0x8a,
> > 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > +
> > +  #
> >    # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
> >    #
> >
> > --
> > 2.12.2.windows.2
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Zimmer, Vincent 6 years, 6 months ago
Marvin:

Thanks for all of the feedback on the SPI items from the most recent UEFI PI spec. We're updating the PI spec now responsive to your findings and these corrections will be reflected in an upcoming errata.

Sorry for the delayed response to you on the findings. I'll follow up w/ UEFI Forum on why we cannot readily use the fw/os forum mailing list for this type of discussion, too.

Vincent

-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Marvin Häuser
Sent: Friday, September 15, 2017 7:57 AM
To: edk2-devel@lists.01.org
Cc: Bi, Dandan <dandan.bi@intel.com>
Subject: Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.

Hey Dandan,

Sorry for the mistakes, I will send them a part of a V2 once you finished reviewing.
No problem for the delay, it's not high priority at all. Thanks for reviewing it!

There are problems within the specification regarding the SPI protocols anyway.
I wanted to report these, though I don't know where to. Andrew suggested to post to the FW/OS Forum,
though it is currently not available, so I'm awaiting response from the UEFI Forum administration.

Best regards,
Marvin.

> -----Original Message-----
> From: Bi, Dandan [mailto:dandan.bi@intel.com]
> Sent: Friday, September 15, 2017 10:22 AM
> To: Ni, Ruiyu <ruiyu.ni@intel.com>; Marvin Häuser
> <Marvin.Haeuser@outlook.com>; edk2-devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Hi Marvin,
> 
> Thank you for your contribution. I am reviewing this patch now. Currently I
> just take a look at the SMM SPI part and find:
> 
> 1. There is a typo in LegacySpiSmmController.h
> The definition should be EFI_LEGACY_SPI_SMM_CONTROLLER_GUID, not
> EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID.
> Typo:
> #define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
>   { 0x62331b78, 0xd8d0, 0x4c8c,                 \
>     { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> And it should  be:
> #define EFI_LEGACY_SPI_SMM_CONTROLLER_GUID \
> { 0x62331b78, 0xd8d0, 0x4c8c, { 0x8c, 0xcb, 0xd2, 0x7d, \ 0xfe, 0x32, 0xdb,
> 0x9b }}
> 
> 2. EFI_SPI_SMM_NOR_FLASH_PROTOCOL definition seems to be missing.
> 
> I will review the remaining part. It may take some time. Sorry for the delay in
> my response
> 
> Thanks,
> Dandan
> 
> -----Original Message-----
> From: Ni, Ruiyu
> Sent: Thursday, September 7, 2017 3:13 PM
> To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-
> devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Bi, Dandan <dandan.bi@intel.com>
> Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Marvin,
> Thank you for your contribution. We will need some time to review the
> definitions against PI Spec.
> If there is a need to post V2, it might be better to separate the header files in
> different groups.
> For example, LegacySpi group, SPI group, SMM SPI group.
> 
> Thanks/Ray
> 
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Marvin Häuser
> > Sent: Wednesday, September 6, 2017 5:21 PM
> > To: edk2-devel@lists.01.org
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>
> > Subject: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > introduced in UEFI PI 1.6.
> >
> > This commit adds header files for the SPI protocols introduced in the
> > UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.
> >
> > EFI_SPI_TRANSACTION_TYPE assumes an enum with its members ordered
> > the
> > way they are listed in the specification, as there are no values given
> > explicitely.
> > EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in the
> > specification was meant to be '1'.
> >
> > Contributed-under: TianoCore Contribution Agreement 1.1
> > Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
> > ---
> >  MdePkg/Include/Protocol/LegacySpiController.h    | 265
> > ++++++++++++++++++
> >  MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
> >  MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
> >  MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
> >  MdePkg/Include/Protocol/SpiConfiguration.h       | 293
> > ++++++++++++++++++++
> >  MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
> >  MdePkg/Include/Protocol/SpiIo.h                  | 292 +++++++++++++++++++
> >  MdePkg/Include/Protocol/SpiNorFlash.h            | 289
> > +++++++++++++++++++
> >  MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
> >  MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
> >  MdePkg/MdePkg.dec                                |  31 +++
> >  11 files changed, 1709 insertions(+)
> >
> > diff --git a/MdePkg/Include/Protocol/LegacySpiController.h
> > b/MdePkg/Include/Protocol/LegacySpiController.h
> > new file mode 100644
> > index 000000000000..2d36eaefc0ee
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiController.h
> > @@ -0,0 +1,265 @@
> > +/** @file
> > +  This file defines the Legacy SPI Controller Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > +#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > +
> > +///
> > +/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
> > +///       definition. This definition assumes it was supposed to be '1'.
> > +///
> > +/// Global ID for the Legacy SPI Controller Protocol
> > +///
> > +#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
> > +  { 0x39136fc7, 0x1a11, 0x49de,         \
> > +    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > +
> > +typedef
> > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
> > +
> > +/**
> > +  Set the erase block opcode.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The menu table contains SPI transaction opcodes which are accessible
> > after
> > +  the legacy SPI flash controller's configuration is locked. The board layer
> > +  specifies the erase block size for the SPI NOR flash part. The SPI NOR
> flash
> > +  peripheral driver selects the erase block opcode which matches the
> erase
> > +  block size and uses this API to load the opcode into the opcode menu
> table.
> > +
> > +  @param[in] This              Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                               structure.
> > +  @param[in] EraseBlockOpcode  Erase block opcode to be placed into the
> > opcode
> > +                               menu table.
> > +
> > +  @retval EFI_SUCCESS       The opcode menu table was updated
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT8                                     EraseBlockOpcode
> > +  );
> > +
> > +/**
> > +  Set the write status prefix opcode.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The prefix table contains SPI transaction write prefix opcodes which are
> > +  accessible after the legacy SPI flash controller's configuration is locked.
> > +  The board layer specifies the write status prefix opcode for the SPI NOR
> > +  flash part. The SPI NOR flash peripheral driver uses this API to load the
> > +  opcode into the prefix table.
> > +
> > +  @param[in] This               Pointer to an
> > +                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
> > +  @param[in] WriteStatusPrefix  Prefix opcode for the write status
> > command.
> > +
> > +  @retval EFI_SUCCESS       The prefix table was updated
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT8                                     WriteStatusPrefix
> > +  );
> > +
> > +/**
> > +  Set the BIOS base address.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS base address works with the protect range registers to protect
> > +  portions of the SPI NOR flash from erase and write operat ions. The BIOS
> > +  calls this API prior to passing control to the OS loader.
> > +
> > +  @param[in] This             Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                              structure.
> > +  @param[in] BiosBaseAddress  The BIOS base address.
> > +
> > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater
> than
> > +                                 This->Maxi.mumOffset
> > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS)
> > (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT32 BiosBaseAddress
> > +  );
> > +
> > +/**
> > +  Clear the SPI protect range registers.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > +  range registers.
> > +
> > +  @param[in] This  Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > structure.
> > +
> > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT)
> > (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > +  );
> > +
> > +/**
> > +  Determine if the SPI range is protected.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > +
> > +  @param[in] This            Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                             structure.
> > +  @param[in] BiosAddress     Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval TRUE   The range is protected
> > +  @retval FALSE  The range is not protected
> > +
> > +**/
> > +typedef
> > +BOOLEAN
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT32                                    BiosAddress,
> > +  IN UINT32                                    BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Set the next protect range register.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS sets the protect range register to prevent write and erase
> > +  operations to a portion of the SPI NOR flash device.
> > +
> > +  @param[in] This             Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +                              structure.
> > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval EFI_SUCCESS            The register was successfully updated
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> >BiosBaseAddress,
> > or
> > +                                 BlocksToProtect * 4 KiB
> > +                                   > This->MaximumRangeBytes, or
> > +                                 BiosAddress - This->BiosBaseAddress
> > +                                   + (BlocksToProtect * 4 KiB)
> > +                                     > This->MaximumRangeBytes
> > +  @retval EFI_OUT_OF_RESOURCES  No protect range register available
> > +  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the
> > BIOS base
> > +                                address is not set
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > +  IN UINT32                                    BiosAddress,
> > +  IN UINT32                                    BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Lock the SPI controller configuration.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine locks the SPI controller's configuration so that the software
> > +  is no longer able to update:
> > +  * Prefix table
> > +  * Opcode menu
> > +  * Opcode type table
> > +  * BIOS base address
> > +  * Protect range registers
> > +
> > +  @param[in] This  Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > structure.
> > +
> > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER)
> (
> > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > +  );
> > +
> > +///
> > +/// Support the extra features of the legacy SPI flash controller.
> > +///
> > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
> > +  ///
> > +  /// Maximum offset from the BIOS base address that is able to be
> > protected.
> > +  ///
> > +  UINT32                                                 MaximumOffset;
> > +
> > +  ///
> > +  /// Maximum number of bytes that can be protected by one range
> register.
> > +  ///
> > +  UINT32                                                 MaximumRangeBytes;
> > +
> > +  ///
> > +  /// The number of registers available for protecting the BIOS.
> > +  ///
> > +  UINT32                                                 RangeRegisterCount;
> > +
> > +  ///
> > +  /// Set the erase block opcode.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE
> > EraseBlockOpcode;
> > +
> > +  ///
> > +  /// Set the write status prefix opcode.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX
> > WriteStatusPrefix;
> > +
> > +  ///
> > +  /// Set the BIOS base address.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS
> > BiosBaseAddress;
> > +
> > +  ///
> > +  /// Clear the SPI protect range registers.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT
> > ClearSpiProtect;
> > +
> > +  ///
> > +  /// Determine if the SPI range is protected.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED
> > IsRangeProtected;
> > +
> > +  ///
> > +  /// Set the next protect range register.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE
> > ProtectNextRange;
> > +
> > +  ///
> > +  /// Lock the SPI controller configuration.
> > +  ///
> > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER
> > LockController;
> > +};
> > +
> > +extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
> > +
> > +#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h
> > b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > new file mode 100644
> > index 000000000000..faa5f5724af7
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > @@ -0,0 +1,201 @@
> > +/** @file
> > +  This file defines the Legacy SPI Flash Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiNorFlash.h>
> > +
> > +///
> > +/// Global ID for the Legacy SPI Flash Protocol
> > +///
> > +#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
> > +  { 0xf01bed57, 0x04bc, 0x4f3f,             \
> > +    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > +
> > +typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > EFI_LEGACY_SPI_FLASH_PROTOCOL;
> > +
> > +/**
> > +  Set the BIOS base address.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS base address works with the protect range registers to protect
> > +  portions of the SPI NOR flash from erase and write operat ions.
> > +  The BIOS calls this API prior to passing control to the OS loader.
> > +
> > +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> > data
> > +                              structure.
> > +  @param[in] BiosBaseAddress  The BIOS base address.
> > +
> > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This-
> > >MaximumOffset
> > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> or
> > not a
> > +                                 legacy SPI host controller
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > +  IN UINT32                               BiosBaseAddress
> > +  );
> > +
> > +/**
> > +  Clear the SPI protect range registers.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > +  range registers.
> > +
> > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> > structure.
> > +
> > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > +  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > +  );
> > +
> > +/**
> > +  Determine if the SPI range is protected.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > +
> > +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> > data
> > +                              structure.
> > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval TRUE   The range is protected
> > +  @retval FALSE  The range is not protected
> > +
> > +**/
> > +typedef
> > +BOOLEAN
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > +  IN UINT32                               BiosAddress,
> > +  IN UINT32                               BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Set the next protect range register.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  The BIOS sets the protect range register to prevent write and erase
> > +  operations to a portion of the SPI NOR flash device.
> > +
> > +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> > data
> > +                              structure.
> > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> protecting.
> > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > +
> > +  @retval EFI_SUCCESS            The register was successfully updated
> > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> >BiosBaseAddress,
> > or
> > +  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
> > +                                   > This->MaximumRangeBytes, or
> > +                                 BiosAddress - This->BiosBaseAddress
> > +                                   + (BlocksToProtect * 4 KiB)
> > +                                     > This->MaximumRangeBytes
> > +  @retval EFI_OUT_OF_RESOURCES   No protect range register available
> > +  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the
> > BIOS
> > +                                 base address is not set Not a legacy SPI host
> > +                                 controller
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > +  IN UINT32                               BiosAddress,
> > +  IN UINT32                               BlocksToProtect
> > +  );
> > +
> > +/**
> > +  Lock the SPI controller configuration.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine locks the SPI controller's configuration so that the software is
> > +  no longer able to update:
> > +  * Prefix table
> > +  * Opcode menu
> > +  * Opcode type table
> > +  * BIOS base address
> > +  * Protect range registers
> > +
> > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> > structure.
> > +
> > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > +  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
> > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > +  );
> > +
> > +///
> > +/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the
> > EFI_SPI_NOR_FLASH_PROTOCOL
> > +/// with APls to support the legacy SPI flash controller.
> > +///
> > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
> > +  ///
> > +  /// This protocol manipulates the SPI NOR flash parts using a common set
> > of
> > +  /// commands.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
> > +
> > +  //
> > +  // Legacy flash (SPI host) controller support
> > +  //
> > +
> > +  ///
> > +  /// Set the BIOS base address.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS
> > BiosBaseAddress;
> > +
> > +  ///
> > +  /// Clear the SPI protect range registers.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT
> > ClearSpiProtect;
> > +
> > +  ///
> > +  /// Determine if the SPI range is protected.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED
> > IsRangeProtected;
> > +
> > +  ///
> > +  /// Set the next protect range register.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE
> > ProtectNextRange;
> > +
> > +  ///
> > +  /// Lock the SPI controller configuration.
> > +  ///
> > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER
> LockController;
> > +};
> > +
> > +extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
> > +
> > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > new file mode 100644
> > index 000000000000..6d8d557cefff
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the Legacy SPI SMM Controler Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > +#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > +
> > +#include <Protocol/LegacySpiController.h>
> > +
> > +///
> > +/// Global ID for the Legacy SPI SMM Controller Protocol
> > +///
> > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > +  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> > +    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > +
> > +typedef
> > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > +EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
> > +
> > +#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > new file mode 100644
> > index 000000000000..a604a22f901f
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the Legacy SPI SMM Flash Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > +#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > +
> > +#include <Protocol/LegacySpiFlash.h>
> > +
> > +///
> > +/// Global ID for the Legacy SPI SMM Flash Protocol
> > +///
> > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > +  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
> > +    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > +
> > +typedef
> > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > +EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
> > +
> > +#endif // __SPI_SMM_FLASH_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h
> > b/MdePkg/Include/Protocol/SpiConfiguration.h
> > new file mode 100644
> > index 000000000000..3a602f67d7a6
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiConfiguration.h
> > @@ -0,0 +1,293 @@
> > +/** @file
> > +  This file defines the SPI Configuration Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > +
> > +///
> > +/// Global ID for the SPI Configuration Protocol
> > +///
> > +#define EFI_SPI_CONFIGURATION_GUID  \
> > +  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
> > +    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > +
> > +///
> > +/// Macros to easily specify frequencies in hertz, kilohertz and megahertz.
> > +///
> > +#define Hz(Frequency)   (Frequency)
> > +#define KHz(Frequency)  (1000 * Hz (Frequency))
> > +#define MHz(Frequency)  (1000 * KHz (Frequency))
> > +
> > +typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
> > +
> > +/**
> > +  Manipulate the chip select for a SPI device.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  Update the value of the chip select line for a SPI peripheral.
> > +  The SPI bus layer calls this routine either in the board layer or in the SPI
> > +  controller to manipulate the chip select pin at the start and end of a SPI
> > +  transaction.
> > +
> > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > structure
> > +                            describing the SPI peripheral whose chip select pin
> > +                            is to be manipulated. The routine may access the
> > +                            ChipSelectParameter field to gain sufficient
> > +                            context to complete the operation.
> > +  @param[in] PinValue       The value to be applied to the chip select line of
> > +                            the SPI peripheral.
> > +
> > +  @retval EFI_SUCCESS            The chip select was set successfully
> > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > +                                 initialized
> > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral-
> > >ChipSelectParameter value
> > +                                 is invalid
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_CHIP_SELECT) (
> > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > +  IN BOOLEAN                   PinValue
> > +  );
> > +
> > +/**
> > +  Set up the clock generator to produce the correct clock frequency, phase
> > and
> > +  polarity for a SPI chip.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine updates the clock generator to generate the correct
> > frequency
> > +  and polarity for the SPI clock.
> > +
> > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> structure
> > from
> > +                            which the routine can access the ClockParameter,
> > +                            ClockPhase and ClockPolarity fields. The routine
> > +                            also has access to the names for the SPI bus and
> > +                            chip which can be used during debugging.
> > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> > clock
> > +                            generator will choose a supported clock frequency
> > +                            which is less then or equal to this value.
> > +                            Specify zero to turn the clock generator off.
> > +                            The actual clock frequency supported by the clock
> > +                            generator will be returned.
> > +
> > +  @retval EFI_SUCCESS      The clock was set up successfully
> > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> the
> > +                           frequency requested by CLockHz
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_CLOCK) (
> > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > +  IN UINT32                    *ClockHz
> > +  );
> > +
> > +///
> > +/// The EFI_SPI_PART data structure provides a description of a SPI part
> > which
> > +/// is independent of the use on the board. This data is available directly
> > +/// from the part's datasheet and may be provided by the vendor.
> > +///
> > +typedef struct _EFI_SPI_PART {
> > +  ///
> > +  /// A Unicode string specifying the SPI chip vendor.
> > +  ///
> > +  CONST CHAR16 *Vendor;
> > +
> > +  ///
> > +  /// A Unicode string specifying the SPI chip part number.
> > +  ///
> > +  CONST CHAR16 *PartNumber;
> > +
> > +  ///
> > +  /// The minimum SPI bus clock frequency used to access this chip. This
> > value
> > +  /// may be specified in the chip's datasheet. If not, use the value of zero.
> > +  ///
> > +  UINT32       MinClockHz;
> > +
> > +  ///
> > +  /// The maximum SPI bus clock frequency used to access this chip. This
> > value
> > +  /// is found in the chip's datasheet.
> > +  ///
> > +  UINT32       MaxClockHz;
> > +
> > +  ///
> > +  /// Specify the polarity of the chip select pin. This value can be found in
> > +  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip
> > select
> > +  ///and FALSE when a zero asserts the chip select.
> > +  ///
> > +  BOOLEAN      ChipSelectPolarity;
> > +} EFI_SPI_PART;
> > +
> > +///
> > +/// The EFI_SPI_BUS data structure provides the connection details
> > between the
> > +/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which
> controls
> > that
> > +/// SPI bus. This data structure also describes the details of how the clock
> is
> > +/// generated for that SPI bus. Finally this data structure provides the list
> > +/// of physical SPI devices which are attached to the SPI bus.
> > +///
> > +typedef struct _EFI_SPI_BUS {
> > +  ///
> > +  /// A Unicode string describing the SPI bus
> > +  ///
> > +  CONST CHAR16                   *FriendlyName;
> > +
> > +  ///
> > +  /// Address of the first EFI_SPI_PERIPHERAL data structure connected to
> > this
> > +  /// bus. Specify NULL if there are no SPI peripherals connected to this
> bus.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
> > +
> > +  ///
> > +  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which
> > uniquely
> > +  /// describes the SPI controller.
> > +  ///
> > +  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
> > +
> > +  ///
> > +  /// Address of the routine which controls the clock used by the SPI bus
> for
> > +  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
> > +  /// when this value is set to NULL.
> > +  ///
> > +  EFI_SPI_CLOCK                  Clock;
> > +
> > +  ///
> > +  /// Address of a data structure containing the additional values which
> > +  /// describe the necessary control for the clock. When Clock is NULL,
> > +  /// the declaration for this data structure is provided by the vendor of
> the
> > +  /// host's SPI controller driver. When Clock is not NULL, the declaration
> for
> > +  /// this data structure is provided by the board layer.
> > +  ///
> > +  VOID                           *ClockParameter;
> > +} EFI_SPI_BUS;
> > +
> > +///
> > +/// The EFI_SPI_PERIPHERAL data structure describes how a specific block
> > of
> > +/// logic which is connected to the SPI bus. This data structure also selects
> > +/// which upper level driver is used to manipulate this SPI device.
> > +/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
> > +/// peripheral driver.
> > +///
> > +struct _EFI_SPI_PERIPHERAL {
> > +  ///
> > +  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify
> NULL
> > if
> > +  /// the current data structure is the last one on the SPI bus.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
> > +
> > +  ///
> > +  /// A unicode string describing the function of the SPI part.
> > +  ///
> > +  CONST CHAR16             *FriendlyName;
> > +
> > +  ///
> > +  /// Address of a GUID provided by the vendor of the SPI peripheral
> driver.
> > +  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus driver
> > uses
> > +  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and to
> > +  /// provide the connection points for the SPI peripheral drivers.
> > +  /// This reduces the comparison logic in the SPI peripheral driver's
> > +  /// Supported routine.
> > +  ///
> > +  CONST GUID               *SpiPeripheralDriverGuid;
> > +
> > +  ///
> > +  /// The address of an EFI_SPI_PART data structure which describes this
> > chip.
> > +  ///
> > +  CONST EFI_SPI_PART       *SpiPart;
> > +
> > +  ///
> > +  /// The maximum clock frequency is specified in the EFI_SPI_P ART.
> When
> > this
> > +  /// this value is non-zero and less than the value in the EFI_SPI_PART
> then
> > +  /// this value is used for the maximum clock frequency for the SPI part.
> > +  ///
> > +  UINT32                   MaxClockHz;
> > +
> > +  ///
> > +  /// Specify the idle value of the clock as found in the datasheet.
> > +  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
> > +  /// clock's idle value is high.
> > +  ///
> > +  BOOLEAN                  ClockPolarity;
> > +
> > +  ///
> > +  /// Specify the clock delay after chip select. Specify zero (0) to delay an
> > +  /// entire clock cycle or one (1) to delay only half a clock cycle.
> > +  ///
> > +  BOOLEAN                  ClockPhase;
> > +
> > +  ///
> > +  /// SPI peripheral attributes, select zero or more of:
> > +  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI
> > peripheral is wired to
> > +  ///   support a 2-bit data bus
> > +  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI
> > peripheral is wired to
> > +  ///   support a 4-bit data bus
> > +  ///
> > +  UINT32                   Attributes;
> > +
> > +  ///
> > +  /// Address of a vendor specific data structure containing additional
> board
> > +  /// configuration details related to the SPI chip. The SPI peripheral layer
> > +  /// uses this data structure when configuring the chip.
> > +  ///
> > +  CONST VOID               *ConfigurationData;
> > +
> > +  ///
> > +  /// The address of an EFI_SPI_BUS data structure which describes the SPI
> > bus
> > +  /// to which this chip is connected.
> > +  ///
> > +  CONST EFI_SPI_BUS        *SpiBus;
> > +
> > +  ///
> > +  /// Address of the routine which controls the chip select pin for this SPI
> > +  /// peripheral. Call the SPI host controller's chip select routine when this
> > +  /// value is set to NULL.
> > +  ///
> > +  EFI_SPI_CHIP_SELECT      ChipSelect;
> > +
> > +  ///
> > +  /// Address of a data structure containing the additional values which
> > +  /// describe the necessary control for the chip select. When ChipSelect is
> > +  /// NULL, the declaration for this data structure is provided by the
> vendor
> > +  /// of the host's SPI controller driver. The vendor's documentation
> > specifies
> > +  /// the necessary values to use for the chip select pin selection and
> > +  /// control. When Chipselect is not NULL, the declaration for this data
> > +  /// structure is provided by the board layer.
> > +  ///
> > +  VOID                     *ChipSelectParameter;
> > +};
> > +
> > +///
> > +/// Describe the details of the board's SPI busses to the SPI driver stack.
> > +/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to
> > expose the data
> > +/// tables which describe the board's SPI busses, The SPI bus layer uses
> > these
> > +/// tables to configure the clock, chip select and manage the SPI
> > transactions
> > +/// on the SPI controllers.
> > +///
> > +typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
> > +  ///
> > +  /// The number of SPI busses on the board.
> > +  ///
> > +  UINT32                          BusCount;
> > +
> > +  ///
> > +  /// The address of an array of EFI_SPI_BUS data structure addresses.
> > +  ///
> > +  CONST EFI_SPI_BUS *CONST *CONST Buslist;
> > +} EFI_SPI_CONFIGURATION_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
> > +
> > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiHc.h
> > b/MdePkg/Include/Protocol/SpiHc.h
> > new file mode 100644
> > index 000000000000..13ad5f45225c
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiHc.h
> > @@ -0,0 +1,194 @@
> > +/** @file
> > +  This file defines the SPI Host Controller Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_HC_PROTOCOL_H__
> > +#define __SPI_HC_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiConfiguration.h>
> > +#include <Protocol/SpiIo.h>
> > +
> > +///
> > +/// Global ID for the SPI Host Controller Protocol
> > +///
> > +#define EFI_SPI_HOST_GUID  \
> > +  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
> > +    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > +
> > +///
> > +/// EDK2-style name
> > +///
> > +#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
> > +
> > +typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
> > +
> > +/**
> > +  Assert or deassert the SPI chip select.
> > +
> > +  This routine is called at TPL_NOTIFY.
> > +  Update the value of the chip select line for a SPI peripheral. The SPI bus
> > +  layer calls this routine either in the board layer or in the SPI controller
> > +  to manipulate the chip select pin at the start and end of a SPI transaction.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > structure
> > +                            describing the SPI peripheral whose chip select pin
> > +                            is to be manipulated. The routine may access the
> > +                            ChipSelectParameter field to gain sufficient
> > +                            context to complete the operati on.
> > +  @param[in] PinValue       The value to be applied to the chip select line of
> > +                            the SPI peripheral.
> > +
> > +  @retval EFI_SUCCESS            The chip select was set as requested
> > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > +                                 initialized
> > +  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its contents
> > are
> > +                                 invalid
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
> > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > +  IN BOOLEAN                    PinValue
> > +  );
> > +
> > +/**
> > +  Set up the clock generator to produce the correct clock frequency, phase
> > and
> > +  polarity for a SPI chip.
> > +
> > +  This routine is called at TPL_NOTIFY.
> > +  This routine updates the clock generator to generate the correct
> > frequency
> > +  and polarity for the SPI clock.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> structure
> > from
> > +                            which the routine can access the ClockParameter,
> > +                            ClockPhase and ClockPolarity fields. The routine
> > +                            also has access to the names for the SPI bus and
> > +                            chip which can be used during debugging.
> > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> SPI
> > +                            host controller will choose a supported clock
> > +                            frequency which is less then or equal to this
> > +                            value. Specify zero to turn the clock generator
> > +                            off. The actual clock frequency supported by the
> > +                            SPI host controller will be returned.
> > +
> > +  @retval EFI_SUCCESS      The clock was set up successfully
> > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> the
> > +                           frequency requested by ClockHz
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
> > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > +  IN UINT32                      *ClockHz
> > +  );
> > +
> > +/**
> > +  Perform the SPI transaction on the SPI peripheral using the SPI host
> > +  controller.
> > +
> > +  This routine is called at TPL_NOTIFY.
> > +  This routine synchronously returns EFI_SUCCESS indicating that the
> > +  asynchronous SPI transaction was started. The routine then waits for
> > +  completion of the SPI transaction prior to returning the final transaction
> > +  status.
> > +
> > +  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > +  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION
> > containing
> > +                             the description of the SPI transaction to perform.
> > +
> > +  @retval EFI_SUCCESS          The transaction completed successfully
> > +  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value is
> > invalid,
> > +                               or the BusTransaction->ReadinBytes value is
> > +                               invalid
> > +  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type is
> > +                               unsupported
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > +  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
> > +  );
> > +
> > +///
> > +/// Support a SPI data transaction between the SPI controller and a SPI
> chip.
> > +///
> > +struct _EFI_SPI_HC_PROTOCOL {
> > +  ///
> > +  /// Host control attributes, may have zero or more of the following set:
> > +  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> > +  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> > +  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> > +  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > +  ///   - The SPI host controller requires the transmit frame to be in most
> > +  ///     significant bits instead of least significant bits.The host driver
> > +  ///     will adjust the frames if necessary.
> > +  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > +  ///   - The SPI host controller places the receive frame to be in most
> > +  ///     significant bits instead of least significant bits.The host driver
> > +  ///     will adjust the frames to be in the least significant bits if
> > +  ///     necessary.
> > +  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
> > +  ///   - The SPI controller supports a 2 - bit data bus
> > +  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> > +  ///   - The SPI controller supports a 4 - bit data bus
> > +  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> > +  ///   - Transfer size includes the opcode byte
> > +  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> > +  ///   - Transfer size includes the 3 address bytes
> > +  /// The SPI host controller must support full - duplex (receive while
> > +  /// sending) operation.The SPI host controller must support a 1 - bit bus
> > +  /// width.
> > +  ///
> > +  UINT32                          Attributes;
> > +
> > +  ///
> > +  /// Mask of frame sizes which the SPI host controller supports. Frame
> size
> > of
> > +  /// N-bits is supported when bit N-1 is set. The host controller must
> > support
> > +  /// a frame size of 8-bits.
> > +  ///
> > +  UINT32                          FrameSizeSupportMask;
> > +
> > +  ///
> > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > +  ///
> > +  UINT32                          MaximumTransferBytes;
> > +
> > +  ///
> > +  /// Assert or deassert the SPI chip select.
> > +  ///
> > +  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
> > +
> > +  ///
> > +  /// Set up the clock generator to produce the correct clock frequency,
> > phase
> > +  /// and polarity for a SPI chip.
> > +  ///
> > +  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
> > +
> > +  ///
> > +  /// Perform the SPI transaction on the SPI peripheral using the SPI host
> > +  /// controller.
> > +  ///
> > +  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
> > +};
> > +
> > +extern EFI_GUID gEfiSpiHcProtocolGuid;
> > +
> > +#endif // __SPI_HC_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiIo.h
> > b/MdePkg/Include/Protocol/SpiIo.h
> > new file mode 100644
> > index 000000000000..e481779acc58
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiIo.h
> > @@ -0,0 +1,292 @@
> > +/** @file
> > +  This file defines the SPI I/O Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_IO_PROTOCOL_H__
> > +#define __SPI_IO_PROTOCOL_H__
> > +
> > +#include <Protocol/LegacySpiController.h>
> > +#include <Protocol/SpiConfiguration.h>
> > +
> > +typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> > +
> > +///
> > +/// Note: The UEFI PI 1.6 specification does not specify values for the
> > +///       members below. The order matches the specification.
> > +///
> > +typedef enum {
> > +  ///
> > +  /// Data flowing in both direction between the host and
> > +  /// SPI peripheral.ReadBytes must equal WriteBytes and both
> ReadBuffer
> > and
> > +  /// WriteBuffer must be provided.
> > +  ///
> > +  SPI_TRANSACTION_FULL_DUPLEX,
> > +
> > +  ///
> > +  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> > +  /// zero.WriteBytes must be non - zero and WriteBuffer must be
> provided.
> > +  ///
> > +  SPI_TRANSACTION_WRITE_ONLY,
> > +
> > +  ///
> > +  /// Data flowing from the SPI peripheral to the host.WriteBytes must be
> > +  /// zero.ReadBytes must be non - zero and ReadBuffer must be
> provided.
> > +  ///
> > +  SPI_TRANSACTION_READ_ONLY,
> > +
> > +  ///
> > +  /// Data first flowing from the host to the SPI peripheral and then data
> > +  /// flows from the SPI peripheral to the host.These types of operations
> get
> > +  /// used for SPI flash devices when control data (opcode, address) must
> be
> > +  /// passed to the SPI peripheral to specify the data to be read.
> > +  ///
> > +  SPI_TRANSACTION_WRITE_THEN_READ
> > +} EFI_SPI_TRANSACTION_TYPE;
> > +
> > +/**
> > +  Initiate a SPI transaction between the host and a SPI peripheral.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine works with the SPI bus layer to pass the SPI transaction to
> the
> > +  SPI controller for execution on the SPI bus. There are four types of
> > +  supported transactions supported by this routine:
> > +  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> > +  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes = 0
> > +  * Read Only: ReadBuffer to receive data from SPI peripheral, WriteBytes
> =
> > 0
> > +  * Write Then Read: WriteBuffer contains control data to write to SPI
> > +                     peripheral before data is placed into the ReadBuffer.
> > +                     Both WriteBytes and ReadBytes must be non-zero.
> > +
> > +  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > +  @param[in]  TransactionType   Type of SPI transaction.
> > +  @param[in]  DebugTransaction  Set TRUE only when debugging is
> desired.
> > +                                Debugging may be turned on for a single SPI
> > +                                transaction. Only this transaction will display
> > +                                debugging messages. All other transactions with
> > +                                this value set to FALSE will not display any
> > +                                debugging messages.
> > +  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
> > +                                the maximum clock frequency supported by the
> > +                                SPI controller and part. Specify a non-zero
> > +                                value only when a specific SPI transaction
> > +                                requires a reduced clock rate.
> > +  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
> > +  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
> > +  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
> > +                                Specify zero for read-only operations.
> > +  @param[in]  WriteBuffer       The buffer containing data to be sent from
> the
> > +                                host to the SPI chip. Specify NULL for read
> > +                                only operations.
> > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > +                                  frame
> > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > +                                  frame
> > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > +                                  per frame The transmit frame is in the least
> > +                                  significant N bits.
> > +  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
> > +                                Specify zero for write-only operations.
> > +  @param[out] ReadBuffer        The buffer to receeive data from the SPI
> chip
> > +                                during the transaction. Specify NULL for write
> > +                                only operations.
> > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > +                                  frame
> > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > +                                  frame
> > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > +                                  per frame The received frame is in the least
> > +                                  significant N bits.
> > +
> > +  @retval EFI_SUCCESS            The SPI transaction completed successfully
> > +  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
> > +  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
> > +  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
> > +                                 or BusWidth not supported by SPI peripheral or
> > +                                 SPI host controller,
> > +                                 or WriteBytes non-zero and WriteBuffer is
> > +                                 NULL,
> > +                                 or ReadBytes non-zero and ReadBuffer is NULL,
> > +                                 or ReadBuffer != WriteBuffer for full-duplex
> > +                                 type,
> > +                                 or WriteBuffer was NULL,
> > +                                 or TPL is too high
> > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI
> transaction
> > +  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the
> SPI
> > bus
> > +                                 layer or the SPI host controller
> > +  @retval EFI_UNSUPPORTED        The SPI controller was not able to
> support
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> > +  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
> > +  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
> > +  IN  BOOLEAN                    DebugTransaction,
> > +  IN  UINT32                     ClockHz OPTIONAL,
> > +  IN  UINT32                     BusWidth,
> > +  IN  UINT32                     FrameSize,
> > +  IN  UINT32                     WriteBytes,
> > +  IN  UINT8                      *WriteBuffer,
> > +  IN  UINT32                     ReadBytes,
> > +  OUT UINT8                      *ReadBuffer
> > +  );
> > +
> > +/**
> > +  Update the SPI peripheral associated with this SPI 10 instance.
> > +
> > +  Support socketed SPI parts by allowing the SPI peripheral driver to
> replace
> > +  the SPI peripheral after the connection is made. An example use is
> > socketed
> > +  SPI NOR flash parts, where the size and parameters change depending
> > upon
> > +  device is in the socket.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > +  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL structure.
> > +
> > +  @retval EFI_SUCCESS            The SPI peripheral was updated successfully
> > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
> > +                                 or the SpiPeripheral->SpiBus is NULL,
> > +                                 or the SpiP eripheral - >SpiBus pointing at
> > +                                 wrong bus,
> > +                                 or the SpiP eripheral - >SpiPart is NULL
> > +
> > +**/
> > +typedef EFI_STATUS
> > +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> > +  IN CONST EFI_SPI_IO_PROTOCOL  *This,
> > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
> > +  );
> > +
> > +///
> > +/// The EFI_SPI_BUS_ TRANSACTION data structure contains the
> > description of the
> > +/// SPI transaction to perform on the host controller.
> > +///
> > +typedef struct _EFI_SPI_BUS_TRANSACTION {
> > +  ///
> > +  /// Pointer to the SPI peripheral being manipulated.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> > +
> > +  ///
> > +  /// Type of transaction specified by one of the
> > EFI_SPI_TRANSACTION_TYPE
> > +  /// values.
> > +  ///
> > +  EFI_SPI_TRANSACTION_TYPE TransactionType;
> > +
> > +  ///
> > +  /// TRUE if the transaction is being debugged. Debugging may be turned
> > on for
> > +  /// a single SPI transaction. Only this transaction will display debugging
> > +  /// messages. All other transactions with this value set to FALSE will not
> > +  /// display any debugging messages.
> > +  ///
> > +  BOOLEAN                  DebugTransaction;
> > +
> > +  ///
> > +  /// SPI bus width in bits: 1, 2, 4
> > +  ///
> > +  UINT32                   BusWidth;
> > +
> > +  ///
> > +  /// Frame size in bits, range: 1 - 32
> > +  ///
> > +  UINT32                   FrameSize;
> > +
> > +  ///
> > +  /// Length of the write buffer in bytes
> > +  ///
> > +  UINT32                   WriteBytes;
> > +
> > +  ///
> > +  /// Buffer containing data to send to the SPI peripheral
> > +  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > +  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > +  ///
> > +  UINT8                    *WriteBuffer;
> > +
> > +  ///
> > +  /// Length of the read buffer in bytes
> > +  ///
> > +  UINT32                   ReadBytes;
> > +
> > +  ///
> > +  /// Buffer to receive the data from the SPI peripheral
> > +  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > +  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > +  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> > +  ///
> > +  UINT8                    *ReadBuffer;
> > +} EFI_SPI_BUS_TRANSACTION;
> > +
> > +///
> > +/// Support managed SPI data transactions between the SPI controller
> and a
> > SPI
> > +/// chip.
> > +///
> > +struct _EFI_SPI_IO_PROTOCOL {
> > +  ///
> > +  /// Address of an EFI_SPI_PERIPHERAL data structure associated with
> this
> > +  /// protocol instance.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
> > +
> > +  ///
> > +  /// Address of the original EFI_SPI_PERIPHERAL data structure associated
> > with
> > +  /// this protocol instance.
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
> > +
> > +  ///
> > +  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of N-
> > bits
> > +  /// is supported when bit N-1 is set. The host controller must support a
> > +  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted to
> > +  /// 8-bit frame sizes by the SPI bus layer if the frame size is not
> supported
> > +  /// by the SPI host controller.
> > +  ///
> > +  UINT32                                    FrameSizeSupportMask;
> > +
> > +  ///
> > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > +  ///
> > +  UINT32                                    MaximumTransferBytes;
> > +
> > +  ///
> > +  /// Transaction attributes: One or more from:
> > +  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> > +  ///   - The SPI host and peripheral supports a 2-bit data bus
> > +  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> > +  ///   - The SPI host and peripheral supports a 4-bit data bus
> > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> > +  ///   - Transfer size includes the opcode byte
> > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> > +  ///   - Transfer size includes the 3 address bytes
> > +  ///
> > +  UINT32                                    Attributes;
> > +
> > +  ///
> > +  /// Pointer to legacy SPI controller protocol
> > +  ///
> > +  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *LegacySpiProtocol;
> > +
> > +  ///
> > +  /// Initiate a SPI transaction between the host and a SPI peripheral.
> > +  ///
> > +  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
> > +
> > +  ///
> > +  /// Update the SPI peripheral associated with this SPI 10 instance.
> > +  ///
> > +  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL UpdateSpiPeripheral;
> > +};
> > +
> > +#endif // __SPI_IO_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h
> > b/MdePkg/Include/Protocol/SpiNorFlash.h
> > new file mode 100644
> > index 000000000000..93d2adaa860e
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiNorFlash.h
> > @@ -0,0 +1,289 @@
> > +/** @file
> > +  This file defines the SPI NOR Flash Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
> > +#define __SPI_NOR_FLASH_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiConfiguration.h>
> > +
> > +///
> > +/// Global ID for the SPI NOR Flash Protocol
> > +///
> > +#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
> > +  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
> > +    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > +
> > +typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL
> > EFI_SPI_NOR_FLASH_PROTOCOL;
> > +
> > +/**
> > +  Read the 3 byte manufacture and device ID from the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads the 3 byte manufacture and device ID from the flash
> > part
> > +  filling the buffer provided.
> > +
> > +  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> > structure.
> > +  @param[out] Buffer  Pointer to a 3 byte buffer to receive the
> manufacture
> > and
> > +                      device ID.
> > +
> > +
> > +
> > +  @retval EFI_SUCCESS            The manufacture and device ID was read
> > +                                 successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL
> > +  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  OUT UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Read data from the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads data from the SPI part in the buffer provided.
> > +
> > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                             structure.
> > +  @param[in]  FlashAddress   Address in the flash to start reading
> > +  @param[in]  LengthInBytes  Read length in bytes
> > +  @param[out] Buffer         Address of a buffer to receive the data
> > +
> > +  @retval EFI_SUCCESS            The data was read successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > +                                 FlashAddress >= This->FlashSize, or
> > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN  UINT32                            FlashAddress,
> > +  IN  UINT32                            LengthInBytes,
> > +  OUT UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Low frequency read data from the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads data from the SPI part in the buffer provided.
> > +
> > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                             structure.
> > +  @param[in]  FlashAddress   Address in the flash to start reading
> > +  @param[in]  LengthInBytes  Read length in bytes
> > +  @param[out] Buffer         Address of a buffer to receive the data
> > +
> > +  @retval EFI_SUCCESS            The data was read successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > +                                 FlashAddress >= This->FlashSize, or
> > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN  UINT32                            FlashAddress,
> > +  IN  UINT32                            LengthInBytes,
> > +  OUT UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Read the flash status register.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine reads the flash part status register.
> > +
> > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                             structure.
> > +  @param[in]  LengthInBytes  Number of status bytes to read.
> > +  @param[out] FlashStatus    Pointer to a buffer to receive the flash status.
> > +
> > +  @retval EFI_SUCCESS  The status register was read successfully.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
> > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN  UINT32                            LengthInBytes,
> > +  OUT UINT8                             *FlashStatus
> > +  );
> > +
> > +/**
> > +  Write the flash status register.
> > +
> > +  This routine must be called at or below TPL_N OTIFY.
> > +  This routine writes the flash part status register.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                            structure.
> > +  @param[in] LengthInBytes  Number of status bytes to write.
> > +  @param[in] FlashStatus    Pointer to a buffer containing the new status.
> > +
> > +  @retval EFI_SUCCESS           The status write was successful.
> > +  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
> > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN UINT32                            LengthInBytes,
> > +  IN UINT8                             *FlashStatus
> > +  );
> > +
> > +/**
> > +  Write data to the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine breaks up the write operation as necessary to write the data
> > to
> > +  the SPI part.
> > +
> > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > +                            structure.
> > +  @param[in] FlashAddress   Address in the flash to start writing
> > +  @param[in] LengthInBytes  Write length in bytes
> > +  @param[in] Buffer         Address of a buffer containing the data
> > +
> > +  @retval EFI_SUCCESS            The data was written successfully.
> > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > +                                 FlashAddress >= This->FlashSize, or
> > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy buffer.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
> > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN UINT32                            FlashAddress,
> > +  IN UINT32                            LengthInBytes,
> > +  IN UINT8                             *Buffer
> > +  );
> > +
> > +/**
> > +  Efficiently erases one or more 4KiB regions in the SPI flash.
> > +
> > +  This routine must be called at or below TPL_NOTIFY.
> > +  This routine uses a combination of 4 KiB and larger blocks to erase the
> > +  specified area.
> > +
> > +  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> > +                           structure.
> > +  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
> > +  @param[in] BlockCount    Number of 4 KiB blocks to erase
> > +
> > +  @retval EFI_SUCCESS            The erase was completed successfully.
> > +  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
> > +                                 BlockCount * 4 KiB
> > +                                   > This->FlashSize - FlashAddress
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
> > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > +  IN UINT32                            FlashAddress,
> > +  IN UINT32                            BlockCount
> > +  );
> > +
> > +///
> > +/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral layer.
> > +/// This protocol manipulates the SPI NOR flash parts using a common set
> of
> > +/// commands. The board layer provides the interconnection and
> > configuration
> > +/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
> > +/// configuration data to expose a generic interface which provides the
> > +/// following APls:
> > +/// * Read manufacture and device ID
> > +/// * Read data
> > +/// * Read data using low frequency
> > +/// * Read status
> > +/// * Write data
> > +/// * Erase 4 KiB blocks
> > +/// * Erase 32 or 64 KiB blocks
> > +/// * Write status
> > +/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set
> the
> > security
> > +/// features on the legacy SPI flash controller.
> > +///
> > +struct _EFI_SPI_NOR_FLASH_PROTOCOL {
> > +  ///
> > +  /// Pointer to an EFI_SPI_PERIPHERAL data structure
> > +  ///
> > +  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
> > +
> > +  ///
> > +  /// Flash size in bytes
> > +  ///
> > +  UINT32                                  FlashSize;
> > +
> > +  ///
> > +  /// Manufacture and Device ID
> > +  ///
> > +  UINT8                                   Deviceid[3];
> > +
> > +  ///
> > +  /// Erase block size in bytes
> > +  ///
> > +  UINT32                                  EraseBlockBytes;
> > +
> > +  ///
> > +  /// Read the 3 byte manufacture and device ID from the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
> > +
> > +  ///
> > +  /// Read data from the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
> > +
> > +  ///
> > +  /// Low frequency read data from the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
> > +
> > +  ///
> > +  /// Read the flash status register.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
> > +
> > +  ///
> > +  /// Write the flash status register.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
> > +
> > +  ///
> > +  /// Write data to the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
> > +
> > +  ///
> > +  /// Efficiently erases one or more 4KiB regions in the SPI flash.
> > +  ///
> > +  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
> > +};
> > +
> > +extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
> > +
> > +#endif // __SPI_NOR_FLASH_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > new file mode 100644
> > index 000000000000..913d4cbb46aa
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the SPI SMM Configuration Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > +#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > +
> > +#include <Protocol/SpiConfiguration.h>
> > +
> > +///
> > +/// Global ID for the SPI SMM Configuration Protocol
> > +///
> > +#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
> > +  { 0x995c6eca, 0x171b, 0x45fd,                  \
> > +    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > +
> > +typedef
> > +struct _EFI_SPI_CONFIGURATION_PROTOCOL
> > +EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
> > +
> > +#endif // __SPI_SMM_CONFIGURATION_H__
> > diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h
> > b/MdePkg/Include/Protocol/SpiSmmHc.h
> > new file mode 100644
> > index 000000000000..91d2312b74b4
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/SpiSmmHc.h
> > @@ -0,0 +1,36 @@
> > +/** @file
> > +  This file defines the SPI SMM Host Controller Protocol.
> > +
> > +  Copyright (c) 2017, 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.
> > +
> > +  @par Revision Reference:
> > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > +
> > +**/
> > +
> > +#ifndef __SPI_SMM_HC_H__
> > +#define __SPI_SMM_HC_H__
> > +
> > +#include <Protocol/SpiHc.h>
> > +
> > +///
> > +/// Global ID for the SPI SMM Host Controller Protocol
> > +///
> > +#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
> > +  { 0xe9f02217, 0x2093, 0x4470,       \
> > +    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > +
> > +typedef
> > +struct _EFI_SPI_HC_PROTOCOL
> > +EFI_SPI_SMM_HC_PROTOCOL;
> > +
> > +extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
> > +
> > +#endif // __SPI_SMM_HC_H__
> > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> > index 1867c54c3bc1..91af6c5c455c 100644
> > --- a/MdePkg/MdePkg.dec
> > +++ b/MdePkg/MdePkg.dec
> > @@ -1246,6 +1246,37 @@ [Protocols]
> >    gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd,
> > { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
> >
> >    #
> > +  # Protocols defined in PI 1.6.
> > +  #
> > +
> > +  ## Include/Protocol/LegacySpiController.h
> > +  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de,
> > { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > +
> > +  ## Include/Protocol/LegacySpiFlash.h
> > +  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, {
> 0x96,
> > 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > +
> > +  ## Include/Protocol/LegacySpiSmmController.h
> > +  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0,
> 0x4c8c,
> > { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > +
> > +  ## Include/Protocol/LegacySpiSmmFlash.h
> > +  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0,
> > { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > +
> > +  ## Include/Protocol/SpiConfiguration.h
> > +  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, {
> 0xb3,
> > 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > +
> > +  ## Include/Protocol/SpiHc.h
> > +  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3,
> 0x99,
> > 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > +
> > +  ## Include/Protocol/SpiNorFlash.h
> > +  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, { 0x85,
> > 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > +
> > +  ## Include/Protocol/SpiSmmConfiguration.h
> > +  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b, 0x45fd,
> > { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > +
> > +  ## Include/Protocol/SpiSmmHc.h
> > +  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, { 0x8a,
> > 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > +
> > +  #
> >    # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
> >    #
> >
> > --
> > 2.12.2.windows.2
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Marvin Häuser 6 years, 6 months ago
Hey Vincent,

Thank you for your response!
It would be very kind of you if you would post an update to edk2-devel and CC me once you get a response from the Forum!

In case you know somebody working on the MM part of the specification, could you please forward the following?
There is a potential problem with EFI_MM_IO_TRAP_DISPATCH_PROTOCOL.Register() that might prevent a Standalone MM implementation:
"If the base of the I/O range specified is zero, then an I/O range with the specified length and characteristics will be allocated and the Address field in RegisterContext updated."
With the current specification, the only way to allocate an I/O Range I know is via the DXE Services, though using the DXE services means that a Standalone MM implementation is not possible. Maybe 0 should no longer be accepted as a possible value (of course that would require an IoTrapDispatch2)? A Standalone MM driver which calls this function would then depend on a DXE driver to already have allocated the range via the DXE Services (the MM driver should probably hook the EndOfDxe event to make sure the DXE code has run). On the other hand, the Standalone MM IoTrap consumer has no way of knowing whether the allocation was completed successfully. So, the only proper way I see would be implementing I/O range allocation during PEI phase and then exposing those allocations via the HOB list, which is available to both the DXE Core to take note of the allocations, as well as the Standalone MM Core, which can expose them to the MM Standalone Drivers. Any comments? Did I maybe overlook something?

Thanks,
Marvin.

> -----Original Message-----
> From: Zimmer, Vincent [mailto:vincent.zimmer@intel.com]
> Sent: Wednesday, September 20, 2017 10:24 PM
> To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-
> devel@lists.01.org
> Cc: Bi, Dandan <dandan.bi@intel.com>; Shaw, Kevin W
> <kevin.w.shaw@intel.com>; Leahy, Leroy P <leroy.p.leahy@intel.com>; UEFI
> Administration <admin@uefi.org>
> Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Marvin:
> 
> Thanks for all of the feedback on the SPI items from the most recent UEFI PI
> spec. We're updating the PI spec now responsive to your findings and these
> corrections will be reflected in an upcoming errata.
> 
> Sorry for the delayed response to you on the findings. I'll follow up w/ UEFI
> Forum on why we cannot readily use the fw/os forum mailing list for this
> type of discussion, too.
> 
> Vincent
> 
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Marvin Häuser
> Sent: Friday, September 15, 2017 7:57 AM
> To: edk2-devel@lists.01.org
> Cc: Bi, Dandan <dandan.bi@intel.com>
> Subject: Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Hey Dandan,
> 
> Sorry for the mistakes, I will send them a part of a V2 once you finished
> reviewing.
> No problem for the delay, it's not high priority at all. Thanks for reviewing it!
> 
> There are problems within the specification regarding the SPI protocols
> anyway.
> I wanted to report these, though I don't know where to. Andrew suggested
> to post to the FW/OS Forum,
> though it is currently not available, so I'm awaiting response from the UEFI
> Forum administration.
> 
> Best regards,
> Marvin.
> 
> > -----Original Message-----
> > From: Bi, Dandan [mailto:dandan.bi@intel.com]
> > Sent: Friday, September 15, 2017 10:22 AM
> > To: Ni, Ruiyu <ruiyu.ni@intel.com>; Marvin Häuser
> > <Marvin.Haeuser@outlook.com>; edk2-devel@lists.01.org
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>
> > Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > introduced in UEFI PI 1.6.
> >
> > Hi Marvin,
> >
> > Thank you for your contribution. I am reviewing this patch now. Currently I
> > just take a look at the SMM SPI part and find:
> >
> > 1. There is a typo in LegacySpiSmmController.h
> > The definition should be EFI_LEGACY_SPI_SMM_CONTROLLER_GUID, not
> > EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID.
> > Typo:
> > #define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> >   { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> >     { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > And it should  be:
> > #define EFI_LEGACY_SPI_SMM_CONTROLLER_GUID \
> > { 0x62331b78, 0xd8d0, 0x4c8c, { 0x8c, 0xcb, 0xd2, 0x7d, \ 0xfe, 0x32, 0xdb,
> > 0x9b }}
> >
> > 2. EFI_SPI_SMM_NOR_FLASH_PROTOCOL definition seems to be missing.
> >
> > I will review the remaining part. It may take some time. Sorry for the delay
> in
> > my response
> >
> > Thanks,
> > Dandan
> >
> > -----Original Message-----
> > From: Ni, Ruiyu
> > Sent: Thursday, September 7, 2017 3:13 PM
> > To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-
> > devel@lists.01.org
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>; Bi, Dandan <dandan.bi@intel.com>
> > Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > introduced in UEFI PI 1.6.
> >
> > Marvin,
> > Thank you for your contribution. We will need some time to review the
> > definitions against PI Spec.
> > If there is a need to post V2, it might be better to separate the header files
> in
> > different groups.
> > For example, LegacySpi group, SPI group, SMM SPI group.
> >
> > Thanks/Ray
> >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > > Marvin Häuser
> > > Sent: Wednesday, September 6, 2017 5:21 PM
> > > To: edk2-devel@lists.01.org
> > > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > > <liming.gao@intel.com>
> > > Subject: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > > introduced in UEFI PI 1.6.
> > >
> > > This commit adds header files for the SPI protocols introduced in the
> > > UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.
> > >
> > > EFI_SPI_TRANSACTION_TYPE assumes an enum with its members
> ordered
> > > the
> > > way they are listed in the specification, as there are no values given
> > > explicitely.
> > > EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in
> the
> > > specification was meant to be '1'.
> > >
> > > Contributed-under: TianoCore Contribution Agreement 1.1
> > > Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
> > > ---
> > >  MdePkg/Include/Protocol/LegacySpiController.h    | 265
> > > ++++++++++++++++++
> > >  MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
> > >  MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
> > >  MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
> > >  MdePkg/Include/Protocol/SpiConfiguration.h       | 293
> > > ++++++++++++++++++++
> > >  MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
> > >  MdePkg/Include/Protocol/SpiIo.h                  | 292
> +++++++++++++++++++
> > >  MdePkg/Include/Protocol/SpiNorFlash.h            | 289
> > > +++++++++++++++++++
> > >  MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
> > >  MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
> > >  MdePkg/MdePkg.dec                                |  31 +++
> > >  11 files changed, 1709 insertions(+)
> > >
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiController.h
> > > b/MdePkg/Include/Protocol/LegacySpiController.h
> > > new file mode 100644
> > > index 000000000000..2d36eaefc0ee
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiController.h
> > > @@ -0,0 +1,265 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI Controller Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > > +#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > > +
> > > +///
> > > +/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
> > > +///       definition. This definition assumes it was supposed to be '1'.
> > > +///
> > > +/// Global ID for the Legacy SPI Controller Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
> > > +  { 0x39136fc7, 0x1a11, 0x49de,         \
> > > +    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > > +
> > > +typedef
> > > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
> > > +
> > > +/**
> > > +  Set the erase block opcode.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The menu table contains SPI transaction opcodes which are accessible
> > > after
> > > +  the legacy SPI flash controller's configuration is locked. The board layer
> > > +  specifies the erase block size for the SPI NOR flash part. The SPI NOR
> > flash
> > > +  peripheral driver selects the erase block opcode which matches the
> > erase
> > > +  block size and uses this API to load the opcode into the opcode menu
> > table.
> > > +
> > > +  @param[in] This              Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                               structure.
> > > +  @param[in] EraseBlockOpcode  Erase block opcode to be placed into
> the
> > > opcode
> > > +                               menu table.
> > > +
> > > +  @retval EFI_SUCCESS       The opcode menu table was updated
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT8                                     EraseBlockOpcode
> > > +  );
> > > +
> > > +/**
> > > +  Set the write status prefix opcode.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The prefix table contains SPI transaction write prefix opcodes which are
> > > +  accessible after the legacy SPI flash controller's configuration is locked.
> > > +  The board layer specifies the write status prefix opcode for the SPI
> NOR
> > > +  flash part. The SPI NOR flash peripheral driver uses this API to load the
> > > +  opcode into the prefix table.
> > > +
> > > +  @param[in] This               Pointer to an
> > > +                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
> > > +  @param[in] WriteStatusPrefix  Prefix opcode for the write status
> > > command.
> > > +
> > > +  @retval EFI_SUCCESS       The prefix table was updated
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT8                                     WriteStatusPrefix
> > > +  );
> > > +
> > > +/**
> > > +  Set the BIOS base address.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS base address works with the protect range registers to
> protect
> > > +  portions of the SPI NOR flash from erase and write operat ions. The
> BIOS
> > > +  calls this API prior to passing control to the OS loader.
> > > +
> > > +  @param[in] This             Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                              structure.
> > > +  @param[in] BiosBaseAddress  The BIOS base address.
> > > +
> > > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater
> > than
> > > +                                 This->Maxi.mumOffset
> > > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS)
> > > (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT32 BiosBaseAddress
> > > +  );
> > > +
> > > +/**
> > > +  Clear the SPI protect range registers.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > > +  range registers.
> > > +
> > > +  @param[in] This  Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT)
> > > (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > > +  );
> > > +
> > > +/**
> > > +  Determine if the SPI range is protected.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > > +
> > > +  @param[in] This            Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                             structure.
> > > +  @param[in] BiosAddress     Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval TRUE   The range is protected
> > > +  @retval FALSE  The range is not protected
> > > +
> > > +**/
> > > +typedef
> > > +BOOLEAN
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT32                                    BiosAddress,
> > > +  IN UINT32                                    BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Set the next protect range register.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS sets the protect range register to prevent write and erase
> > > +  operations to a portion of the SPI NOR flash device.
> > > +
> > > +  @param[in] This             Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                              structure.
> > > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval EFI_SUCCESS            The register was successfully updated
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> > >BiosBaseAddress,
> > > or
> > > +                                 BlocksToProtect * 4 KiB
> > > +                                   > This->MaximumRangeBytes, or
> > > +                                 BiosAddress - This->BiosBaseAddress
> > > +                                   + (BlocksToProtect * 4 KiB)
> > > +                                     > This->MaximumRangeBytes
> > > +  @retval EFI_OUT_OF_RESOURCES  No protect range register available
> > > +  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the
> > > BIOS base
> > > +                                address is not set
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT32                                    BiosAddress,
> > > +  IN UINT32                                    BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Lock the SPI controller configuration.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine locks the SPI controller's configuration so that the software
> > > +  is no longer able to update:
> > > +  * Prefix table
> > > +  * Opcode menu
> > > +  * Opcode type table
> > > +  * BIOS base address
> > > +  * Protect range registers
> > > +
> > > +  @param[in] This  Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER)
> > (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > > +  );
> > > +
> > > +///
> > > +/// Support the extra features of the legacy SPI flash controller.
> > > +///
> > > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
> > > +  ///
> > > +  /// Maximum offset from the BIOS base address that is able to be
> > > protected.
> > > +  ///
> > > +  UINT32                                                 MaximumOffset;
> > > +
> > > +  ///
> > > +  /// Maximum number of bytes that can be protected by one range
> > register.
> > > +  ///
> > > +  UINT32                                                 MaximumRangeBytes;
> > > +
> > > +  ///
> > > +  /// The number of registers available for protecting the BIOS.
> > > +  ///
> > > +  UINT32                                                 RangeRegisterCount;
> > > +
> > > +  ///
> > > +  /// Set the erase block opcode.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE
> > > EraseBlockOpcode;
> > > +
> > > +  ///
> > > +  /// Set the write status prefix opcode.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX
> > > WriteStatusPrefix;
> > > +
> > > +  ///
> > > +  /// Set the BIOS base address.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS
> > > BiosBaseAddress;
> > > +
> > > +  ///
> > > +  /// Clear the SPI protect range registers.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT
> > > ClearSpiProtect;
> > > +
> > > +  ///
> > > +  /// Determine if the SPI range is protected.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED
> > > IsRangeProtected;
> > > +
> > > +  ///
> > > +  /// Set the next protect range register.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE
> > > ProtectNextRange;
> > > +
> > > +  ///
> > > +  /// Lock the SPI controller configuration.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER
> > > LockController;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
> > > +
> > > +#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h
> > > b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > > new file mode 100644
> > > index 000000000000..faa5f5724af7
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > > @@ -0,0 +1,201 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI Flash Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiNorFlash.h>
> > > +
> > > +///
> > > +/// Global ID for the Legacy SPI Flash Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
> > > +  { 0xf01bed57, 0x04bc, 0x4f3f,             \
> > > +    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > > +
> > > +typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > EFI_LEGACY_SPI_FLASH_PROTOCOL;
> > > +
> > > +/**
> > > +  Set the BIOS base address.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS base address works with the protect range registers to
> protect
> > > +  portions of the SPI NOR flash from erase and write operat ions.
> > > +  The BIOS calls this API prior to passing control to the OS loader.
> > > +
> > > +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > data
> > > +                              structure.
> > > +  @param[in] BiosBaseAddress  The BIOS base address.
> > > +
> > > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This-
> > > >MaximumOffset
> > > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> > or
> > > not a
> > > +                                 legacy SPI host controller
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                               BiosBaseAddress
> > > +  );
> > > +
> > > +/**
> > > +  Clear the SPI protect range registers.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > > +  range registers.
> > > +
> > > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > > +  );
> > > +
> > > +/**
> > > +  Determine if the SPI range is protected.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > > +
> > > +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > data
> > > +                              structure.
> > > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval TRUE   The range is protected
> > > +  @retval FALSE  The range is not protected
> > > +
> > > +**/
> > > +typedef
> > > +BOOLEAN
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                               BiosAddress,
> > > +  IN UINT32                               BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Set the next protect range register.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS sets the protect range register to prevent write and erase
> > > +  operations to a portion of the SPI NOR flash device.
> > > +
> > > +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > data
> > > +                              structure.
> > > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval EFI_SUCCESS            The register was successfully updated
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> > >BiosBaseAddress,
> > > or
> > > +  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
> > > +                                   > This->MaximumRangeBytes, or
> > > +                                 BiosAddress - This->BiosBaseAddress
> > > +                                   + (BlocksToProtect * 4 KiB)
> > > +                                     > This->MaximumRangeBytes
> > > +  @retval EFI_OUT_OF_RESOURCES   No protect range register available
> > > +  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the
> > > BIOS
> > > +                                 base address is not set Not a legacy SPI host
> > > +                                 controller
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE)
> (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                               BiosAddress,
> > > +  IN UINT32                               BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Lock the SPI controller configuration.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine locks the SPI controller's configuration so that the software
> is
> > > +  no longer able to update:
> > > +  * Prefix table
> > > +  * Opcode menu
> > > +  * Opcode type table
> > > +  * BIOS base address
> > > +  * Protect range registers
> > > +
> > > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > > +  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the
> > > EFI_SPI_NOR_FLASH_PROTOCOL
> > > +/// with APls to support the legacy SPI flash controller.
> > > +///
> > > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
> > > +  ///
> > > +  /// This protocol manipulates the SPI NOR flash parts using a common
> set
> > > of
> > > +  /// commands.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
> > > +
> > > +  //
> > > +  // Legacy flash (SPI host) controller support
> > > +  //
> > > +
> > > +  ///
> > > +  /// Set the BIOS base address.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS
> > > BiosBaseAddress;
> > > +
> > > +  ///
> > > +  /// Clear the SPI protect range registers.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT
> > > ClearSpiProtect;
> > > +
> > > +  ///
> > > +  /// Determine if the SPI range is protected.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED
> > > IsRangeProtected;
> > > +
> > > +  ///
> > > +  /// Set the next protect range register.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE
> > > ProtectNextRange;
> > > +
> > > +  ///
> > > +  /// Lock the SPI controller configuration.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER
> > LockController;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
> > > +
> > > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > > b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > > new file mode 100644
> > > index 000000000000..6d8d557cefff
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI SMM Controler Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > > +#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > > +
> > > +#include <Protocol/LegacySpiController.h>
> > > +
> > > +///
> > > +/// Global ID for the Legacy SPI SMM Controller Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > > +  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> > > +    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > > +
> > > +typedef
> > > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
> > > +
> > > +#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > > b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > > new file mode 100644
> > > index 000000000000..a604a22f901f
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI SMM Flash Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > > +#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > > +
> > > +#include <Protocol/LegacySpiFlash.h>
> > > +
> > > +///
> > > +/// Global ID for the Legacy SPI SMM Flash Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > > +  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
> > > +    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > > +
> > > +typedef
> > > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > +EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
> > > +
> > > +#endif // __SPI_SMM_FLASH_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h
> > > b/MdePkg/Include/Protocol/SpiConfiguration.h
> > > new file mode 100644
> > > index 000000000000..3a602f67d7a6
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiConfiguration.h
> > > @@ -0,0 +1,293 @@
> > > +/** @file
> > > +  This file defines the SPI Configuration Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > > +
> > > +///
> > > +/// Global ID for the SPI Configuration Protocol
> > > +///
> > > +#define EFI_SPI_CONFIGURATION_GUID  \
> > > +  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
> > > +    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > > +
> > > +///
> > > +/// Macros to easily specify frequencies in hertz, kilohertz and
> megahertz.
> > > +///
> > > +#define Hz(Frequency)   (Frequency)
> > > +#define KHz(Frequency)  (1000 * Hz (Frequency))
> > > +#define MHz(Frequency)  (1000 * KHz (Frequency))
> > > +
> > > +typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
> > > +
> > > +/**
> > > +  Manipulate the chip select for a SPI device.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  Update the value of the chip select line for a SPI peripheral.
> > > +  The SPI bus layer calls this routine either in the board layer or in the SPI
> > > +  controller to manipulate the chip select pin at the start and end of a SPI
> > > +  transaction.
> > > +
> > > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > > structure
> > > +                            describing the SPI peripheral whose chip select pin
> > > +                            is to be manipulated. The routine may access the
> > > +                            ChipSelectParameter field to gain sufficient
> > > +                            context to complete the operation.
> > > +  @param[in] PinValue       The value to be applied to the chip select line
> of
> > > +                            the SPI peripheral.
> > > +
> > > +  @retval EFI_SUCCESS            The chip select was set successfully
> > > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > > +                                 initialized
> > > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral-
> > > >ChipSelectParameter value
> > > +                                 is invalid
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_CHIP_SELECT) (
> > > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > > +  IN BOOLEAN                   PinValue
> > > +  );
> > > +
> > > +/**
> > > +  Set up the clock generator to produce the correct clock frequency,
> phase
> > > and
> > > +  polarity for a SPI chip.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine updates the clock generator to generate the correct
> > > frequency
> > > +  and polarity for the SPI clock.
> > > +
> > > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> > structure
> > > from
> > > +                            which the routine can access the ClockParameter,
> > > +                            ClockPhase and ClockPolarity fields. The routine
> > > +                            also has access to the names for the SPI bus and
> > > +                            chip which can be used during debugging.
> > > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> > > clock
> > > +                            generator will choose a supported clock frequency
> > > +                            which is less then or equal to this value.
> > > +                            Specify zero to turn the clock generator off.
> > > +                            The actual clock frequency supported by the clock
> > > +                            generator will be returned.
> > > +
> > > +  @retval EFI_SUCCESS      The clock was set up successfully
> > > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> > the
> > > +                           frequency requested by CLockHz
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_CLOCK) (
> > > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > > +  IN UINT32                    *ClockHz
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_SPI_PART data structure provides a description of a SPI part
> > > which
> > > +/// is independent of the use on the board. This data is available directly
> > > +/// from the part's datasheet and may be provided by the vendor.
> > > +///
> > > +typedef struct _EFI_SPI_PART {
> > > +  ///
> > > +  /// A Unicode string specifying the SPI chip vendor.
> > > +  ///
> > > +  CONST CHAR16 *Vendor;
> > > +
> > > +  ///
> > > +  /// A Unicode string specifying the SPI chip part number.
> > > +  ///
> > > +  CONST CHAR16 *PartNumber;
> > > +
> > > +  ///
> > > +  /// The minimum SPI bus clock frequency used to access this chip. This
> > > value
> > > +  /// may be specified in the chip's datasheet. If not, use the value of
> zero.
> > > +  ///
> > > +  UINT32       MinClockHz;
> > > +
> > > +  ///
> > > +  /// The maximum SPI bus clock frequency used to access this chip. This
> > > value
> > > +  /// is found in the chip's datasheet.
> > > +  ///
> > > +  UINT32       MaxClockHz;
> > > +
> > > +  ///
> > > +  /// Specify the polarity of the chip select pin. This value can be found in
> > > +  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip
> > > select
> > > +  ///and FALSE when a zero asserts the chip select.
> > > +  ///
> > > +  BOOLEAN      ChipSelectPolarity;
> > > +} EFI_SPI_PART;
> > > +
> > > +///
> > > +/// The EFI_SPI_BUS data structure provides the connection details
> > > between the
> > > +/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which
> > controls
> > > that
> > > +/// SPI bus. This data structure also describes the details of how the
> clock
> > is
> > > +/// generated for that SPI bus. Finally this data structure provides the list
> > > +/// of physical SPI devices which are attached to the SPI bus.
> > > +///
> > > +typedef struct _EFI_SPI_BUS {
> > > +  ///
> > > +  /// A Unicode string describing the SPI bus
> > > +  ///
> > > +  CONST CHAR16                   *FriendlyName;
> > > +
> > > +  ///
> > > +  /// Address of the first EFI_SPI_PERIPHERAL data structure connected
> to
> > > this
> > > +  /// bus. Specify NULL if there are no SPI peripherals connected to this
> > bus.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
> > > +
> > > +  ///
> > > +  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which
> > > uniquely
> > > +  /// describes the SPI controller.
> > > +  ///
> > > +  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
> > > +
> > > +  ///
> > > +  /// Address of the routine which controls the clock used by the SPI bus
> > for
> > > +  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
> > > +  /// when this value is set to NULL.
> > > +  ///
> > > +  EFI_SPI_CLOCK                  Clock;
> > > +
> > > +  ///
> > > +  /// Address of a data structure containing the additional values which
> > > +  /// describe the necessary control for the clock. When Clock is NULL,
> > > +  /// the declaration for this data structure is provided by the vendor of
> > the
> > > +  /// host's SPI controller driver. When Clock is not NULL, the declaration
> > for
> > > +  /// this data structure is provided by the board layer.
> > > +  ///
> > > +  VOID                           *ClockParameter;
> > > +} EFI_SPI_BUS;
> > > +
> > > +///
> > > +/// The EFI_SPI_PERIPHERAL data structure describes how a specific
> block
> > > of
> > > +/// logic which is connected to the SPI bus. This data structure also
> selects
> > > +/// which upper level driver is used to manipulate this SPI device.
> > > +/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
> > > +/// peripheral driver.
> > > +///
> > > +struct _EFI_SPI_PERIPHERAL {
> > > +  ///
> > > +  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify
> > NULL
> > > if
> > > +  /// the current data structure is the last one on the SPI bus.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
> > > +
> > > +  ///
> > > +  /// A unicode string describing the function of the SPI part.
> > > +  ///
> > > +  CONST CHAR16             *FriendlyName;
> > > +
> > > +  ///
> > > +  /// Address of a GUID provided by the vendor of the SPI peripheral
> > driver.
> > > +  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus
> driver
> > > uses
> > > +  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and
> to
> > > +  /// provide the connection points for the SPI peripheral drivers.
> > > +  /// This reduces the comparison logic in the SPI peripheral driver's
> > > +  /// Supported routine.
> > > +  ///
> > > +  CONST GUID               *SpiPeripheralDriverGuid;
> > > +
> > > +  ///
> > > +  /// The address of an EFI_SPI_PART data structure which describes this
> > > chip.
> > > +  ///
> > > +  CONST EFI_SPI_PART       *SpiPart;
> > > +
> > > +  ///
> > > +  /// The maximum clock frequency is specified in the EFI_SPI_P ART.
> > When
> > > this
> > > +  /// this value is non-zero and less than the value in the EFI_SPI_PART
> > then
> > > +  /// this value is used for the maximum clock frequency for the SPI part.
> > > +  ///
> > > +  UINT32                   MaxClockHz;
> > > +
> > > +  ///
> > > +  /// Specify the idle value of the clock as found in the datasheet.
> > > +  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
> > > +  /// clock's idle value is high.
> > > +  ///
> > > +  BOOLEAN                  ClockPolarity;
> > > +
> > > +  ///
> > > +  /// Specify the clock delay after chip select. Specify zero (0) to delay an
> > > +  /// entire clock cycle or one (1) to delay only half a clock cycle.
> > > +  ///
> > > +  BOOLEAN                  ClockPhase;
> > > +
> > > +  ///
> > > +  /// SPI peripheral attributes, select zero or more of:
> > > +  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI
> > > peripheral is wired to
> > > +  ///   support a 2-bit data bus
> > > +  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI
> > > peripheral is wired to
> > > +  ///   support a 4-bit data bus
> > > +  ///
> > > +  UINT32                   Attributes;
> > > +
> > > +  ///
> > > +  /// Address of a vendor specific data structure containing additional
> > board
> > > +  /// configuration details related to the SPI chip. The SPI peripheral layer
> > > +  /// uses this data structure when configuring the chip.
> > > +  ///
> > > +  CONST VOID               *ConfigurationData;
> > > +
> > > +  ///
> > > +  /// The address of an EFI_SPI_BUS data structure which describes the
> SPI
> > > bus
> > > +  /// to which this chip is connected.
> > > +  ///
> > > +  CONST EFI_SPI_BUS        *SpiBus;
> > > +
> > > +  ///
> > > +  /// Address of the routine which controls the chip select pin for this SPI
> > > +  /// peripheral. Call the SPI host controller's chip select routine when
> this
> > > +  /// value is set to NULL.
> > > +  ///
> > > +  EFI_SPI_CHIP_SELECT      ChipSelect;
> > > +
> > > +  ///
> > > +  /// Address of a data structure containing the additional values which
> > > +  /// describe the necessary control for the chip select. When ChipSelect
> is
> > > +  /// NULL, the declaration for this data structure is provided by the
> > vendor
> > > +  /// of the host's SPI controller driver. The vendor's documentation
> > > specifies
> > > +  /// the necessary values to use for the chip select pin selection and
> > > +  /// control. When Chipselect is not NULL, the declaration for this data
> > > +  /// structure is provided by the board layer.
> > > +  ///
> > > +  VOID                     *ChipSelectParameter;
> > > +};
> > > +
> > > +///
> > > +/// Describe the details of the board's SPI busses to the SPI driver stack.
> > > +/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to
> > > expose the data
> > > +/// tables which describe the board's SPI busses, The SPI bus layer uses
> > > these
> > > +/// tables to configure the clock, chip select and manage the SPI
> > > transactions
> > > +/// on the SPI controllers.
> > > +///
> > > +typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
> > > +  ///
> > > +  /// The number of SPI busses on the board.
> > > +  ///
> > > +  UINT32                          BusCount;
> > > +
> > > +  ///
> > > +  /// The address of an array of EFI_SPI_BUS data structure addresses.
> > > +  ///
> > > +  CONST EFI_SPI_BUS *CONST *CONST Buslist;
> > > +} EFI_SPI_CONFIGURATION_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
> > > +
> > > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiHc.h
> > > b/MdePkg/Include/Protocol/SpiHc.h
> > > new file mode 100644
> > > index 000000000000..13ad5f45225c
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiHc.h
> > > @@ -0,0 +1,194 @@
> > > +/** @file
> > > +  This file defines the SPI Host Controller Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_HC_PROTOCOL_H__
> > > +#define __SPI_HC_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiConfiguration.h>
> > > +#include <Protocol/SpiIo.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI Host Controller Protocol
> > > +///
> > > +#define EFI_SPI_HOST_GUID  \
> > > +  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
> > > +    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > > +
> > > +///
> > > +/// EDK2-style name
> > > +///
> > > +#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
> > > +
> > > +typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
> > > +
> > > +/**
> > > +  Assert or deassert the SPI chip select.
> > > +
> > > +  This routine is called at TPL_NOTIFY.
> > > +  Update the value of the chip select line for a SPI peripheral. The SPI bus
> > > +  layer calls this routine either in the board layer or in the SPI controller
> > > +  to manipulate the chip select pin at the start and end of a SPI
> transaction.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > > structure
> > > +                            describing the SPI peripheral whose chip select pin
> > > +                            is to be manipulated. The routine may access the
> > > +                            ChipSelectParameter field to gain sufficient
> > > +                            context to complete the operati on.
> > > +  @param[in] PinValue       The value to be applied to the chip select line
> of
> > > +                            the SPI peripheral.
> > > +
> > > +  @retval EFI_SUCCESS            The chip select was set as requested
> > > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > > +                                 initialized
> > > +  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its
> contents
> > > are
> > > +                                 invalid
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
> > > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > > +  IN BOOLEAN                    PinValue
> > > +  );
> > > +
> > > +/**
> > > +  Set up the clock generator to produce the correct clock frequency,
> phase
> > > and
> > > +  polarity for a SPI chip.
> > > +
> > > +  This routine is called at TPL_NOTIFY.
> > > +  This routine updates the clock generator to generate the correct
> > > frequency
> > > +  and polarity for the SPI clock.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> > structure
> > > from
> > > +                            which the routine can access the ClockParameter,
> > > +                            ClockPhase and ClockPolarity fields. The routine
> > > +                            also has access to the names for the SPI bus and
> > > +                            chip which can be used during debugging.
> > > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> > SPI
> > > +                            host controller will choose a supported clock
> > > +                            frequency which is less then or equal to this
> > > +                            value. Specify zero to turn the clock generator
> > > +                            off. The actual clock frequency supported by the
> > > +                            SPI host controller will be returned.
> > > +
> > > +  @retval EFI_SUCCESS      The clock was set up successfully
> > > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> > the
> > > +                           frequency requested by ClockHz
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
> > > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > > +  IN UINT32                      *ClockHz
> > > +  );
> > > +
> > > +/**
> > > +  Perform the SPI transaction on the SPI peripheral using the SPI host
> > > +  controller.
> > > +
> > > +  This routine is called at TPL_NOTIFY.
> > > +  This routine synchronously returns EFI_SUCCESS indicating that the
> > > +  asynchronous SPI transaction was started. The routine then waits for
> > > +  completion of the SPI transaction prior to returning the final transaction
> > > +  status.
> > > +
> > > +  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > > +  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION
> > > containing
> > > +                             the description of the SPI transaction to perform.
> > > +
> > > +  @retval EFI_SUCCESS          The transaction completed successfully
> > > +  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value
> is
> > > invalid,
> > > +                               or the BusTransaction->ReadinBytes value is
> > > +                               invalid
> > > +  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type
> is
> > > +                               unsupported
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> > > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > > +  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
> > > +  );
> > > +
> > > +///
> > > +/// Support a SPI data transaction between the SPI controller and a SPI
> > chip.
> > > +///
> > > +struct _EFI_SPI_HC_PROTOCOL {
> > > +  ///
> > > +  /// Host control attributes, may have zero or more of the following set:
> > > +  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> > > +  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> > > +  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> > > +  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > > +  ///   - The SPI host controller requires the transmit frame to be in most
> > > +  ///     significant bits instead of least significant bits.The host driver
> > > +  ///     will adjust the frames if necessary.
> > > +  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > > +  ///   - The SPI host controller places the receive frame to be in most
> > > +  ///     significant bits instead of least significant bits.The host driver
> > > +  ///     will adjust the frames to be in the least significant bits if
> > > +  ///     necessary.
> > > +  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
> > > +  ///   - The SPI controller supports a 2 - bit data bus
> > > +  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> > > +  ///   - The SPI controller supports a 4 - bit data bus
> > > +  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> > > +  ///   - Transfer size includes the opcode byte
> > > +  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> > > +  ///   - Transfer size includes the 3 address bytes
> > > +  /// The SPI host controller must support full - duplex (receive while
> > > +  /// sending) operation.The SPI host controller must support a 1 - bit
> bus
> > > +  /// width.
> > > +  ///
> > > +  UINT32                          Attributes;
> > > +
> > > +  ///
> > > +  /// Mask of frame sizes which the SPI host controller supports. Frame
> > size
> > > of
> > > +  /// N-bits is supported when bit N-1 is set. The host controller must
> > > support
> > > +  /// a frame size of 8-bits.
> > > +  ///
> > > +  UINT32                          FrameSizeSupportMask;
> > > +
> > > +  ///
> > > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > > +  ///
> > > +  UINT32                          MaximumTransferBytes;
> > > +
> > > +  ///
> > > +  /// Assert or deassert the SPI chip select.
> > > +  ///
> > > +  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
> > > +
> > > +  ///
> > > +  /// Set up the clock generator to produce the correct clock frequency,
> > > phase
> > > +  /// and polarity for a SPI chip.
> > > +  ///
> > > +  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
> > > +
> > > +  ///
> > > +  /// Perform the SPI transaction on the SPI peripheral using the SPI host
> > > +  /// controller.
> > > +  ///
> > > +  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiSpiHcProtocolGuid;
> > > +
> > > +#endif // __SPI_HC_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiIo.h
> > > b/MdePkg/Include/Protocol/SpiIo.h
> > > new file mode 100644
> > > index 000000000000..e481779acc58
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiIo.h
> > > @@ -0,0 +1,292 @@
> > > +/** @file
> > > +  This file defines the SPI I/O Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_IO_PROTOCOL_H__
> > > +#define __SPI_IO_PROTOCOL_H__
> > > +
> > > +#include <Protocol/LegacySpiController.h>
> > > +#include <Protocol/SpiConfiguration.h>
> > > +
> > > +typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> > > +
> > > +///
> > > +/// Note: The UEFI PI 1.6 specification does not specify values for the
> > > +///       members below. The order matches the specification.
> > > +///
> > > +typedef enum {
> > > +  ///
> > > +  /// Data flowing in both direction between the host and
> > > +  /// SPI peripheral.ReadBytes must equal WriteBytes and both
> > ReadBuffer
> > > and
> > > +  /// WriteBuffer must be provided.
> > > +  ///
> > > +  SPI_TRANSACTION_FULL_DUPLEX,
> > > +
> > > +  ///
> > > +  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> > > +  /// zero.WriteBytes must be non - zero and WriteBuffer must be
> > provided.
> > > +  ///
> > > +  SPI_TRANSACTION_WRITE_ONLY,
> > > +
> > > +  ///
> > > +  /// Data flowing from the SPI peripheral to the host.WriteBytes must
> be
> > > +  /// zero.ReadBytes must be non - zero and ReadBuffer must be
> > provided.
> > > +  ///
> > > +  SPI_TRANSACTION_READ_ONLY,
> > > +
> > > +  ///
> > > +  /// Data first flowing from the host to the SPI peripheral and then data
> > > +  /// flows from the SPI peripheral to the host.These types of operations
> > get
> > > +  /// used for SPI flash devices when control data (opcode, address)
> must
> > be
> > > +  /// passed to the SPI peripheral to specify the data to be read.
> > > +  ///
> > > +  SPI_TRANSACTION_WRITE_THEN_READ
> > > +} EFI_SPI_TRANSACTION_TYPE;
> > > +
> > > +/**
> > > +  Initiate a SPI transaction between the host and a SPI peripheral.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine works with the SPI bus layer to pass the SPI transaction to
> > the
> > > +  SPI controller for execution on the SPI bus. There are four types of
> > > +  supported transactions supported by this routine:
> > > +  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> > > +  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes =
> 0
> > > +  * Read Only: ReadBuffer to receive data from SPI peripheral,
> WriteBytes
> > =
> > > 0
> > > +  * Write Then Read: WriteBuffer contains control data to write to SPI
> > > +                     peripheral before data is placed into the ReadBuffer.
> > > +                     Both WriteBytes and ReadBytes must be non-zero.
> > > +
> > > +  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > > +  @param[in]  TransactionType   Type of SPI transaction.
> > > +  @param[in]  DebugTransaction  Set TRUE only when debugging is
> > desired.
> > > +                                Debugging may be turned on for a single SPI
> > > +                                transaction. Only this transaction will display
> > > +                                debugging messages. All other transactions with
> > > +                                this value set to FALSE will not display any
> > > +                                debugging messages.
> > > +  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
> > > +                                the maximum clock frequency supported by the
> > > +                                SPI controller and part. Specify a non-zero
> > > +                                value only when a specific SPI transaction
> > > +                                requires a reduced clock rate.
> > > +  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
> > > +  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
> > > +  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
> > > +                                Specify zero for read-only operations.
> > > +  @param[in]  WriteBuffer       The buffer containing data to be sent from
> > the
> > > +                                host to the SPI chip. Specify NULL for read
> > > +                                only operations.
> > > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > > +                                  frame
> > > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > > +                                  frame
> > > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > > +                                  per frame The transmit frame is in the least
> > > +                                  significant N bits.
> > > +  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
> > > +                                Specify zero for write-only operations.
> > > +  @param[out] ReadBuffer        The buffer to receeive data from the SPI
> > chip
> > > +                                during the transaction. Specify NULL for write
> > > +                                only operations.
> > > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > > +                                  frame
> > > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > > +                                  frame
> > > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > > +                                  per frame The received frame is in the least
> > > +                                  significant N bits.
> > > +
> > > +  @retval EFI_SUCCESS            The SPI transaction completed successfully
> > > +  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
> > > +  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
> > > +  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
> > > +                                 or BusWidth not supported by SPI peripheral or
> > > +                                 SPI host controller,
> > > +                                 or WriteBytes non-zero and WriteBuffer is
> > > +                                 NULL,
> > > +                                 or ReadBytes non-zero and ReadBuffer is NULL,
> > > +                                 or ReadBuffer != WriteBuffer for full-duplex
> > > +                                 type,
> > > +                                 or WriteBuffer was NULL,
> > > +                                 or TPL is too high
> > > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI
> > transaction
> > > +  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the
> > SPI
> > > bus
> > > +                                 layer or the SPI host controller
> > > +  @retval EFI_UNSUPPORTED        The SPI controller was not able to
> > support
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> > > +  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
> > > +  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
> > > +  IN  BOOLEAN                    DebugTransaction,
> > > +  IN  UINT32                     ClockHz OPTIONAL,
> > > +  IN  UINT32                     BusWidth,
> > > +  IN  UINT32                     FrameSize,
> > > +  IN  UINT32                     WriteBytes,
> > > +  IN  UINT8                      *WriteBuffer,
> > > +  IN  UINT32                     ReadBytes,
> > > +  OUT UINT8                      *ReadBuffer
> > > +  );
> > > +
> > > +/**
> > > +  Update the SPI peripheral associated with this SPI 10 instance.
> > > +
> > > +  Support socketed SPI parts by allowing the SPI peripheral driver to
> > replace
> > > +  the SPI peripheral after the connection is made. An example use is
> > > socketed
> > > +  SPI NOR flash parts, where the size and parameters change depending
> > > upon
> > > +  device is in the socket.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > > +  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL
> structure.
> > > +
> > > +  @retval EFI_SUCCESS            The SPI peripheral was updated
> successfully
> > > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
> > > +                                 or the SpiPeripheral->SpiBus is NULL,
> > > +                                 or the SpiP eripheral - >SpiBus pointing at
> > > +                                 wrong bus,
> > > +                                 or the SpiP eripheral - >SpiPart is NULL
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> > > +  IN CONST EFI_SPI_IO_PROTOCOL  *This,
> > > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_SPI_BUS_ TRANSACTION data structure contains the
> > > description of the
> > > +/// SPI transaction to perform on the host controller.
> > > +///
> > > +typedef struct _EFI_SPI_BUS_TRANSACTION {
> > > +  ///
> > > +  /// Pointer to the SPI peripheral being manipulated.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Type of transaction specified by one of the
> > > EFI_SPI_TRANSACTION_TYPE
> > > +  /// values.
> > > +  ///
> > > +  EFI_SPI_TRANSACTION_TYPE TransactionType;
> > > +
> > > +  ///
> > > +  /// TRUE if the transaction is being debugged. Debugging may be
> turned
> > > on for
> > > +  /// a single SPI transaction. Only this transaction will display debugging
> > > +  /// messages. All other transactions with this value set to FALSE will not
> > > +  /// display any debugging messages.
> > > +  ///
> > > +  BOOLEAN                  DebugTransaction;
> > > +
> > > +  ///
> > > +  /// SPI bus width in bits: 1, 2, 4
> > > +  ///
> > > +  UINT32                   BusWidth;
> > > +
> > > +  ///
> > > +  /// Frame size in bits, range: 1 - 32
> > > +  ///
> > > +  UINT32                   FrameSize;
> > > +
> > > +  ///
> > > +  /// Length of the write buffer in bytes
> > > +  ///
> > > +  UINT32                   WriteBytes;
> > > +
> > > +  ///
> > > +  /// Buffer containing data to send to the SPI peripheral
> > > +  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > > +  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > > +  ///
> > > +  UINT8                    *WriteBuffer;
> > > +
> > > +  ///
> > > +  /// Length of the read buffer in bytes
> > > +  ///
> > > +  UINT32                   ReadBytes;
> > > +
> > > +  ///
> > > +  /// Buffer to receive the data from the SPI peripheral
> > > +  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > > +  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > > +  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> > > +  ///
> > > +  UINT8                    *ReadBuffer;
> > > +} EFI_SPI_BUS_TRANSACTION;
> > > +
> > > +///
> > > +/// Support managed SPI data transactions between the SPI controller
> > and a
> > > SPI
> > > +/// chip.
> > > +///
> > > +struct _EFI_SPI_IO_PROTOCOL {
> > > +  ///
> > > +  /// Address of an EFI_SPI_PERIPHERAL data structure associated with
> > this
> > > +  /// protocol instance.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Address of the original EFI_SPI_PERIPHERAL data structure
> associated
> > > with
> > > +  /// this protocol instance.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of
> N-
> > > bits
> > > +  /// is supported when bit N-1 is set. The host controller must support a
> > > +  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted
> to
> > > +  /// 8-bit frame sizes by the SPI bus layer if the frame size is not
> > supported
> > > +  /// by the SPI host controller.
> > > +  ///
> > > +  UINT32                                    FrameSizeSupportMask;
> > > +
> > > +  ///
> > > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > > +  ///
> > > +  UINT32                                    MaximumTransferBytes;
> > > +
> > > +  ///
> > > +  /// Transaction attributes: One or more from:
> > > +  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> > > +  ///   - The SPI host and peripheral supports a 2-bit data bus
> > > +  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> > > +  ///   - The SPI host and peripheral supports a 4-bit data bus
> > > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> > > +  ///   - Transfer size includes the opcode byte
> > > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> > > +  ///   - Transfer size includes the 3 address bytes
> > > +  ///
> > > +  UINT32                                    Attributes;
> > > +
> > > +  ///
> > > +  /// Pointer to legacy SPI controller protocol
> > > +  ///
> > > +  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> *LegacySpiProtocol;
> > > +
> > > +  ///
> > > +  /// Initiate a SPI transaction between the host and a SPI peripheral.
> > > +  ///
> > > +  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
> > > +
> > > +  ///
> > > +  /// Update the SPI peripheral associated with this SPI 10 instance.
> > > +  ///
> > > +  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL
> UpdateSpiPeripheral;
> > > +};
> > > +
> > > +#endif // __SPI_IO_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h
> > > b/MdePkg/Include/Protocol/SpiNorFlash.h
> > > new file mode 100644
> > > index 000000000000..93d2adaa860e
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiNorFlash.h
> > > @@ -0,0 +1,289 @@
> > > +/** @file
> > > +  This file defines the SPI NOR Flash Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
> > > +#define __SPI_NOR_FLASH_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiConfiguration.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI NOR Flash Protocol
> > > +///
> > > +#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
> > > +  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
> > > +    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > > +
> > > +typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL
> > > EFI_SPI_NOR_FLASH_PROTOCOL;
> > > +
> > > +/**
> > > +  Read the 3 byte manufacture and device ID from the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads the 3 byte manufacture and device ID from the flash
> > > part
> > > +  filling the buffer provided.
> > > +
> > > +  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> > > structure.
> > > +  @param[out] Buffer  Pointer to a 3 byte buffer to receive the
> > manufacture
> > > and
> > > +                      device ID.
> > > +
> > > +
> > > +
> > > +  @retval EFI_SUCCESS            The manufacture and device ID was read
> > > +                                 successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL
> > > +  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash
> part.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  OUT UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Read data from the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads data from the SPI part in the buffer provided.
> > > +
> > > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                             structure.
> > > +  @param[in]  FlashAddress   Address in the flash to start reading
> > > +  @param[in]  LengthInBytes  Read length in bytes
> > > +  @param[out] Buffer         Address of a buffer to receive the data
> > > +
> > > +  @retval EFI_SUCCESS            The data was read successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > > +                                 FlashAddress >= This->FlashSize, or
> > > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN  UINT32                            FlashAddress,
> > > +  IN  UINT32                            LengthInBytes,
> > > +  OUT UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Low frequency read data from the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads data from the SPI part in the buffer provided.
> > > +
> > > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                             structure.
> > > +  @param[in]  FlashAddress   Address in the flash to start reading
> > > +  @param[in]  LengthInBytes  Read length in bytes
> > > +  @param[out] Buffer         Address of a buffer to receive the data
> > > +
> > > +  @retval EFI_SUCCESS            The data was read successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > > +                                 FlashAddress >= This->FlashSize, or
> > > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN  UINT32                            FlashAddress,
> > > +  IN  UINT32                            LengthInBytes,
> > > +  OUT UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Read the flash status register.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads the flash part status register.
> > > +
> > > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                             structure.
> > > +  @param[in]  LengthInBytes  Number of status bytes to read.
> > > +  @param[out] FlashStatus    Pointer to a buffer to receive the flash
> status.
> > > +
> > > +  @retval EFI_SUCCESS  The status register was read successfully.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN  UINT32                            LengthInBytes,
> > > +  OUT UINT8                             *FlashStatus
> > > +  );
> > > +
> > > +/**
> > > +  Write the flash status register.
> > > +
> > > +  This routine must be called at or below TPL_N OTIFY.
> > > +  This routine writes the flash part status register.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                            structure.
> > > +  @param[in] LengthInBytes  Number of status bytes to write.
> > > +  @param[in] FlashStatus    Pointer to a buffer containing the new status.
> > > +
> > > +  @retval EFI_SUCCESS           The status write was successful.
> > > +  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
> > > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                            LengthInBytes,
> > > +  IN UINT8                             *FlashStatus
> > > +  );
> > > +
> > > +/**
> > > +  Write data to the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine breaks up the write operation as necessary to write the
> data
> > > to
> > > +  the SPI part.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                            structure.
> > > +  @param[in] FlashAddress   Address in the flash to start writing
> > > +  @param[in] LengthInBytes  Write length in bytes
> > > +  @param[in] Buffer         Address of a buffer containing the data
> > > +
> > > +  @retval EFI_SUCCESS            The data was written successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > > +                                 FlashAddress >= This->FlashSize, or
> > > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy
> buffer.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
> > > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                            FlashAddress,
> > > +  IN UINT32                            LengthInBytes,
> > > +  IN UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Efficiently erases one or more 4KiB regions in the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine uses a combination of 4 KiB and larger blocks to erase the
> > > +  specified area.
> > > +
> > > +  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > > +                           structure.
> > > +  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
> > > +  @param[in] BlockCount    Number of 4 KiB blocks to erase
> > > +
> > > +  @retval EFI_SUCCESS            The erase was completed successfully.
> > > +  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
> > > +                                 BlockCount * 4 KiB
> > > +                                   > This->FlashSize - FlashAddress
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
> > > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                            FlashAddress,
> > > +  IN UINT32                            BlockCount
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral
> layer.
> > > +/// This protocol manipulates the SPI NOR flash parts using a common
> set
> > of
> > > +/// commands. The board layer provides the interconnection and
> > > configuration
> > > +/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
> > > +/// configuration data to expose a generic interface which provides the
> > > +/// following APls:
> > > +/// * Read manufacture and device ID
> > > +/// * Read data
> > > +/// * Read data using low frequency
> > > +/// * Read status
> > > +/// * Write data
> > > +/// * Erase 4 KiB blocks
> > > +/// * Erase 32 or 64 KiB blocks
> > > +/// * Write status
> > > +/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set
> > the
> > > security
> > > +/// features on the legacy SPI flash controller.
> > > +///
> > > +struct _EFI_SPI_NOR_FLASH_PROTOCOL {
> > > +  ///
> > > +  /// Pointer to an EFI_SPI_PERIPHERAL data structure
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Flash size in bytes
> > > +  ///
> > > +  UINT32                                  FlashSize;
> > > +
> > > +  ///
> > > +  /// Manufacture and Device ID
> > > +  ///
> > > +  UINT8                                   Deviceid[3];
> > > +
> > > +  ///
> > > +  /// Erase block size in bytes
> > > +  ///
> > > +  UINT32                                  EraseBlockBytes;
> > > +
> > > +  ///
> > > +  /// Read the 3 byte manufacture and device ID from the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
> > > +
> > > +  ///
> > > +  /// Read data from the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
> > > +
> > > +  ///
> > > +  /// Low frequency read data from the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
> > > +
> > > +  ///
> > > +  /// Read the flash status register.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
> > > +
> > > +  ///
> > > +  /// Write the flash status register.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
> > > +
> > > +  ///
> > > +  /// Write data to the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
> > > +
> > > +  ///
> > > +  /// Efficiently erases one or more 4KiB regions in the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
> > > +
> > > +#endif // __SPI_NOR_FLASH_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > > b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > > new file mode 100644
> > > index 000000000000..913d4cbb46aa
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the SPI SMM Configuration Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > > +#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiConfiguration.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI SMM Configuration Protocol
> > > +///
> > > +#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
> > > +  { 0x995c6eca, 0x171b, 0x45fd,                  \
> > > +    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > > +
> > > +typedef
> > > +struct _EFI_SPI_CONFIGURATION_PROTOCOL
> > > +EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
> > > +
> > > +#endif // __SPI_SMM_CONFIGURATION_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h
> > > b/MdePkg/Include/Protocol/SpiSmmHc.h
> > > new file mode 100644
> > > index 000000000000..91d2312b74b4
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiSmmHc.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the SPI SMM Host Controller Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_SMM_HC_H__
> > > +#define __SPI_SMM_HC_H__
> > > +
> > > +#include <Protocol/SpiHc.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI SMM Host Controller Protocol
> > > +///
> > > +#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
> > > +  { 0xe9f02217, 0x2093, 0x4470,       \
> > > +    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > > +
> > > +typedef
> > > +struct _EFI_SPI_HC_PROTOCOL
> > > +EFI_SPI_SMM_HC_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
> > > +
> > > +#endif // __SPI_SMM_HC_H__
> > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> > > index 1867c54c3bc1..91af6c5c455c 100644
> > > --- a/MdePkg/MdePkg.dec
> > > +++ b/MdePkg/MdePkg.dec
> > > @@ -1246,6 +1246,37 @@ [Protocols]
> > >    gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd,
> > > { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
> > >
> > >    #
> > > +  # Protocols defined in PI 1.6.
> > > +  #
> > > +
> > > +  ## Include/Protocol/LegacySpiController.h
> > > +  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de,
> > > { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > > +
> > > +  ## Include/Protocol/LegacySpiFlash.h
> > > +  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, {
> > 0x96,
> > > 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > > +
> > > +  ## Include/Protocol/LegacySpiSmmController.h
> > > +  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0,
> > 0x4c8c,
> > > { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > > +
> > > +  ## Include/Protocol/LegacySpiSmmFlash.h
> > > +  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0,
> > > { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > > +
> > > +  ## Include/Protocol/SpiConfiguration.h
> > > +  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, {
> > 0xb3,
> > > 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > > +
> > > +  ## Include/Protocol/SpiHc.h
> > > +  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3,
> > 0x99,
> > > 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > > +
> > > +  ## Include/Protocol/SpiNorFlash.h
> > > +  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, {
> 0x85,
> > > 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > > +
> > > +  ## Include/Protocol/SpiSmmConfiguration.h
> > > +  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b,
> 0x45fd,
> > > { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > > +
> > > +  ## Include/Protocol/SpiSmmHc.h
> > > +  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, {
> 0x8a,
> > > 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > > +
> > > +  #
> > >    # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
> > >    #
> > >
> > > --
> > > 2.12.2.windows.2
> > >
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Zimmer, Vincent 6 years, 6 months ago
Good points on the use case.  I'll take a look.
Thanks again
Vincent

-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Marvin Häuser
Sent: Wednesday, September 20, 2017 2:26 PM
To: edk2-devel@lists.01.org
Cc: Zimmer, Vincent <vincent.zimmer@intel.com>
Subject: Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.

Hey Vincent,

Thank you for your response!
It would be very kind of you if you would post an update to edk2-devel and CC me once you get a response from the Forum!

In case you know somebody working on the MM part of the specification, could you please forward the following?
There is a potential problem with EFI_MM_IO_TRAP_DISPATCH_PROTOCOL.Register() that might prevent a Standalone MM implementation:
"If the base of the I/O range specified is zero, then an I/O range with the specified length and characteristics will be allocated and the Address field in RegisterContext updated."
With the current specification, the only way to allocate an I/O Range I know is via the DXE Services, though using the DXE services means that a Standalone MM implementation is not possible. Maybe 0 should no longer be accepted as a possible value (of course that would require an IoTrapDispatch2)? A Standalone MM driver which calls this function would then depend on a DXE driver to already have allocated the range via the DXE Services (the MM driver should probably hook the EndOfDxe event to make sure the DXE code has run). On the other hand, the Standalone MM IoTrap consumer has no way of knowing whether the allocation was completed successfully. So, the only proper way I see would be implementing I/O range allocation during PEI phase and then exposing those allocations via the HOB list, which is available to both the DXE Core to take note of the allocations, as well as the Standalone MM Core, which can expose them to the MM Standalone Drivers. Any comments? Did I maybe overlook something?

Thanks,
Marvin.

> -----Original Message-----
> From: Zimmer, Vincent [mailto:vincent.zimmer@intel.com]
> Sent: Wednesday, September 20, 2017 10:24 PM
> To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-
> devel@lists.01.org
> Cc: Bi, Dandan <dandan.bi@intel.com>; Shaw, Kevin W
> <kevin.w.shaw@intel.com>; Leahy, Leroy P <leroy.p.leahy@intel.com>; UEFI
> Administration <admin@uefi.org>
> Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Marvin:
> 
> Thanks for all of the feedback on the SPI items from the most recent UEFI PI
> spec. We're updating the PI spec now responsive to your findings and these
> corrections will be reflected in an upcoming errata.
> 
> Sorry for the delayed response to you on the findings. I'll follow up w/ UEFI
> Forum on why we cannot readily use the fw/os forum mailing list for this
> type of discussion, too.
> 
> Vincent
> 
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Marvin Häuser
> Sent: Friday, September 15, 2017 7:57 AM
> To: edk2-devel@lists.01.org
> Cc: Bi, Dandan <dandan.bi@intel.com>
> Subject: Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> Hey Dandan,
> 
> Sorry for the mistakes, I will send them a part of a V2 once you finished
> reviewing.
> No problem for the delay, it's not high priority at all. Thanks for reviewing it!
> 
> There are problems within the specification regarding the SPI protocols
> anyway.
> I wanted to report these, though I don't know where to. Andrew suggested
> to post to the FW/OS Forum,
> though it is currently not available, so I'm awaiting response from the UEFI
> Forum administration.
> 
> Best regards,
> Marvin.
> 
> > -----Original Message-----
> > From: Bi, Dandan [mailto:dandan.bi@intel.com]
> > Sent: Friday, September 15, 2017 10:22 AM
> > To: Ni, Ruiyu <ruiyu.ni@intel.com>; Marvin Häuser
> > <Marvin.Haeuser@outlook.com>; edk2-devel@lists.01.org
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>
> > Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > introduced in UEFI PI 1.6.
> >
> > Hi Marvin,
> >
> > Thank you for your contribution. I am reviewing this patch now. Currently I
> > just take a look at the SMM SPI part and find:
> >
> > 1. There is a typo in LegacySpiSmmController.h
> > The definition should be EFI_LEGACY_SPI_SMM_CONTROLLER_GUID, not
> > EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID.
> > Typo:
> > #define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> >   { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> >     { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > And it should  be:
> > #define EFI_LEGACY_SPI_SMM_CONTROLLER_GUID \
> > { 0x62331b78, 0xd8d0, 0x4c8c, { 0x8c, 0xcb, 0xd2, 0x7d, \ 0xfe, 0x32, 0xdb,
> > 0x9b }}
> >
> > 2. EFI_SPI_SMM_NOR_FLASH_PROTOCOL definition seems to be missing.
> >
> > I will review the remaining part. It may take some time. Sorry for the delay
> in
> > my response
> >
> > Thanks,
> > Dandan
> >
> > -----Original Message-----
> > From: Ni, Ruiyu
> > Sent: Thursday, September 7, 2017 3:13 PM
> > To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-
> > devel@lists.01.org
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>; Bi, Dandan <dandan.bi@intel.com>
> > Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > introduced in UEFI PI 1.6.
> >
> > Marvin,
> > Thank you for your contribution. We will need some time to review the
> > definitions against PI Spec.
> > If there is a need to post V2, it might be better to separate the header files
> in
> > different groups.
> > For example, LegacySpi group, SPI group, SMM SPI group.
> >
> > Thanks/Ray
> >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > > Marvin Häuser
> > > Sent: Wednesday, September 6, 2017 5:21 PM
> > > To: edk2-devel@lists.01.org
> > > Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> > > <liming.gao@intel.com>
> > > Subject: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> > > introduced in UEFI PI 1.6.
> > >
> > > This commit adds header files for the SPI protocols introduced in the
> > > UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.
> > >
> > > EFI_SPI_TRANSACTION_TYPE assumes an enum with its members
> ordered
> > > the
> > > way they are listed in the specification, as there are no values given
> > > explicitely.
> > > EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in
> the
> > > specification was meant to be '1'.
> > >
> > > Contributed-under: TianoCore Contribution Agreement 1.1
> > > Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
> > > ---
> > >  MdePkg/Include/Protocol/LegacySpiController.h    | 265
> > > ++++++++++++++++++
> > >  MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
> > >  MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
> > >  MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
> > >  MdePkg/Include/Protocol/SpiConfiguration.h       | 293
> > > ++++++++++++++++++++
> > >  MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
> > >  MdePkg/Include/Protocol/SpiIo.h                  | 292
> +++++++++++++++++++
> > >  MdePkg/Include/Protocol/SpiNorFlash.h            | 289
> > > +++++++++++++++++++
> > >  MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
> > >  MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
> > >  MdePkg/MdePkg.dec                                |  31 +++
> > >  11 files changed, 1709 insertions(+)
> > >
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiController.h
> > > b/MdePkg/Include/Protocol/LegacySpiController.h
> > > new file mode 100644
> > > index 000000000000..2d36eaefc0ee
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiController.h
> > > @@ -0,0 +1,265 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI Controller Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > > +#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > > +
> > > +///
> > > +/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
> > > +///       definition. This definition assumes it was supposed to be '1'.
> > > +///
> > > +/// Global ID for the Legacy SPI Controller Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
> > > +  { 0x39136fc7, 0x1a11, 0x49de,         \
> > > +    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > > +
> > > +typedef
> > > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
> > > +
> > > +/**
> > > +  Set the erase block opcode.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The menu table contains SPI transaction opcodes which are accessible
> > > after
> > > +  the legacy SPI flash controller's configuration is locked. The board layer
> > > +  specifies the erase block size for the SPI NOR flash part. The SPI NOR
> > flash
> > > +  peripheral driver selects the erase block opcode which matches the
> > erase
> > > +  block size and uses this API to load the opcode into the opcode menu
> > table.
> > > +
> > > +  @param[in] This              Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                               structure.
> > > +  @param[in] EraseBlockOpcode  Erase block opcode to be placed into
> the
> > > opcode
> > > +                               menu table.
> > > +
> > > +  @retval EFI_SUCCESS       The opcode menu table was updated
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT8                                     EraseBlockOpcode
> > > +  );
> > > +
> > > +/**
> > > +  Set the write status prefix opcode.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The prefix table contains SPI transaction write prefix opcodes which are
> > > +  accessible after the legacy SPI flash controller's configuration is locked.
> > > +  The board layer specifies the write status prefix opcode for the SPI
> NOR
> > > +  flash part. The SPI NOR flash peripheral driver uses this API to load the
> > > +  opcode into the prefix table.
> > > +
> > > +  @param[in] This               Pointer to an
> > > +                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
> > > +  @param[in] WriteStatusPrefix  Prefix opcode for the write status
> > > command.
> > > +
> > > +  @retval EFI_SUCCESS       The prefix table was updated
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT8                                     WriteStatusPrefix
> > > +  );
> > > +
> > > +/**
> > > +  Set the BIOS base address.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS base address works with the protect range registers to
> protect
> > > +  portions of the SPI NOR flash from erase and write operat ions. The
> BIOS
> > > +  calls this API prior to passing control to the OS loader.
> > > +
> > > +  @param[in] This             Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                              structure.
> > > +  @param[in] BiosBaseAddress  The BIOS base address.
> > > +
> > > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater
> > than
> > > +                                 This->Maxi.mumOffset
> > > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS)
> > > (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT32 BiosBaseAddress
> > > +  );
> > > +
> > > +/**
> > > +  Clear the SPI protect range registers.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > > +  range registers.
> > > +
> > > +  @param[in] This  Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI
> > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT)
> > > (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > > +  );
> > > +
> > > +/**
> > > +  Determine if the SPI range is protected.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > > +
> > > +  @param[in] This            Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                             structure.
> > > +  @param[in] BiosAddress     Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval TRUE   The range is protected
> > > +  @retval FALSE  The range is not protected
> > > +
> > > +**/
> > > +typedef
> > > +BOOLEAN
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT32                                    BiosAddress,
> > > +  IN UINT32                                    BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Set the next protect range register.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS sets the protect range register to prevent write and erase
> > > +  operations to a portion of the SPI NOR flash device.
> > > +
> > > +  @param[in] This             Pointer to an
> > > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +                              structure.
> > > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval EFI_SUCCESS            The register was successfully updated
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> > >BiosBaseAddress,
> > > or
> > > +                                 BlocksToProtect * 4 KiB
> > > +                                   > This->MaximumRangeBytes, or
> > > +                                 BiosAddress - This->BiosBaseAddress
> > > +                                   + (BlocksToProtect * 4 KiB)
> > > +                                     > This->MaximumRangeBytes
> > > +  @retval EFI_OUT_OF_RESOURCES  No protect range register available
> > > +  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the
> > > BIOS base
> > > +                                address is not set
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI
> > > *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> > > +  IN UINT32                                    BiosAddress,
> > > +  IN UINT32                                    BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Lock the SPI controller configuration.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine locks the SPI controller's configuration so that the software
> > > +  is no longer able to update:
> > > +  * Prefix table
> > > +  * Opcode menu
> > > +  * Opcode type table
> > > +  * BIOS base address
> > > +  * Protect range registers
> > > +
> > > +  @param[in] This  Pointer to an
> > EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER)
> > (
> > > +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> > > +  );
> > > +
> > > +///
> > > +/// Support the extra features of the legacy SPI flash controller.
> > > +///
> > > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
> > > +  ///
> > > +  /// Maximum offset from the BIOS base address that is able to be
> > > protected.
> > > +  ///
> > > +  UINT32                                                 MaximumOffset;
> > > +
> > > +  ///
> > > +  /// Maximum number of bytes that can be protected by one range
> > register.
> > > +  ///
> > > +  UINT32                                                 MaximumRangeBytes;
> > > +
> > > +  ///
> > > +  /// The number of registers available for protecting the BIOS.
> > > +  ///
> > > +  UINT32                                                 RangeRegisterCount;
> > > +
> > > +  ///
> > > +  /// Set the erase block opcode.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE
> > > EraseBlockOpcode;
> > > +
> > > +  ///
> > > +  /// Set the write status prefix opcode.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX
> > > WriteStatusPrefix;
> > > +
> > > +  ///
> > > +  /// Set the BIOS base address.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS
> > > BiosBaseAddress;
> > > +
> > > +  ///
> > > +  /// Clear the SPI protect range registers.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT
> > > ClearSpiProtect;
> > > +
> > > +  ///
> > > +  /// Determine if the SPI range is protected.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED
> > > IsRangeProtected;
> > > +
> > > +  ///
> > > +  /// Set the next protect range register.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE
> > > ProtectNextRange;
> > > +
> > > +  ///
> > > +  /// Lock the SPI controller configuration.
> > > +  ///
> > > +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER
> > > LockController;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
> > > +
> > > +#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h
> > > b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > > new file mode 100644
> > > index 000000000000..faa5f5724af7
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
> > > @@ -0,0 +1,201 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI Flash Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiNorFlash.h>
> > > +
> > > +///
> > > +/// Global ID for the Legacy SPI Flash Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
> > > +  { 0xf01bed57, 0x04bc, 0x4f3f,             \
> > > +    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > > +
> > > +typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > EFI_LEGACY_SPI_FLASH_PROTOCOL;
> > > +
> > > +/**
> > > +  Set the BIOS base address.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS base address works with the protect range registers to
> protect
> > > +  portions of the SPI NOR flash from erase and write operat ions.
> > > +  The BIOS calls this API prior to passing control to the OS loader.
> > > +
> > > +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > data
> > > +                              structure.
> > > +  @param[in] BiosBaseAddress  The BIOS base address.
> > > +
> > > +  @retval EFI_SUCCESS            The BIOS base address was properly set
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This-
> > > >MaximumOffset
> > > +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> > or
> > > not a
> > > +                                 legacy SPI host controller
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                               BiosBaseAddress
> > > +  );
> > > +
> > > +/**
> > > +  Clear the SPI protect range registers.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to set an initial condition on the SPI protect
> > > +  range registers.
> > > +
> > > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS       The registers were successfully cleared
> > > +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> > > +  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > > +  );
> > > +
> > > +/**
> > > +  Determine if the SPI range is protected.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS uses this routine to verify a range in the SPI is protected.
> > > +
> > > +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > data
> > > +                              structure.
> > > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval TRUE   The range is protected
> > > +  @retval FALSE  The range is not protected
> > > +
> > > +**/
> > > +typedef
> > > +BOOLEAN
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                               BiosAddress,
> > > +  IN UINT32                               BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Set the next protect range register.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  The BIOS sets the protect range register to prevent write and erase
> > > +  operations to a portion of the SPI NOR flash device.
> > > +
> > > +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > data
> > > +                              structure.
> > > +  @param[in] BiosAddress      Address within a 4 KiB block to start
> > protecting.
> > > +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> > > +
> > > +  @retval EFI_SUCCESS            The register was successfully updated
> > > +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> > > +  @retval EFI_INVALID_PARAMETER  BiosAddress < This-
> > >BiosBaseAddress,
> > > or
> > > +  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
> > > +                                   > This->MaximumRangeBytes, or
> > > +                                 BiosAddress - This->BiosBaseAddress
> > > +                                   + (BlocksToProtect * 4 KiB)
> > > +                                     > This->MaximumRangeBytes
> > > +  @retval EFI_OUT_OF_RESOURCES   No protect range register available
> > > +  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the
> > > BIOS
> > > +                                 base address is not set Not a legacy SPI host
> > > +                                 controller
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE)
> (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                               BiosAddress,
> > > +  IN UINT32                               BlocksToProtect
> > > +  );
> > > +
> > > +/**
> > > +  Lock the SPI controller configuration.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine locks the SPI controller's configuration so that the software
> is
> > > +  no longer able to update:
> > > +  * Prefix table
> > > +  * Opcode menu
> > > +  * Opcode type table
> > > +  * BIOS base address
> > > +  * Protect range registers
> > > +
> > > +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> > > structure.
> > > +
> > > +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> > > +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> > > +  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
> > > +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the
> > > EFI_SPI_NOR_FLASH_PROTOCOL
> > > +/// with APls to support the legacy SPI flash controller.
> > > +///
> > > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
> > > +  ///
> > > +  /// This protocol manipulates the SPI NOR flash parts using a common
> set
> > > of
> > > +  /// commands.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
> > > +
> > > +  //
> > > +  // Legacy flash (SPI host) controller support
> > > +  //
> > > +
> > > +  ///
> > > +  /// Set the BIOS base address.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS
> > > BiosBaseAddress;
> > > +
> > > +  ///
> > > +  /// Clear the SPI protect range registers.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT
> > > ClearSpiProtect;
> > > +
> > > +  ///
> > > +  /// Determine if the SPI range is protected.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED
> > > IsRangeProtected;
> > > +
> > > +  ///
> > > +  /// Set the next protect range register.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE
> > > ProtectNextRange;
> > > +
> > > +  ///
> > > +  /// Lock the SPI controller configuration.
> > > +  ///
> > > +  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER
> > LockController;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
> > > +
> > > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > > b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > > new file mode 100644
> > > index 000000000000..6d8d557cefff
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI SMM Controler Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > > +#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > > +
> > > +#include <Protocol/LegacySpiController.h>
> > > +
> > > +///
> > > +/// Global ID for the Legacy SPI SMM Controller Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > > +  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> > > +    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > > +
> > > +typedef
> > > +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> > > +EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
> > > +
> > > +#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > > b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > > new file mode 100644
> > > index 000000000000..a604a22f901f
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the Legacy SPI SMM Flash Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > > +#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> > > +
> > > +#include <Protocol/LegacySpiFlash.h>
> > > +
> > > +///
> > > +/// Global ID for the Legacy SPI SMM Flash Protocol
> > > +///
> > > +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> > > +  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
> > > +    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > > +
> > > +typedef
> > > +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> > > +EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
> > > +
> > > +#endif // __SPI_SMM_FLASH_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h
> > > b/MdePkg/Include/Protocol/SpiConfiguration.h
> > > new file mode 100644
> > > index 000000000000..3a602f67d7a6
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiConfiguration.h
> > > @@ -0,0 +1,293 @@
> > > +/** @file
> > > +  This file defines the SPI Configuration Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> > > +#define __SPI_CONFIGURATION_PROTOCOL_H__
> > > +
> > > +///
> > > +/// Global ID for the SPI Configuration Protocol
> > > +///
> > > +#define EFI_SPI_CONFIGURATION_GUID  \
> > > +  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
> > > +    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > > +
> > > +///
> > > +/// Macros to easily specify frequencies in hertz, kilohertz and
> megahertz.
> > > +///
> > > +#define Hz(Frequency)   (Frequency)
> > > +#define KHz(Frequency)  (1000 * Hz (Frequency))
> > > +#define MHz(Frequency)  (1000 * KHz (Frequency))
> > > +
> > > +typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
> > > +
> > > +/**
> > > +  Manipulate the chip select for a SPI device.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  Update the value of the chip select line for a SPI peripheral.
> > > +  The SPI bus layer calls this routine either in the board layer or in the SPI
> > > +  controller to manipulate the chip select pin at the start and end of a SPI
> > > +  transaction.
> > > +
> > > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > > structure
> > > +                            describing the SPI peripheral whose chip select pin
> > > +                            is to be manipulated. The routine may access the
> > > +                            ChipSelectParameter field to gain sufficient
> > > +                            context to complete the operation.
> > > +  @param[in] PinValue       The value to be applied to the chip select line
> of
> > > +                            the SPI peripheral.
> > > +
> > > +  @retval EFI_SUCCESS            The chip select was set successfully
> > > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > > +                                 initialized
> > > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral-
> > > >ChipSelectParameter value
> > > +                                 is invalid
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_CHIP_SELECT) (
> > > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > > +  IN BOOLEAN                   PinValue
> > > +  );
> > > +
> > > +/**
> > > +  Set up the clock generator to produce the correct clock frequency,
> phase
> > > and
> > > +  polarity for a SPI chip.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine updates the clock generator to generate the correct
> > > frequency
> > > +  and polarity for the SPI clock.
> > > +
> > > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> > structure
> > > from
> > > +                            which the routine can access the ClockParameter,
> > > +                            ClockPhase and ClockPolarity fields. The routine
> > > +                            also has access to the names for the SPI bus and
> > > +                            chip which can be used during debugging.
> > > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> > > clock
> > > +                            generator will choose a supported clock frequency
> > > +                            which is less then or equal to this value.
> > > +                            Specify zero to turn the clock generator off.
> > > +                            The actual clock frequency supported by the clock
> > > +                            generator will be returned.
> > > +
> > > +  @retval EFI_SUCCESS      The clock was set up successfully
> > > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> > the
> > > +                           frequency requested by CLockHz
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_CLOCK) (
> > > +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> > > +  IN UINT32                    *ClockHz
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_SPI_PART data structure provides a description of a SPI part
> > > which
> > > +/// is independent of the use on the board. This data is available directly
> > > +/// from the part's datasheet and may be provided by the vendor.
> > > +///
> > > +typedef struct _EFI_SPI_PART {
> > > +  ///
> > > +  /// A Unicode string specifying the SPI chip vendor.
> > > +  ///
> > > +  CONST CHAR16 *Vendor;
> > > +
> > > +  ///
> > > +  /// A Unicode string specifying the SPI chip part number.
> > > +  ///
> > > +  CONST CHAR16 *PartNumber;
> > > +
> > > +  ///
> > > +  /// The minimum SPI bus clock frequency used to access this chip. This
> > > value
> > > +  /// may be specified in the chip's datasheet. If not, use the value of
> zero.
> > > +  ///
> > > +  UINT32       MinClockHz;
> > > +
> > > +  ///
> > > +  /// The maximum SPI bus clock frequency used to access this chip. This
> > > value
> > > +  /// is found in the chip's datasheet.
> > > +  ///
> > > +  UINT32       MaxClockHz;
> > > +
> > > +  ///
> > > +  /// Specify the polarity of the chip select pin. This value can be found in
> > > +  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip
> > > select
> > > +  ///and FALSE when a zero asserts the chip select.
> > > +  ///
> > > +  BOOLEAN      ChipSelectPolarity;
> > > +} EFI_SPI_PART;
> > > +
> > > +///
> > > +/// The EFI_SPI_BUS data structure provides the connection details
> > > between the
> > > +/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which
> > controls
> > > that
> > > +/// SPI bus. This data structure also describes the details of how the
> clock
> > is
> > > +/// generated for that SPI bus. Finally this data structure provides the list
> > > +/// of physical SPI devices which are attached to the SPI bus.
> > > +///
> > > +typedef struct _EFI_SPI_BUS {
> > > +  ///
> > > +  /// A Unicode string describing the SPI bus
> > > +  ///
> > > +  CONST CHAR16                   *FriendlyName;
> > > +
> > > +  ///
> > > +  /// Address of the first EFI_SPI_PERIPHERAL data structure connected
> to
> > > this
> > > +  /// bus. Specify NULL if there are no SPI peripherals connected to this
> > bus.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
> > > +
> > > +  ///
> > > +  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which
> > > uniquely
> > > +  /// describes the SPI controller.
> > > +  ///
> > > +  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
> > > +
> > > +  ///
> > > +  /// Address of the routine which controls the clock used by the SPI bus
> > for
> > > +  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
> > > +  /// when this value is set to NULL.
> > > +  ///
> > > +  EFI_SPI_CLOCK                  Clock;
> > > +
> > > +  ///
> > > +  /// Address of a data structure containing the additional values which
> > > +  /// describe the necessary control for the clock. When Clock is NULL,
> > > +  /// the declaration for this data structure is provided by the vendor of
> > the
> > > +  /// host's SPI controller driver. When Clock is not NULL, the declaration
> > for
> > > +  /// this data structure is provided by the board layer.
> > > +  ///
> > > +  VOID                           *ClockParameter;
> > > +} EFI_SPI_BUS;
> > > +
> > > +///
> > > +/// The EFI_SPI_PERIPHERAL data structure describes how a specific
> block
> > > of
> > > +/// logic which is connected to the SPI bus. This data structure also
> selects
> > > +/// which upper level driver is used to manipulate this SPI device.
> > > +/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
> > > +/// peripheral driver.
> > > +///
> > > +struct _EFI_SPI_PERIPHERAL {
> > > +  ///
> > > +  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify
> > NULL
> > > if
> > > +  /// the current data structure is the last one on the SPI bus.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
> > > +
> > > +  ///
> > > +  /// A unicode string describing the function of the SPI part.
> > > +  ///
> > > +  CONST CHAR16             *FriendlyName;
> > > +
> > > +  ///
> > > +  /// Address of a GUID provided by the vendor of the SPI peripheral
> > driver.
> > > +  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus
> driver
> > > uses
> > > +  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and
> to
> > > +  /// provide the connection points for the SPI peripheral drivers.
> > > +  /// This reduces the comparison logic in the SPI peripheral driver's
> > > +  /// Supported routine.
> > > +  ///
> > > +  CONST GUID               *SpiPeripheralDriverGuid;
> > > +
> > > +  ///
> > > +  /// The address of an EFI_SPI_PART data structure which describes this
> > > chip.
> > > +  ///
> > > +  CONST EFI_SPI_PART       *SpiPart;
> > > +
> > > +  ///
> > > +  /// The maximum clock frequency is specified in the EFI_SPI_P ART.
> > When
> > > this
> > > +  /// this value is non-zero and less than the value in the EFI_SPI_PART
> > then
> > > +  /// this value is used for the maximum clock frequency for the SPI part.
> > > +  ///
> > > +  UINT32                   MaxClockHz;
> > > +
> > > +  ///
> > > +  /// Specify the idle value of the clock as found in the datasheet.
> > > +  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
> > > +  /// clock's idle value is high.
> > > +  ///
> > > +  BOOLEAN                  ClockPolarity;
> > > +
> > > +  ///
> > > +  /// Specify the clock delay after chip select. Specify zero (0) to delay an
> > > +  /// entire clock cycle or one (1) to delay only half a clock cycle.
> > > +  ///
> > > +  BOOLEAN                  ClockPhase;
> > > +
> > > +  ///
> > > +  /// SPI peripheral attributes, select zero or more of:
> > > +  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI
> > > peripheral is wired to
> > > +  ///   support a 2-bit data bus
> > > +  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI
> > > peripheral is wired to
> > > +  ///   support a 4-bit data bus
> > > +  ///
> > > +  UINT32                   Attributes;
> > > +
> > > +  ///
> > > +  /// Address of a vendor specific data structure containing additional
> > board
> > > +  /// configuration details related to the SPI chip. The SPI peripheral layer
> > > +  /// uses this data structure when configuring the chip.
> > > +  ///
> > > +  CONST VOID               *ConfigurationData;
> > > +
> > > +  ///
> > > +  /// The address of an EFI_SPI_BUS data structure which describes the
> SPI
> > > bus
> > > +  /// to which this chip is connected.
> > > +  ///
> > > +  CONST EFI_SPI_BUS        *SpiBus;
> > > +
> > > +  ///
> > > +  /// Address of the routine which controls the chip select pin for this SPI
> > > +  /// peripheral. Call the SPI host controller's chip select routine when
> this
> > > +  /// value is set to NULL.
> > > +  ///
> > > +  EFI_SPI_CHIP_SELECT      ChipSelect;
> > > +
> > > +  ///
> > > +  /// Address of a data structure containing the additional values which
> > > +  /// describe the necessary control for the chip select. When ChipSelect
> is
> > > +  /// NULL, the declaration for this data structure is provided by the
> > vendor
> > > +  /// of the host's SPI controller driver. The vendor's documentation
> > > specifies
> > > +  /// the necessary values to use for the chip select pin selection and
> > > +  /// control. When Chipselect is not NULL, the declaration for this data
> > > +  /// structure is provided by the board layer.
> > > +  ///
> > > +  VOID                     *ChipSelectParameter;
> > > +};
> > > +
> > > +///
> > > +/// Describe the details of the board's SPI busses to the SPI driver stack.
> > > +/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to
> > > expose the data
> > > +/// tables which describe the board's SPI busses, The SPI bus layer uses
> > > these
> > > +/// tables to configure the clock, chip select and manage the SPI
> > > transactions
> > > +/// on the SPI controllers.
> > > +///
> > > +typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
> > > +  ///
> > > +  /// The number of SPI busses on the board.
> > > +  ///
> > > +  UINT32                          BusCount;
> > > +
> > > +  ///
> > > +  /// The address of an array of EFI_SPI_BUS data structure addresses.
> > > +  ///
> > > +  CONST EFI_SPI_BUS *CONST *CONST Buslist;
> > > +} EFI_SPI_CONFIGURATION_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
> > > +
> > > +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiHc.h
> > > b/MdePkg/Include/Protocol/SpiHc.h
> > > new file mode 100644
> > > index 000000000000..13ad5f45225c
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiHc.h
> > > @@ -0,0 +1,194 @@
> > > +/** @file
> > > +  This file defines the SPI Host Controller Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_HC_PROTOCOL_H__
> > > +#define __SPI_HC_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiConfiguration.h>
> > > +#include <Protocol/SpiIo.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI Host Controller Protocol
> > > +///
> > > +#define EFI_SPI_HOST_GUID  \
> > > +  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
> > > +    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > > +
> > > +///
> > > +/// EDK2-style name
> > > +///
> > > +#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
> > > +
> > > +typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
> > > +
> > > +/**
> > > +  Assert or deassert the SPI chip select.
> > > +
> > > +  This routine is called at TPL_NOTIFY.
> > > +  Update the value of the chip select line for a SPI peripheral. The SPI bus
> > > +  layer calls this routine either in the board layer or in the SPI controller
> > > +  to manipulate the chip select pin at the start and end of a SPI
> transaction.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > > +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> > > structure
> > > +                            describing the SPI peripheral whose chip select pin
> > > +                            is to be manipulated. The routine may access the
> > > +                            ChipSelectParameter field to gain sufficient
> > > +                            context to complete the operati on.
> > > +  @param[in] PinValue       The value to be applied to the chip select line
> of
> > > +                            the SPI peripheral.
> > > +
> > > +  @retval EFI_SUCCESS            The chip select was set as requested
> > > +  @retval EFI_NOT_READY          Support for the chip select is not properly
> > > +                                 initialized
> > > +  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its
> contents
> > > are
> > > +                                 invalid
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
> > > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > > +  IN BOOLEAN                    PinValue
> > > +  );
> > > +
> > > +/**
> > > +  Set up the clock generator to produce the correct clock frequency,
> phase
> > > and
> > > +  polarity for a SPI chip.
> > > +
> > > +  This routine is called at TPL_NOTIFY.
> > > +  This routine updates the clock generator to generate the correct
> > > frequency
> > > +  and polarity for the SPI clock.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > > +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data
> > structure
> > > from
> > > +                            which the routine can access the ClockParameter,
> > > +                            ClockPhase and ClockPolarity fields. The routine
> > > +                            also has access to the names for the SPI bus and
> > > +                            chip which can be used during debugging.
> > > +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> > SPI
> > > +                            host controller will choose a supported clock
> > > +                            frequency which is less then or equal to this
> > > +                            value. Specify zero to turn the clock generator
> > > +                            off. The actual clock frequency supported by the
> > > +                            SPI host controller will be returned.
> > > +
> > > +  @retval EFI_SUCCESS      The clock was set up successfully
> > > +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support
> > the
> > > +                           frequency requested by ClockHz
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
> > > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> > > +  IN UINT32                      *ClockHz
> > > +  );
> > > +
> > > +/**
> > > +  Perform the SPI transaction on the SPI peripheral using the SPI host
> > > +  controller.
> > > +
> > > +  This routine is called at TPL_NOTIFY.
> > > +  This routine synchronously returns EFI_SUCCESS indicating that the
> > > +  asynchronous SPI transaction was started. The routine then waits for
> > > +  completion of the SPI transaction prior to returning the final transaction
> > > +  status.
> > > +
> > > +  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
> > > +  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION
> > > containing
> > > +                             the description of the SPI transaction to perform.
> > > +
> > > +  @retval EFI_SUCCESS          The transaction completed successfully
> > > +  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value
> is
> > > invalid,
> > > +                               or the BusTransaction->ReadinBytes value is
> > > +                               invalid
> > > +  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type
> is
> > > +                               unsupported
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> > > +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> > > +  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
> > > +  );
> > > +
> > > +///
> > > +/// Support a SPI data transaction between the SPI controller and a SPI
> > chip.
> > > +///
> > > +struct _EFI_SPI_HC_PROTOCOL {
> > > +  ///
> > > +  /// Host control attributes, may have zero or more of the following set:
> > > +  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> > > +  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> > > +  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> > > +  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > > +  ///   - The SPI host controller requires the transmit frame to be in most
> > > +  ///     significant bits instead of least significant bits.The host driver
> > > +  ///     will adjust the frames if necessary.
> > > +  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
> > > +  ///   - The SPI host controller places the receive frame to be in most
> > > +  ///     significant bits instead of least significant bits.The host driver
> > > +  ///     will adjust the frames to be in the least significant bits if
> > > +  ///     necessary.
> > > +  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
> > > +  ///   - The SPI controller supports a 2 - bit data bus
> > > +  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> > > +  ///   - The SPI controller supports a 4 - bit data bus
> > > +  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> > > +  ///   - Transfer size includes the opcode byte
> > > +  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> > > +  ///   - Transfer size includes the 3 address bytes
> > > +  /// The SPI host controller must support full - duplex (receive while
> > > +  /// sending) operation.The SPI host controller must support a 1 - bit
> bus
> > > +  /// width.
> > > +  ///
> > > +  UINT32                          Attributes;
> > > +
> > > +  ///
> > > +  /// Mask of frame sizes which the SPI host controller supports. Frame
> > size
> > > of
> > > +  /// N-bits is supported when bit N-1 is set. The host controller must
> > > support
> > > +  /// a frame size of 8-bits.
> > > +  ///
> > > +  UINT32                          FrameSizeSupportMask;
> > > +
> > > +  ///
> > > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > > +  ///
> > > +  UINT32                          MaximumTransferBytes;
> > > +
> > > +  ///
> > > +  /// Assert or deassert the SPI chip select.
> > > +  ///
> > > +  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
> > > +
> > > +  ///
> > > +  /// Set up the clock generator to produce the correct clock frequency,
> > > phase
> > > +  /// and polarity for a SPI chip.
> > > +  ///
> > > +  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
> > > +
> > > +  ///
> > > +  /// Perform the SPI transaction on the SPI peripheral using the SPI host
> > > +  /// controller.
> > > +  ///
> > > +  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiSpiHcProtocolGuid;
> > > +
> > > +#endif // __SPI_HC_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiIo.h
> > > b/MdePkg/Include/Protocol/SpiIo.h
> > > new file mode 100644
> > > index 000000000000..e481779acc58
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiIo.h
> > > @@ -0,0 +1,292 @@
> > > +/** @file
> > > +  This file defines the SPI I/O Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_IO_PROTOCOL_H__
> > > +#define __SPI_IO_PROTOCOL_H__
> > > +
> > > +#include <Protocol/LegacySpiController.h>
> > > +#include <Protocol/SpiConfiguration.h>
> > > +
> > > +typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> > > +
> > > +///
> > > +/// Note: The UEFI PI 1.6 specification does not specify values for the
> > > +///       members below. The order matches the specification.
> > > +///
> > > +typedef enum {
> > > +  ///
> > > +  /// Data flowing in both direction between the host and
> > > +  /// SPI peripheral.ReadBytes must equal WriteBytes and both
> > ReadBuffer
> > > and
> > > +  /// WriteBuffer must be provided.
> > > +  ///
> > > +  SPI_TRANSACTION_FULL_DUPLEX,
> > > +
> > > +  ///
> > > +  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> > > +  /// zero.WriteBytes must be non - zero and WriteBuffer must be
> > provided.
> > > +  ///
> > > +  SPI_TRANSACTION_WRITE_ONLY,
> > > +
> > > +  ///
> > > +  /// Data flowing from the SPI peripheral to the host.WriteBytes must
> be
> > > +  /// zero.ReadBytes must be non - zero and ReadBuffer must be
> > provided.
> > > +  ///
> > > +  SPI_TRANSACTION_READ_ONLY,
> > > +
> > > +  ///
> > > +  /// Data first flowing from the host to the SPI peripheral and then data
> > > +  /// flows from the SPI peripheral to the host.These types of operations
> > get
> > > +  /// used for SPI flash devices when control data (opcode, address)
> must
> > be
> > > +  /// passed to the SPI peripheral to specify the data to be read.
> > > +  ///
> > > +  SPI_TRANSACTION_WRITE_THEN_READ
> > > +} EFI_SPI_TRANSACTION_TYPE;
> > > +
> > > +/**
> > > +  Initiate a SPI transaction between the host and a SPI peripheral.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine works with the SPI bus layer to pass the SPI transaction to
> > the
> > > +  SPI controller for execution on the SPI bus. There are four types of
> > > +  supported transactions supported by this routine:
> > > +  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> > > +  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes =
> 0
> > > +  * Read Only: ReadBuffer to receive data from SPI peripheral,
> WriteBytes
> > =
> > > 0
> > > +  * Write Then Read: WriteBuffer contains control data to write to SPI
> > > +                     peripheral before data is placed into the ReadBuffer.
> > > +                     Both WriteBytes and ReadBytes must be non-zero.
> > > +
> > > +  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > > +  @param[in]  TransactionType   Type of SPI transaction.
> > > +  @param[in]  DebugTransaction  Set TRUE only when debugging is
> > desired.
> > > +                                Debugging may be turned on for a single SPI
> > > +                                transaction. Only this transaction will display
> > > +                                debugging messages. All other transactions with
> > > +                                this value set to FALSE will not display any
> > > +                                debugging messages.
> > > +  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
> > > +                                the maximum clock frequency supported by the
> > > +                                SPI controller and part. Specify a non-zero
> > > +                                value only when a specific SPI transaction
> > > +                                requires a reduced clock rate.
> > > +  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
> > > +  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
> > > +  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
> > > +                                Specify zero for read-only operations.
> > > +  @param[in]  WriteBuffer       The buffer containing data to be sent from
> > the
> > > +                                host to the SPI chip. Specify NULL for read
> > > +                                only operations.
> > > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > > +                                  frame
> > > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > > +                                  frame
> > > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > > +                                  per frame The transmit frame is in the least
> > > +                                  significant N bits.
> > > +  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
> > > +                                Specify zero for write-only operations.
> > > +  @param[out] ReadBuffer        The buffer to receeive data from the SPI
> > chip
> > > +                                during the transaction. Specify NULL for write
> > > +                                only operations.
> > > +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> > > +                                  frame
> > > +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> > > +                                  frame
> > > +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> > > +                                  per frame The received frame is in the least
> > > +                                  significant N bits.
> > > +
> > > +  @retval EFI_SUCCESS            The SPI transaction completed successfully
> > > +  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
> > > +  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
> > > +  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
> > > +                                 or BusWidth not supported by SPI peripheral or
> > > +                                 SPI host controller,
> > > +                                 or WriteBytes non-zero and WriteBuffer is
> > > +                                 NULL,
> > > +                                 or ReadBytes non-zero and ReadBuffer is NULL,
> > > +                                 or ReadBuffer != WriteBuffer for full-duplex
> > > +                                 type,
> > > +                                 or WriteBuffer was NULL,
> > > +                                 or TPL is too high
> > > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI
> > transaction
> > > +  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the
> > SPI
> > > bus
> > > +                                 layer or the SPI host controller
> > > +  @retval EFI_UNSUPPORTED        The SPI controller was not able to
> > support
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> > > +  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
> > > +  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
> > > +  IN  BOOLEAN                    DebugTransaction,
> > > +  IN  UINT32                     ClockHz OPTIONAL,
> > > +  IN  UINT32                     BusWidth,
> > > +  IN  UINT32                     FrameSize,
> > > +  IN  UINT32                     WriteBytes,
> > > +  IN  UINT8                      *WriteBuffer,
> > > +  IN  UINT32                     ReadBytes,
> > > +  OUT UINT8                      *ReadBuffer
> > > +  );
> > > +
> > > +/**
> > > +  Update the SPI peripheral associated with this SPI 10 instance.
> > > +
> > > +  Support socketed SPI parts by allowing the SPI peripheral driver to
> > replace
> > > +  the SPI peripheral after the connection is made. An example use is
> > > socketed
> > > +  SPI NOR flash parts, where the size and parameters change depending
> > > upon
> > > +  device is in the socket.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
> > > +  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL
> structure.
> > > +
> > > +  @retval EFI_SUCCESS            The SPI peripheral was updated
> successfully
> > > +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
> > > +                                 or the SpiPeripheral->SpiBus is NULL,
> > > +                                 or the SpiP eripheral - >SpiBus pointing at
> > > +                                 wrong bus,
> > > +                                 or the SpiP eripheral - >SpiPart is NULL
> > > +
> > > +**/
> > > +typedef EFI_STATUS
> > > +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> > > +  IN CONST EFI_SPI_IO_PROTOCOL  *This,
> > > +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_SPI_BUS_ TRANSACTION data structure contains the
> > > description of the
> > > +/// SPI transaction to perform on the host controller.
> > > +///
> > > +typedef struct _EFI_SPI_BUS_TRANSACTION {
> > > +  ///
> > > +  /// Pointer to the SPI peripheral being manipulated.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Type of transaction specified by one of the
> > > EFI_SPI_TRANSACTION_TYPE
> > > +  /// values.
> > > +  ///
> > > +  EFI_SPI_TRANSACTION_TYPE TransactionType;
> > > +
> > > +  ///
> > > +  /// TRUE if the transaction is being debugged. Debugging may be
> turned
> > > on for
> > > +  /// a single SPI transaction. Only this transaction will display debugging
> > > +  /// messages. All other transactions with this value set to FALSE will not
> > > +  /// display any debugging messages.
> > > +  ///
> > > +  BOOLEAN                  DebugTransaction;
> > > +
> > > +  ///
> > > +  /// SPI bus width in bits: 1, 2, 4
> > > +  ///
> > > +  UINT32                   BusWidth;
> > > +
> > > +  ///
> > > +  /// Frame size in bits, range: 1 - 32
> > > +  ///
> > > +  UINT32                   FrameSize;
> > > +
> > > +  ///
> > > +  /// Length of the write buffer in bytes
> > > +  ///
> > > +  UINT32                   WriteBytes;
> > > +
> > > +  ///
> > > +  /// Buffer containing data to send to the SPI peripheral
> > > +  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > > +  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > > +  ///
> > > +  UINT8                    *WriteBuffer;
> > > +
> > > +  ///
> > > +  /// Length of the read buffer in bytes
> > > +  ///
> > > +  UINT32                   ReadBytes;
> > > +
> > > +  ///
> > > +  /// Buffer to receive the data from the SPI peripheral
> > > +  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> > > +  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> > > +  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> > > +  ///
> > > +  UINT8                    *ReadBuffer;
> > > +} EFI_SPI_BUS_TRANSACTION;
> > > +
> > > +///
> > > +/// Support managed SPI data transactions between the SPI controller
> > and a
> > > SPI
> > > +/// chip.
> > > +///
> > > +struct _EFI_SPI_IO_PROTOCOL {
> > > +  ///
> > > +  /// Address of an EFI_SPI_PERIPHERAL data structure associated with
> > this
> > > +  /// protocol instance.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Address of the original EFI_SPI_PERIPHERAL data structure
> associated
> > > with
> > > +  /// this protocol instance.
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of
> N-
> > > bits
> > > +  /// is supported when bit N-1 is set. The host controller must support a
> > > +  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted
> to
> > > +  /// 8-bit frame sizes by the SPI bus layer if the frame size is not
> > supported
> > > +  /// by the SPI host controller.
> > > +  ///
> > > +  UINT32                                    FrameSizeSupportMask;
> > > +
> > > +  ///
> > > +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> > > +  ///
> > > +  UINT32                                    MaximumTransferBytes;
> > > +
> > > +  ///
> > > +  /// Transaction attributes: One or more from:
> > > +  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> > > +  ///   - The SPI host and peripheral supports a 2-bit data bus
> > > +  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> > > +  ///   - The SPI host and peripheral supports a 4-bit data bus
> > > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> > > +  ///   - Transfer size includes the opcode byte
> > > +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> > > +  ///   - Transfer size includes the 3 address bytes
> > > +  ///
> > > +  UINT32                                    Attributes;
> > > +
> > > +  ///
> > > +  /// Pointer to legacy SPI controller protocol
> > > +  ///
> > > +  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> *LegacySpiProtocol;
> > > +
> > > +  ///
> > > +  /// Initiate a SPI transaction between the host and a SPI peripheral.
> > > +  ///
> > > +  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
> > > +
> > > +  ///
> > > +  /// Update the SPI peripheral associated with this SPI 10 instance.
> > > +  ///
> > > +  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL
> UpdateSpiPeripheral;
> > > +};
> > > +
> > > +#endif // __SPI_IO_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h
> > > b/MdePkg/Include/Protocol/SpiNorFlash.h
> > > new file mode 100644
> > > index 000000000000..93d2adaa860e
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiNorFlash.h
> > > @@ -0,0 +1,289 @@
> > > +/** @file
> > > +  This file defines the SPI NOR Flash Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
> > > +#define __SPI_NOR_FLASH_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiConfiguration.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI NOR Flash Protocol
> > > +///
> > > +#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
> > > +  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
> > > +    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > > +
> > > +typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL
> > > EFI_SPI_NOR_FLASH_PROTOCOL;
> > > +
> > > +/**
> > > +  Read the 3 byte manufacture and device ID from the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads the 3 byte manufacture and device ID from the flash
> > > part
> > > +  filling the buffer provided.
> > > +
> > > +  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> > > structure.
> > > +  @param[out] Buffer  Pointer to a 3 byte buffer to receive the
> > manufacture
> > > and
> > > +                      device ID.
> > > +
> > > +
> > > +
> > > +  @retval EFI_SUCCESS            The manufacture and device ID was read
> > > +                                 successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL
> > > +  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash
> part.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  OUT UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Read data from the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads data from the SPI part in the buffer provided.
> > > +
> > > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                             structure.
> > > +  @param[in]  FlashAddress   Address in the flash to start reading
> > > +  @param[in]  LengthInBytes  Read length in bytes
> > > +  @param[out] Buffer         Address of a buffer to receive the data
> > > +
> > > +  @retval EFI_SUCCESS            The data was read successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > > +                                 FlashAddress >= This->FlashSize, or
> > > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN  UINT32                            FlashAddress,
> > > +  IN  UINT32                            LengthInBytes,
> > > +  OUT UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Low frequency read data from the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads data from the SPI part in the buffer provided.
> > > +
> > > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                             structure.
> > > +  @param[in]  FlashAddress   Address in the flash to start reading
> > > +  @param[in]  LengthInBytes  Read length in bytes
> > > +  @param[out] Buffer         Address of a buffer to receive the data
> > > +
> > > +  @retval EFI_SUCCESS            The data was read successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > > +                                 FlashAddress >= This->FlashSize, or
> > > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN  UINT32                            FlashAddress,
> > > +  IN  UINT32                            LengthInBytes,
> > > +  OUT UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Read the flash status register.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine reads the flash part status register.
> > > +
> > > +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                             structure.
> > > +  @param[in]  LengthInBytes  Number of status bytes to read.
> > > +  @param[out] FlashStatus    Pointer to a buffer to receive the flash
> status.
> > > +
> > > +  @retval EFI_SUCCESS  The status register was read successfully.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
> > > +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN  UINT32                            LengthInBytes,
> > > +  OUT UINT8                             *FlashStatus
> > > +  );
> > > +
> > > +/**
> > > +  Write the flash status register.
> > > +
> > > +  This routine must be called at or below TPL_N OTIFY.
> > > +  This routine writes the flash part status register.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                            structure.
> > > +  @param[in] LengthInBytes  Number of status bytes to write.
> > > +  @param[in] FlashStatus    Pointer to a buffer containing the new status.
> > > +
> > > +  @retval EFI_SUCCESS           The status write was successful.
> > > +  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
> > > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                            LengthInBytes,
> > > +  IN UINT8                             *FlashStatus
> > > +  );
> > > +
> > > +/**
> > > +  Write data to the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine breaks up the write operation as necessary to write the
> data
> > > to
> > > +  the SPI part.
> > > +
> > > +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> > data
> > > +                            structure.
> > > +  @param[in] FlashAddress   Address in the flash to start writing
> > > +  @param[in] LengthInBytes  Write length in bytes
> > > +  @param[in] Buffer         Address of a buffer containing the data
> > > +
> > > +  @retval EFI_SUCCESS            The data was written successfully.
> > > +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> > > +                                 FlashAddress >= This->FlashSize, or
> > > +                                 LengthInBytes > This->FlashSize - FlashAddress
> > > +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy
> buffer.
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
> > > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                            FlashAddress,
> > > +  IN UINT32                            LengthInBytes,
> > > +  IN UINT8                             *Buffer
> > > +  );
> > > +
> > > +/**
> > > +  Efficiently erases one or more 4KiB regions in the SPI flash.
> > > +
> > > +  This routine must be called at or below TPL_NOTIFY.
> > > +  This routine uses a combination of 4 KiB and larger blocks to erase the
> > > +  specified area.
> > > +
> > > +  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL
> data
> > > +                           structure.
> > > +  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
> > > +  @param[in] BlockCount    Number of 4 KiB blocks to erase
> > > +
> > > +  @retval EFI_SUCCESS            The erase was completed successfully.
> > > +  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
> > > +                                 BlockCount * 4 KiB
> > > +                                   > This->FlashSize - FlashAddress
> > > +
> > > +**/
> > > +typedef
> > > +EFI_STATUS
> > > +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
> > > +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> > > +  IN UINT32                            FlashAddress,
> > > +  IN UINT32                            BlockCount
> > > +  );
> > > +
> > > +///
> > > +/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral
> layer.
> > > +/// This protocol manipulates the SPI NOR flash parts using a common
> set
> > of
> > > +/// commands. The board layer provides the interconnection and
> > > configuration
> > > +/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
> > > +/// configuration data to expose a generic interface which provides the
> > > +/// following APls:
> > > +/// * Read manufacture and device ID
> > > +/// * Read data
> > > +/// * Read data using low frequency
> > > +/// * Read status
> > > +/// * Write data
> > > +/// * Erase 4 KiB blocks
> > > +/// * Erase 32 or 64 KiB blocks
> > > +/// * Write status
> > > +/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set
> > the
> > > security
> > > +/// features on the legacy SPI flash controller.
> > > +///
> > > +struct _EFI_SPI_NOR_FLASH_PROTOCOL {
> > > +  ///
> > > +  /// Pointer to an EFI_SPI_PERIPHERAL data structure
> > > +  ///
> > > +  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
> > > +
> > > +  ///
> > > +  /// Flash size in bytes
> > > +  ///
> > > +  UINT32                                  FlashSize;
> > > +
> > > +  ///
> > > +  /// Manufacture and Device ID
> > > +  ///
> > > +  UINT8                                   Deviceid[3];
> > > +
> > > +  ///
> > > +  /// Erase block size in bytes
> > > +  ///
> > > +  UINT32                                  EraseBlockBytes;
> > > +
> > > +  ///
> > > +  /// Read the 3 byte manufacture and device ID from the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
> > > +
> > > +  ///
> > > +  /// Read data from the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
> > > +
> > > +  ///
> > > +  /// Low frequency read data from the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
> > > +
> > > +  ///
> > > +  /// Read the flash status register.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
> > > +
> > > +  ///
> > > +  /// Write the flash status register.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
> > > +
> > > +  ///
> > > +  /// Write data to the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
> > > +
> > > +  ///
> > > +  /// Efficiently erases one or more 4KiB regions in the SPI flash.
> > > +  ///
> > > +  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
> > > +};
> > > +
> > > +extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
> > > +
> > > +#endif // __SPI_NOR_FLASH_PROTOCOL_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > > b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > > new file mode 100644
> > > index 000000000000..913d4cbb46aa
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the SPI SMM Configuration Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > > +#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> > > +
> > > +#include <Protocol/SpiConfiguration.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI SMM Configuration Protocol
> > > +///
> > > +#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
> > > +  { 0x995c6eca, 0x171b, 0x45fd,                  \
> > > +    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > > +
> > > +typedef
> > > +struct _EFI_SPI_CONFIGURATION_PROTOCOL
> > > +EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
> > > +
> > > +#endif // __SPI_SMM_CONFIGURATION_H__
> > > diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h
> > > b/MdePkg/Include/Protocol/SpiSmmHc.h
> > > new file mode 100644
> > > index 000000000000..91d2312b74b4
> > > --- /dev/null
> > > +++ b/MdePkg/Include/Protocol/SpiSmmHc.h
> > > @@ -0,0 +1,36 @@
> > > +/** @file
> > > +  This file defines the SPI SMM Host Controller Protocol.
> > > +
> > > +  Copyright (c) 2017, 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.
> > > +
> > > +  @par Revision Reference:
> > > +    This Protocol was introduced in UEFI PI Specification 1.6.
> > > +
> > > +**/
> > > +
> > > +#ifndef __SPI_SMM_HC_H__
> > > +#define __SPI_SMM_HC_H__
> > > +
> > > +#include <Protocol/SpiHc.h>
> > > +
> > > +///
> > > +/// Global ID for the SPI SMM Host Controller Protocol
> > > +///
> > > +#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
> > > +  { 0xe9f02217, 0x2093, 0x4470,       \
> > > +    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > > +
> > > +typedef
> > > +struct _EFI_SPI_HC_PROTOCOL
> > > +EFI_SPI_SMM_HC_PROTOCOL;
> > > +
> > > +extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
> > > +
> > > +#endif // __SPI_SMM_HC_H__
> > > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> > > index 1867c54c3bc1..91af6c5c455c 100644
> > > --- a/MdePkg/MdePkg.dec
> > > +++ b/MdePkg/MdePkg.dec
> > > @@ -1246,6 +1246,37 @@ [Protocols]
> > >    gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd,
> > > { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
> > >
> > >    #
> > > +  # Protocols defined in PI 1.6.
> > > +  #
> > > +
> > > +  ## Include/Protocol/LegacySpiController.h
> > > +  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de,
> > > { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> > > +
> > > +  ## Include/Protocol/LegacySpiFlash.h
> > > +  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, {
> > 0x96,
> > > 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> > > +
> > > +  ## Include/Protocol/LegacySpiSmmController.h
> > > +  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0,
> > 0x4c8c,
> > > { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> > > +
> > > +  ## Include/Protocol/LegacySpiSmmFlash.h
> > > +  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0,
> > > { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> > > +
> > > +  ## Include/Protocol/SpiConfiguration.h
> > > +  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, {
> > 0xb3,
> > > 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> > > +
> > > +  ## Include/Protocol/SpiHc.h
> > > +  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3,
> > 0x99,
> > > 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> > > +
> > > +  ## Include/Protocol/SpiNorFlash.h
> > > +  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, {
> 0x85,
> > > 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> > > +
> > > +  ## Include/Protocol/SpiSmmConfiguration.h
> > > +  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b,
> 0x45fd,
> > > { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> > > +
> > > +  ## Include/Protocol/SpiSmmHc.h
> > > +  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, {
> 0x8a,
> > > 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> > > +
> > > +  #
> > >    # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
> > >    #
> > >
> > > --
> > > 2.12.2.windows.2
> > >
> > > _______________________________________________
> > > edk2-devel mailing list
> > > edk2-devel@lists.01.org
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.
Posted by Bi, Dandan 6 years, 6 months ago
Hi Marvin,

I have reviewed the remaining parts.
Here are the comments:
1. There is a typo in LegacySpiFlash.h
    Typo:
    #ifndef __SPI_CONFIGURATION_PROTOCOL_H__
    #define __SPI_CONFIGURATION_PROTOCOL_H__
   The token __SPI_CONFIGURATION_PROTOCOL_H__ in LegacySpiFlash.h in duplicated with the one in SpiConfiguration.h, please update it.

2.  The type EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA in SpiNorFlash.h is not used,  and it's also not defined in Spec, we may remove it.
  (1)typedef
   EFI_STATUS
   (EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
     IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
     IN  UINT32                            FlashAddress,
     IN  UINT32                            LengthInBytes,
     OUT UINT8                             *Buffer
     );
   ///
   /// Low frequency read data from the SPI flash.
   /// 
   EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;

3. You could use patch check tool in BaseTools/Scripts/PatchCheck.py to verify the format of your updates.


Thanks,
Dandan

-----Original Message-----
From: Bi, Dandan 
Sent: Friday, September 15, 2017 4:22 PM
To: Ni, Ruiyu <ruiyu.ni@intel.com>; Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-devel@lists.01.org
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>
Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.

Hi Marvin,

Thank you for your contribution. I am reviewing this patch now. Currently I just take a look at the SMM SPI part and find:

1. There is a typo in LegacySpiSmmController.h
The definition should be EFI_LEGACY_SPI_SMM_CONTROLLER_GUID, not EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID.
Typo:
#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
And it should  be:
#define EFI_LEGACY_SPI_SMM_CONTROLLER_GUID \
{ 0x62331b78, 0xd8d0, 0x4c8c, { 0x8c, 0xcb, 0xd2, 0x7d, \ 0xfe, 0x32, 0xdb, 0x9b }}

2. EFI_SPI_SMM_NOR_FLASH_PROTOCOL definition seems to be missing.

I will review the remaining part. It may take some time. Sorry for the delay in my response

Thanks,
Dandan

-----Original Message-----
From: Ni, Ruiyu 
Sent: Thursday, September 7, 2017 3:13 PM
To: Marvin Häuser <Marvin.Haeuser@outlook.com>; edk2-devel@lists.01.org
Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Bi, Dandan <dandan.bi@intel.com>
Subject: RE: [PATCH v1] MdePkg: Add definitions for the SPI protocols introduced in UEFI PI 1.6.

Marvin,
Thank you for your contribution. We will need some time to review the definitions against PI Spec.
If there is a need to post V2, it might be better to separate the header files in different groups.
For example, LegacySpi group, SPI group, SMM SPI group.

Thanks/Ray

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> Marvin Häuser
> Sent: Wednesday, September 6, 2017 5:21 PM
> To: edk2-devel@lists.01.org
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> Subject: [edk2] [PATCH v1] MdePkg: Add definitions for the SPI protocols
> introduced in UEFI PI 1.6.
> 
> This commit adds header files for the SPI protocols introduced in the
> UEFI PI 1.6 specification, as well as their GUIDs to MdePkg.dec.
> 
> EFI_SPI_TRANSACTION_TYPE assumes an enum with its members ordered
> the
> way they are listed in the specification, as there are no values given
> explicitely.
> EFI_LEGACY_SPI_CONTROLLER_GUID assumes the character 'l' used in the
> specification was meant to be '1'.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Marvin Haeuser <Marvin.Haeuser@outlook.com>
> ---
>  MdePkg/Include/Protocol/LegacySpiController.h    | 265
> ++++++++++++++++++
>  MdePkg/Include/Protocol/LegacySpiFlash.h         | 201 ++++++++++++++
>  MdePkg/Include/Protocol/LegacySpiSmmController.h |  36 +++
>  MdePkg/Include/Protocol/LegacySpiSmmFlash.h      |  36 +++
>  MdePkg/Include/Protocol/SpiConfiguration.h       | 293
> ++++++++++++++++++++
>  MdePkg/Include/Protocol/SpiHc.h                  | 194 +++++++++++++
>  MdePkg/Include/Protocol/SpiIo.h                  | 292 +++++++++++++++++++
>  MdePkg/Include/Protocol/SpiNorFlash.h            | 289
> +++++++++++++++++++
>  MdePkg/Include/Protocol/SpiSmmConfiguration.h    |  36 +++
>  MdePkg/Include/Protocol/SpiSmmHc.h               |  36 +++
>  MdePkg/MdePkg.dec                                |  31 +++
>  11 files changed, 1709 insertions(+)
> 
> diff --git a/MdePkg/Include/Protocol/LegacySpiController.h
> b/MdePkg/Include/Protocol/LegacySpiController.h
> new file mode 100644
> index 000000000000..2d36eaefc0ee
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiController.h
> @@ -0,0 +1,265 @@
> +/** @file
> +  This file defines the Legacy SPI Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> +#define __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> +
> +///
> +/// Note: The UEFI PI 1.6 specification uses the character 'l' in the GUID
> +///       definition. This definition assumes it was supposed to be '1'.
> +///
> +/// Global ID for the Legacy SPI Controller Protocol
> +///
> +#define EFI_LEGACY_SPI_CONTROLLER_GUID  \
> +  { 0x39136fc7, 0x1a11, 0x49de,         \
> +    { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +EFI_LEGACY_SPI_CONTROLLER_PROTOCOL;
> +
> +/**
> +  Set the erase block opcode.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The menu table contains SPI transaction opcodes which are accessible
> after
> +  the legacy SPI flash controller's configuration is locked. The board layer
> +  specifies the erase block size for the SPI NOR flash part. The SPI NOR flash
> +  peripheral driver selects the erase block opcode which matches the erase
> +  block size and uses this API to load the opcode into the opcode menu table.
> +
> +  @param[in] This              Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                               structure.
> +  @param[in] EraseBlockOpcode  Erase block opcode to be placed into the
> opcode
> +                               menu table.
> +
> +  @retval EFI_SUCCESS       The opcode menu table was updated
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT8                                     EraseBlockOpcode
> +  );
> +
> +/**
> +  Set the write status prefix opcode.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The prefix table contains SPI transaction write prefix opcodes which are
> +  accessible after the legacy SPI flash controller's configuration is locked.
> +  The board layer specifies the write status prefix opcode for the SPI NOR
> +  flash part. The SPI NOR flash peripheral driver uses this API to load the
> +  opcode into the prefix table.
> +
> +  @param[in] This               Pointer to an
> +                                EFI_LEGACY_SPI_CONTROLLER_PROTOCOL structure.
> +  @param[in] WriteStatusPrefix  Prefix opcode for the write status
> command.
> +
> +  @retval EFI_SUCCESS       The prefix table was updated
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT8                                     WriteStatusPrefix
> +  );
> +
> +/**
> +  Set the BIOS base address.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS base address works with the protect range registers to protect
> +  portions of the SPI NOR flash from erase and write operat ions. The BIOS
> +  calls this API prior to passing control to the OS loader.
> +
> +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                              structure.
> +  @param[in] BiosBaseAddress  The BIOS base address.
> +
> +  @retval EFI_SUCCESS            The BIOS base address was properly set
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  The BIOS base address is greater than
> +                                 This->Maxi.mumOffset
> +  @retval EFI_UNSUPPORTED        The BIOS base address was already set
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS)
> (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32 BiosBaseAddress
> +  );
> +
> +/**
> +  Clear the SPI protect range registers.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to set an initial condition on the SPI protect
> +  range registers.
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> structure.
> +
> +  @retval EFI_SUCCESS       The registers were successfully cleared
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT)
> (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> +  );
> +
> +/**
> +  Determine if the SPI range is protected.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to verify a range in the SPI is protected.
> +
> +  @param[in] This            Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                             structure.
> +  @param[in] BiosAddress     Address within a 4 KiB block to start protecting.
> +  @param[in] BytesToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval TRUE   The range is protected
> +  @retval FALSE  The range is not protected
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32                                    BiosAddress,
> +  IN UINT32                                    BlocksToProtect
> +  );
> +
> +/**
> +  Set the next protect range register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS sets the protect range register to prevent write and erase
> +  operations to a portion of the SPI NOR flash device.
> +
> +  @param[in] This             Pointer to an
> EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval EFI_SUCCESS            The register was successfully updated
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress,
> or
> +                                 BlocksToProtect * 4 KiB
> +                                   > This->MaximumRangeBytes, or
> +                                 BiosAddress - This->BiosBaseAddress
> +                                   + (BlocksToProtect * 4 KiB)
> +                                     > This->MaximumRangeBytes
> +  @retval EFI_OUT_OF_RESOURCES  No protect range register available
> +  @retval EFI_UNSUPPORTED       Call This->SetBaseAddress because the
> BIOS base
> +                                address is not set
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI
> *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This,
> +  IN UINT32                                    BiosAddress,
> +  IN UINT32                                    BlocksToProtect
> +  );
> +
> +/**
> +  Lock the SPI controller configuration.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine locks the SPI controller's configuration so that the software
> +  is no longer able to update:
> +  * Prefix table
> +  * Opcode menu
> +  * Opcode type table
> +  * BIOS base address
> +  * Protect range registers
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> structure.
> +
> +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER) (
> +  IN CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *This
> +  );
> +
> +///
> +/// Support the extra features of the legacy SPI flash controller.
> +///
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL {
> +  ///
> +  /// Maximum offset from the BIOS base address that is able to be
> protected.
> +  ///
> +  UINT32                                                 MaximumOffset;
> +
> +  ///
> +  /// Maximum number of bytes that can be protected by one range register.
> +  ///
> +  UINT32                                                 MaximumRangeBytes;
> +
> +  ///
> +  /// The number of registers available for protecting the BIOS.
> +  ///
> +  UINT32                                                 RangeRegisterCount;
> +
> +  ///
> +  /// Set the erase block opcode.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_ERASE_BLOCK_OPCODE
> EraseBlockOpcode;
> +
> +  ///
> +  /// Set the write status prefix opcode.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_WRITE_STATUS_PREFIX
> WriteStatusPrefix;
> +
> +  ///
> +  /// Set the BIOS base address.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_BIOS_BASE_ADDRESS
> BiosBaseAddress;
> +
> +  ///
> +  /// Clear the SPI protect range registers.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_CLEAR_SPI_PROTECT
> ClearSpiProtect;
> +
> +  ///
> +  /// Determine if the SPI range is protected.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_IS_RANGE_PROTECTED
> IsRangeProtected;
> +
> +  ///
> +  /// Set the next protect range register.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_PROTECT_NEXT_RANGE
> ProtectNextRange;
> +
> +  ///
> +  /// Lock the SPI controller configuration.
> +  ///
> +  EFI_LEGACY_SPI_CONTROLLER_PROTOCOL_LOCK_CONTROLLER
> LockController;
> +};
> +
> +extern EFI_GUID gEfiLegacySpiControllerProtocolGuid;
> +
> +#endif // __LEGACY_SPI_CONTROLLER_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiFlash.h
> b/MdePkg/Include/Protocol/LegacySpiFlash.h
> new file mode 100644
> index 000000000000..faa5f5724af7
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiFlash.h
> @@ -0,0 +1,201 @@
> +/** @file
> +  This file defines the Legacy SPI Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_CONFIGURATION_PROTOCOL_H__
> +
> +#include <Protocol/SpiNorFlash.h>
> +
> +///
> +/// Global ID for the Legacy SPI Flash Protocol
> +///
> +#define EFI_LEGACY_SPI_FLASH_PROTOCOL_GUID  \
> +  { 0xf01bed57, 0x04bc, 0x4f3f,             \
> +    { 0x96, 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> +
> +typedef struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> EFI_LEGACY_SPI_FLASH_PROTOCOL;
> +
> +/**
> +  Set the BIOS base address.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS base address works with the protect range registers to protect
> +  portions of the SPI NOR flash from erase and write operat ions.
> +  The BIOS calls this API prior to passing control to the OS loader.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosBaseAddress  The BIOS base address.
> +
> +  @retval EFI_SUCCESS            The BIOS base address was properly set
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosBaseAddress > This-
> >MaximumOffset
> +  @retval EFI_UNSUPPORTED        The BIOS base address was already set or
> not a
> +                                 legacy SPI host controller
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosBaseAddress
> +  );
> +
> +/**
> +  Clear the SPI protect range registers.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to set an initial condition on the SPI protect
> +  range registers.
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> structure.
> +
> +  @retval EFI_SUCCESS       The registers were successfully cleared
> +  @retval EFI_ACCESS_ERROR  The SPI controller is locked
> +  @retval EFI_UNSUPPORTED   Not a legacy SPI host controller
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> +  );
> +
> +/**
> +  Determine if the SPI range is protected.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS uses this routine to verify a range in the SPI is protected.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval TRUE   The range is protected
> +  @retval FALSE  The range is not protected
> +
> +**/
> +typedef
> +BOOLEAN
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosAddress,
> +  IN UINT32                               BlocksToProtect
> +  );
> +
> +/**
> +  Set the next protect range register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  The BIOS sets the protect range register to prevent write and erase
> +  operations to a portion of the SPI NOR flash device.
> +
> +  @param[in] This             Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL
> data
> +                              structure.
> +  @param[in] BiosAddress      Address within a 4 KiB block to start protecting.
> +  @param[in] BlocksToProtect  The number of 4 KiB blocks to protect.
> +
> +  @retval EFI_SUCCESS            The register was successfully updated
> +  @retval EFI_ACCESS_ERROR       The SPI controller is locked
> +  @retval EFI_INVALID_PARAMETER  BiosAddress < This->BiosBaseAddress,
> or
> +  @retval EFI_INVALID_PARAMETER  BlocksToProtect * 4 KiB
> +                                   > This->MaximumRangeBytes, or
> +                                 BiosAddress - This->BiosBaseAddress
> +                                   + (BlocksToProtect * 4 KiB)
> +                                     > This->MaximumRangeBytes
> +  @retval EFI_OUT_OF_RESOURCES   No protect range register available
> +  @retval EFI_UNSUPPORTED        Call This->SetBaseAddress because the
> BIOS
> +                                 base address is not set Not a legacy SPI host
> +                                 controller
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This,
> +  IN UINT32                               BiosAddress,
> +  IN UINT32                               BlocksToProtect
> +  );
> +
> +/**
> +  Lock the SPI controller configuration.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine locks the SPI controller's configuration so that the software is
> +  no longer able to update:
> +  * Prefix table
> +  * Opcode menu
> +  * Opcode type table
> +  * BIOS base address
> +  * Protect range registers
> +
> +  @param[in] This  Pointer to an EFI_LEGACY_SPI_FLASH_PROTOCOL data
> structure.
> +
> +  @retval EFI_SUCCESS          The SPI controller was successfully locked
> +  @retval EFI_ALREADY_STARTED  The SPI controller was already locked
> +  @retval EFI_UNSUPPORTED      Not a legacy SPI host controller
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER) (
> +  IN CONST EFI_LEGACY_SPI_FLASH_PROTOCOL  *This
> +  );
> +
> +///
> +/// The EFI_LEGACY_SPI_FLASH_PROTOCOL extends the
> EFI_SPI_NOR_FLASH_PROTOCOL
> +/// with APls to support the legacy SPI flash controller.
> +///
> +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL {
> +  ///
> +  /// This protocol manipulates the SPI NOR flash parts using a common set
> of
> +  /// commands.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL                       FlashProtocol;
> +
> +  //
> +  // Legacy flash (SPI host) controller support
> +  //
> +
> +  ///
> +  /// Set the BIOS base address.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_BIOS_BASE_ADDRESS
> BiosBaseAddress;
> +
> +  ///
> +  /// Clear the SPI protect range registers.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_CLEAR_SPI_PROTECT
> ClearSpiProtect;
> +
> +  ///
> +  /// Determine if the SPI range is protected.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_IS_RANGE_PROTECTED
> IsRangeProtected;
> +
> +  ///
> +  /// Set the next protect range register.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_PROTECT_NEXT_RANGE
> ProtectNextRange;
> +
> +  ///
> +  /// Lock the SPI controller configuration.
> +  ///
> +  EFI_LEGACY_SPI_FLASH_PROTOCOL_LOCK_CONTROLLER    LockController;
> +};
> +
> +extern EFI_GUID gEfiLegacySpiFlashProtocolGuid;
> +
> +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiSmmController.h
> b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> new file mode 100644
> index 000000000000..6d8d557cefff
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiSmmController.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the Legacy SPI SMM Controler Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> +#define __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiController.h>
> +
> +///
> +/// Global ID for the Legacy SPI SMM Controller Protocol
> +///
> +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> +  { 0x62331b78, 0xd8d0, 0x4c8c,                 \
> +    { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_CONTROLLER_PROTOCOL
> +EFI_LEGACY_SPI_SMM_CONTROLLER_PROTOCOL;
> +
> +extern EFI_GUID gEfiLegacySpiSmmControllerProtocolGuid;
> +
> +#endif // __LEGACY_SPI_SMM_CONTROLLER_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> new file mode 100644
> index 000000000000..a604a22f901f
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/LegacySpiSmmFlash.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the Legacy SPI SMM Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> +#define __LEGACY_SPI_SMM_FLASH_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiFlash.h>
> +
> +///
> +/// Global ID for the Legacy SPI SMM Flash Protocol
> +///
> +#define EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL_GUID  \
> +  { 0x5e3848d4, 0x0db5, 0x4fc0,                 \
> +    { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> +
> +typedef
> +struct _EFI_LEGACY_SPI_FLASH_PROTOCOL
> +EFI_LEGACY_SPI_SMM_FLASH_PROTOCOL;
> +
> +extern EFI_GUID gEfiLegacySpiSmmFlashProtocolGuid;
> +
> +#endif // __SPI_SMM_FLASH_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiConfiguration.h
> b/MdePkg/Include/Protocol/SpiConfiguration.h
> new file mode 100644
> index 000000000000..3a602f67d7a6
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiConfiguration.h
> @@ -0,0 +1,293 @@
> +/** @file
> +  This file defines the SPI Configuration Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_CONFIGURATION_PROTOCOL_H__
> +
> +///
> +/// Global ID for the SPI Configuration Protocol
> +///
> +#define EFI_SPI_CONFIGURATION_GUID  \
> +  { 0x85a6d3e6, 0xb65b, 0x4afc,     \
> +    { 0xb3, 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> +
> +///
> +/// Macros to easily specify frequencies in hertz, kilohertz and megahertz.
> +///
> +#define Hz(Frequency)   (Frequency)
> +#define KHz(Frequency)  (1000 * Hz (Frequency))
> +#define MHz(Frequency)  (1000 * KHz (Frequency))
> +
> +typedef struct _EFI_SPI_PERIPHERAL EFI_SPI_PERIPHERAL;
> +
> +/**
> +  Manipulate the chip select for a SPI device.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  Update the value of the chip select line for a SPI peripheral.
> +  The SPI bus layer calls this routine either in the board layer or in the SPI
> +  controller to manipulate the chip select pin at the start and end of a SPI
> +  transaction.
> +
> +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> structure
> +                            describing the SPI peripheral whose chip select pin
> +                            is to be manipulated. The routine may access the
> +                            ChipSelectParameter field to gain sufficient
> +                            context to complete the operation.
> +  @param[in] PinValue       The value to be applied to the chip select line of
> +                            the SPI peripheral.
> +
> +  @retval EFI_SUCCESS            The chip select was set successfully
> +  @retval EFI_NOT_READY          Support for the chip select is not properly
> +                                 initialized
> +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral-
> >ChipSelectParameter value
> +                                 is invalid
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_CHIP_SELECT) (
> +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> +  IN BOOLEAN                   PinValue
> +  );
> +
> +/**
> +  Set up the clock generator to produce the correct clock frequency, phase
> and
> +  polarity for a SPI chip.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine updates the clock generator to generate the correct
> frequency
> +  and polarity for the SPI clock.
> +
> +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure
> from
> +                            which the routine can access the ClockParameter,
> +                            ClockPhase and ClockPolarity fields. The routine
> +                            also has access to the names for the SPI bus and
> +                            chip which can be used during debugging.
> +  @param[in] ClockHz        Pointer to the requested clock frequency. The
> clock
> +                            generator will choose a supported clock frequency
> +                            which is less then or equal to this value.
> +                            Specify zero to turn the clock generator off.
> +                            The actual clock frequency supported by the clock
> +                            generator will be returned.
> +
> +  @retval EFI_SUCCESS      The clock was set up successfully
> +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
> +                           frequency requested by CLockHz
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_CLOCK) (
> +  IN CONST EFI_SPI_PERIPHERAL  *SpiPeripheral,
> +  IN UINT32                    *ClockHz
> +  );
> +
> +///
> +/// The EFI_SPI_PART data structure provides a description of a SPI part
> which
> +/// is independent of the use on the board. This data is available directly
> +/// from the part's datasheet and may be provided by the vendor.
> +///
> +typedef struct _EFI_SPI_PART {
> +  ///
> +  /// A Unicode string specifying the SPI chip vendor.
> +  ///
> +  CONST CHAR16 *Vendor;
> +
> +  ///
> +  /// A Unicode string specifying the SPI chip part number.
> +  ///
> +  CONST CHAR16 *PartNumber;
> +
> +  ///
> +  /// The minimum SPI bus clock frequency used to access this chip. This
> value
> +  /// may be specified in the chip's datasheet. If not, use the value of zero.
> +  ///
> +  UINT32       MinClockHz;
> +
> +  ///
> +  /// The maximum SPI bus clock frequency used to access this chip. This
> value
> +  /// is found in the chip's datasheet.
> +  ///
> +  UINT32       MaxClockHz;
> +
> +  ///
> +  /// Specify the polarity of the chip select pin. This value can be found in
> +  /// the SPI chip's datasheet. Specify TRUE when a one asserts the chip
> select
> +  ///and FALSE when a zero asserts the chip select.
> +  ///
> +  BOOLEAN      ChipSelectPolarity;
> +} EFI_SPI_PART;
> +
> +///
> +/// The EFI_SPI_BUS data structure provides the connection details
> between the
> +/// physical SPI bus and the EFI_SPI_HC_PROTOCOL instance which controls
> that
> +/// SPI bus. This data structure also describes the details of how the clock is
> +/// generated for that SPI bus. Finally this data structure provides the list
> +/// of physical SPI devices which are attached to the SPI bus.
> +///
> +typedef struct _EFI_SPI_BUS {
> +  ///
> +  /// A Unicode string describing the SPI bus
> +  ///
> +  CONST CHAR16                   *FriendlyName;
> +
> +  ///
> +  /// Address of the first EFI_SPI_PERIPHERAL data structure connected to
> this
> +  /// bus. Specify NULL if there are no SPI peripherals connected to this bus.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL       *Peripherallist;
> +
> +  ///
> +  /// Address of an EFI_DEVICE_PATH_PROTOCOL data structure which
> uniquely
> +  /// describes the SPI controller.
> +  ///
> +  CONST EFI_DEVICE_PATH_PROTOCOL *ControllerPath;
> +
> +  ///
> +  /// Address of the routine which controls the clock used by the SPI bus for
> +  /// this SPI peripheral. The SPI host co ntroller's clock routine is called
> +  /// when this value is set to NULL.
> +  ///
> +  EFI_SPI_CLOCK                  Clock;
> +
> +  ///
> +  /// Address of a data structure containing the additional values which
> +  /// describe the necessary control for the clock. When Clock is NULL,
> +  /// the declaration for this data structure is provided by the vendor of the
> +  /// host's SPI controller driver. When Clock is not NULL, the declaration for
> +  /// this data structure is provided by the board layer.
> +  ///
> +  VOID                           *ClockParameter;
> +} EFI_SPI_BUS;
> +
> +///
> +/// The EFI_SPI_PERIPHERAL data structure describes how a specific block
> of
> +/// logic which is connected to the SPI bus. This data structure also selects
> +/// which upper level driver is used to manipulate this SPI device.
> +/// The SpiPeripheraLDriverGuid is available from the vendor of the SPI
> +/// peripheral driver.
> +///
> +struct _EFI_SPI_PERIPHERAL {
> +  ///
> +  /// Address of the next EFI_SPI_PERIPHERAL data structure. Specify NULL
> if
> +  /// the current data structure is the last one on the SPI bus.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL *NextSpiPeripheral;
> +
> +  ///
> +  /// A unicode string describing the function of the SPI part.
> +  ///
> +  CONST CHAR16             *FriendlyName;
> +
> +  ///
> +  /// Address of a GUID provided by the vendor of the SPI peripheral driver.
> +  /// Instead of using a " EFI_SPI_IO_PROTOCOL" GUID, the SPI bus driver
> uses
> +  /// this GUID to identify an EFI_SPI_IO_PROTOCOL data structure and to
> +  /// provide the connection points for the SPI peripheral drivers.
> +  /// This reduces the comparison logic in the SPI peripheral driver's
> +  /// Supported routine.
> +  ///
> +  CONST GUID               *SpiPeripheralDriverGuid;
> +
> +  ///
> +  /// The address of an EFI_SPI_PART data structure which describes this
> chip.
> +  ///
> +  CONST EFI_SPI_PART       *SpiPart;
> +
> +  ///
> +  /// The maximum clock frequency is specified in the EFI_SPI_P ART. When
> this
> +  /// this value is non-zero and less than the value in the EFI_SPI_PART then
> +  /// this value is used for the maximum clock frequency for the SPI part.
> +  ///
> +  UINT32                   MaxClockHz;
> +
> +  ///
> +  /// Specify the idle value of the clock as found in the datasheet.
> +  /// Use zero (0) if the clock'S idle value is low or one (1) if the the
> +  /// clock's idle value is high.
> +  ///
> +  BOOLEAN                  ClockPolarity;
> +
> +  ///
> +  /// Specify the clock delay after chip select. Specify zero (0) to delay an
> +  /// entire clock cycle or one (1) to delay only half a clock cycle.
> +  ///
> +  BOOLEAN                  ClockPhase;
> +
> +  ///
> +  /// SPI peripheral attributes, select zero or more of:
> +  /// * SPI_PART_SUPPORTS_2_B1T_DATA_BUS_W1DTH - The SPI
> peripheral is wired to
> +  ///   support a 2-bit data bus
> +  /// * SPI_PART_SUPPORTS_4_B1T_DATA_BUS_W1DTH - The SPI
> peripheral is wired to
> +  ///   support a 4-bit data bus
> +  ///
> +  UINT32                   Attributes;
> +
> +  ///
> +  /// Address of a vendor specific data structure containing additional board
> +  /// configuration details related to the SPI chip. The SPI peripheral layer
> +  /// uses this data structure when configuring the chip.
> +  ///
> +  CONST VOID               *ConfigurationData;
> +
> +  ///
> +  /// The address of an EFI_SPI_BUS data structure which describes the SPI
> bus
> +  /// to which this chip is connected.
> +  ///
> +  CONST EFI_SPI_BUS        *SpiBus;
> +
> +  ///
> +  /// Address of the routine which controls the chip select pin for this SPI
> +  /// peripheral. Call the SPI host controller's chip select routine when this
> +  /// value is set to NULL.
> +  ///
> +  EFI_SPI_CHIP_SELECT      ChipSelect;
> +
> +  ///
> +  /// Address of a data structure containing the additional values which
> +  /// describe the necessary control for the chip select. When ChipSelect is
> +  /// NULL, the declaration for this data structure is provided by the vendor
> +  /// of the host's SPI controller driver. The vendor's documentation
> specifies
> +  /// the necessary values to use for the chip select pin selection and
> +  /// control. When Chipselect is not NULL, the declaration for this data
> +  /// structure is provided by the board layer.
> +  ///
> +  VOID                     *ChipSelectParameter;
> +};
> +
> +///
> +/// Describe the details of the board's SPI busses to the SPI driver stack.
> +/// The board layer uses the EFI_SPI_CONFIGURATION_PROTOCOL to
> expose the data
> +/// tables which describe the board's SPI busses, The SPI bus layer uses
> these
> +/// tables to configure the clock, chip select and manage the SPI
> transactions
> +/// on the SPI controllers.
> +///
> +typedef struct _EFI_SPI_CONFIGURATION_PROTOCOL {
> +  ///
> +  /// The number of SPI busses on the board.
> +  ///
> +  UINT32                          BusCount;
> +
> +  ///
> +  /// The address of an array of EFI_SPI_BUS data structure addresses.
> +  ///
> +  CONST EFI_SPI_BUS *CONST *CONST Buslist;
> +} EFI_SPI_CONFIGURATION_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiConfigurationProtocolGuid;
> +
> +#endif // __SPI_CONFIGURATION_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiHc.h
> b/MdePkg/Include/Protocol/SpiHc.h
> new file mode 100644
> index 000000000000..13ad5f45225c
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiHc.h
> @@ -0,0 +1,194 @@
> +/** @file
> +  This file defines the SPI Host Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_HC_PROTOCOL_H__
> +#define __SPI_HC_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +#include <Protocol/SpiIo.h>
> +
> +///
> +/// Global ID for the SPI Host Controller Protocol
> +///
> +#define EFI_SPI_HOST_GUID  \
> +  { 0xc74e5db2, 0xfa96, 0x4ae2,   \
> +    { 0xb3, 0x99, 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> +
> +///
> +/// EDK2-style name
> +///
> +#define EFI_SPI_HC_PROTOCOL_GUID  EFI_SPI_HOST_GUID
> +
> +typedef struct _EFI_SPI_HC_PROTOCOL EFI_SPI_HC_PROTOCOL;
> +
> +/**
> +  Assert or deassert the SPI chip select.
> +
> +  This routine is called at TPL_NOTIFY.
> +  Update the value of the chip select line for a SPI peripheral. The SPI bus
> +  layer calls this routine either in the board layer or in the SPI controller
> +  to manipulate the chip select pin at the start and end of a SPI transaction.
> +
> +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] SpiPeripheral  The address of an EFI_SPI_PERIPHERAL data
> structure
> +                            describing the SPI peripheral whose chip select pin
> +                            is to be manipulated. The routine may access the
> +                            ChipSelectParameter field to gain sufficient
> +                            context to complete the operati on.
> +  @param[in] PinValue       The value to be applied to the chip select line of
> +                            the SPI peripheral.
> +
> +  @retval EFI_SUCCESS            The chip select was set as requested
> +  @retval EFI_NOT_READY          Support for the chip select is not properly
> +                                 initialized
> +  @retval EFI_INVALID_PARAMETER  The ChipSeLect value or its contents
> are
> +                                 invalid
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_CHIP_SELECT) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> +  IN BOOLEAN                    PinValue
> +  );
> +
> +/**
> +  Set up the clock generator to produce the correct clock frequency, phase
> and
> +  polarity for a SPI chip.
> +
> +  This routine is called at TPL_NOTIFY.
> +  This routine updates the clock generator to generate the correct
> frequency
> +  and polarity for the SPI clock.
> +
> +  @param[in] This           Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] SpiPeripheral  Pointer to a EFI_SPI_PERIPHERAL data structure
> from
> +                            which the routine can access the ClockParameter,
> +                            ClockPhase and ClockPolarity fields. The routine
> +                            also has access to the names for the SPI bus and
> +                            chip which can be used during debugging.
> +  @param[in] ClockHz        Pointer to the requested clock frequency. The SPI
> +                            host controller will choose a supported clock
> +                            frequency which is less then or equal to this
> +                            value. Specify zero to turn the clock generator
> +                            off. The actual clock frequency supported by the
> +                            SPI host controller will be returned.
> +
> +  @retval EFI_SUCCESS      The clock was set up successfully
> +  @retval EFI_UNSUPPORTED  The SPI controller was not able to support the
> +                           frequency requested by ClockHz
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_CLOCK) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral,
> +  IN UINT32                      *ClockHz
> +  );
> +
> +/**
> +  Perform the SPI transaction on the SPI peripheral using the SPI host
> +  controller.
> +
> +  This routine is called at TPL_NOTIFY.
> +  This routine synchronously returns EFI_SUCCESS indicating that the
> +  asynchronous SPI transaction was started. The routine then waits for
> +  completion of the SPI transaction prior to returning the final transaction
> +  status.
> +
> +  @param[in] This            Pointer to an EFI_SPI_HC_PROTOCOL structure.
> +  @param[in] BusTransaction  Pointer to a EFI_SPI_BUS_ TRANSACTION
> containing
> +                             the description of the SPI transaction to perform.
> +
> +  @retval EFI_SUCCESS          The transaction completed successfully
> +  @retval EFI_BAD_BUFFER_SIZE  The BusTransaction->WriteBytes value is
> invalid,
> +                               or the BusTransaction->ReadinBytes value is
> +                               invalid
> +  @retval EFI_UNSUPPORTED      The BusTransaction-> Transaction Type is
> +                               unsupported
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_HC_PROTOCOL_TRANSACTION) (
> +  IN CONST EFI_SPI_HC_PROTOCOL  *This,
> +  IN EFI_SPI_BUS_TRANSACTION    *BusTransaction
> +  );
> +
> +///
> +/// Support a SPI data transaction between the SPI controller and a SPI chip.
> +///
> +struct _EFI_SPI_HC_PROTOCOL {
> +  ///
> +  /// Host control attributes, may have zero or more of the following set:
> +  /// * HC_SUPPORTS_WRITE_ONLY_OPERATIONS
> +  /// * HC_SUPPORTS_READ_ONLY_OPERATIONS
> +  /// * HC_SUPPORTS_WRITE_THEN_READ_OPERATIONS
> +  /// * HC_TX_FRAME_IN_MOST_SIGNIFICANT_BITS
> +  ///   - The SPI host controller requires the transmit frame to be in most
> +  ///     significant bits instead of least significant bits.The host driver
> +  ///     will adjust the frames if necessary.
> +  /// * HC_RX_FRAME_IN_MOST_SIGNIFICANT_BITS
> +  ///   - The SPI host controller places the receive frame to be in most
> +  ///     significant bits instead of least significant bits.The host driver
> +  ///     will adjust the frames to be in the least significant bits if
> +  ///     necessary.
> +  /// * HC_SUPPORTS_2_BIT_DATA_BUS_W1DTH
> +  ///   - The SPI controller supports a 2 - bit data bus
> +  /// * HC_SUPPORTS_4_B1T_DATA_BUS_WIDTH
> +  ///   - The SPI controller supports a 4 - bit data bus
> +  /// * HC_TRANSFER_SIZE_INCLUDES_OPCODE
> +  ///   - Transfer size includes the opcode byte
> +  /// * HC_TRANSFER_SIZE_INCLUDES_ADDRESS
> +  ///   - Transfer size includes the 3 address bytes
> +  /// The SPI host controller must support full - duplex (receive while
> +  /// sending) operation.The SPI host controller must support a 1 - bit bus
> +  /// width.
> +  ///
> +  UINT32                          Attributes;
> +
> +  ///
> +  /// Mask of frame sizes which the SPI host controller supports. Frame size
> of
> +  /// N-bits is supported when bit N-1 is set. The host controller must
> support
> +  /// a frame size of 8-bits.
> +  ///
> +  UINT32                          FrameSizeSupportMask;
> +
> +  ///
> +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> +  ///
> +  UINT32                          MaximumTransferBytes;
> +
> +  ///
> +  /// Assert or deassert the SPI chip select.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_CHIP_SELECT ChipSelect;
> +
> +  ///
> +  /// Set up the clock generator to produce the correct clock frequency,
> phase
> +  /// and polarity for a SPI chip.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_CLOCK       Clock;
> +
> +  ///
> +  /// Perform the SPI transaction on the SPI peripheral using the SPI host
> +  /// controller.
> +  ///
> +  EFI_SPI_HC_PROTOCOL_TRANSACTION Transaction;
> +};
> +
> +extern EFI_GUID gEfiSpiHcProtocolGuid;
> +
> +#endif // __SPI_HC_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiIo.h
> b/MdePkg/Include/Protocol/SpiIo.h
> new file mode 100644
> index 000000000000..e481779acc58
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiIo.h
> @@ -0,0 +1,292 @@
> +/** @file
> +  This file defines the SPI I/O Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_IO_PROTOCOL_H__
> +#define __SPI_IO_PROTOCOL_H__
> +
> +#include <Protocol/LegacySpiController.h>
> +#include <Protocol/SpiConfiguration.h>
> +
> +typedef struct _EFI_SPI_IO_PROTOCOL EFI_SPI_IO_PROTOCOL;
> +
> +///
> +/// Note: The UEFI PI 1.6 specification does not specify values for the
> +///       members below. The order matches the specification.
> +///
> +typedef enum {
> +  ///
> +  /// Data flowing in both direction between the host and
> +  /// SPI peripheral.ReadBytes must equal WriteBytes and both ReadBuffer
> and
> +  /// WriteBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_FULL_DUPLEX,
> +
> +  ///
> +  /// Data flowing from the host to the SPI peripheral.ReadBytes must be
> +  /// zero.WriteBytes must be non - zero and WriteBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_WRITE_ONLY,
> +
> +  ///
> +  /// Data flowing from the SPI peripheral to the host.WriteBytes must be
> +  /// zero.ReadBytes must be non - zero and ReadBuffer must be provided.
> +  ///
> +  SPI_TRANSACTION_READ_ONLY,
> +
> +  ///
> +  /// Data first flowing from the host to the SPI peripheral and then data
> +  /// flows from the SPI peripheral to the host.These types of operations get
> +  /// used for SPI flash devices when control data (opcode, address) must be
> +  /// passed to the SPI peripheral to specify the data to be read.
> +  ///
> +  SPI_TRANSACTION_WRITE_THEN_READ
> +} EFI_SPI_TRANSACTION_TYPE;
> +
> +/**
> +  Initiate a SPI transaction between the host and a SPI peripheral.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine works with the SPI bus layer to pass the SPI transaction to the
> +  SPI controller for execution on the SPI bus. There are four types of
> +  supported transactions supported by this routine:
> +  * Full Duplex: WriteBuffer and ReadBuffer are the same size.
> +  * Write Only: WriteBuffer contains data for SPI peripheral, ReadBytes = 0
> +  * Read Only: ReadBuffer to receive data from SPI peripheral, WriteBytes =
> 0
> +  * Write Then Read: WriteBuffer contains control data to write to SPI
> +                     peripheral before data is placed into the ReadBuffer.
> +                     Both WriteBytes and ReadBytes must be non-zero.
> +
> +  @param[in]  This              Pointer to an EFI_SPI_IO_PROTOCOL structure.
> +  @param[in]  TransactionType   Type of SPI transaction.
> +  @param[in]  DebugTransaction  Set TRUE only when debugging is desired.
> +                                Debugging may be turned on for a single SPI
> +                                transaction. Only this transaction will display
> +                                debugging messages. All other transactions with
> +                                this value set to FALSE will not display any
> +                                debugging messages.
> +  @param[in]  ClockHz           Specify the ClockHz value as zero (0) to use
> +                                the maximum clock frequency supported by the
> +                                SPI controller and part. Specify a non-zero
> +                                value only when a specific SPI transaction
> +                                requires a reduced clock rate.
> +  @param[in]  BusWidth          Width of the SPI bus in bits: 1, 2, 4
> +  @param[in]  FrameSize         Frame size in bits, range: 1 - 32
> +  @param[in]  WriteBytes        The length of the WriteBuffer in bytes.
> +                                Specify zero for read-only operations.
> +  @param[in]  WriteBuffer       The buffer containing data to be sent from the
> +                                host to the SPI chip. Specify NULL for read
> +                                only operations.
> +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> +                                  frame
> +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> +                                  frame
> +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> +                                  per frame The transmit frame is in the least
> +                                  significant N bits.
> +  @param[in]  ReadBytes         The length of the ReadBuffer in bytes.
> +                                Specify zero for write-only operations.
> +  @param[out] ReadBuffer        The buffer to receeive data from the SPI chip
> +                                during the transaction. Specify NULL for write
> +                                only operations.
> +                                * Frame sizes 1-8 bits: UINT8 (one byte) per
> +                                  frame
> +                                * Frame sizes 7-16 bits: UINT16 (two bytes) per
> +                                  frame
> +                                * Frame sizes 17-32 bits: UINT32 (four bytes)
> +                                  per frame The received frame is in the least
> +                                  significant N bits.
> +
> +  @retval EFI_SUCCESS            The SPI transaction completed successfully
> +  @retval EFI_BAD_BUFFER_SIZE    The writeBytes value was invalid
> +  @retval EFI_BAD_BUFFER_SIZE    The ReadBytes value was invalid
> +  @retval EFI_INVALID_PARAMETER  TransactionType is not valid,
> +                                 or BusWidth not supported by SPI peripheral or
> +                                 SPI host controller,
> +                                 or WriteBytes non-zero and WriteBuffer is
> +                                 NULL,
> +                                 or ReadBytes non-zero and ReadBuffer is NULL,
> +                                 or ReadBuffer != WriteBuffer for full-duplex
> +                                 type,
> +                                 or WriteBuffer was NULL,
> +                                 or TPL is too high
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory for SPI transaction
> +  @retval EFI_UNSUPPORTED        The FrameSize is not supported by the SPI
> bus
> +                                 layer or the SPI host controller
> +  @retval EFI_UNSUPPORTED        The SPI controller was not able to support
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_TRANSACTION) (
> +  IN  CONST EFI_SPI_IO_PROTOCOL  *This,
> +  IN  EFI_SPI_TRANSACTION_TYPE   TransactionType,
> +  IN  BOOLEAN                    DebugTransaction,
> +  IN  UINT32                     ClockHz OPTIONAL,
> +  IN  UINT32                     BusWidth,
> +  IN  UINT32                     FrameSize,
> +  IN  UINT32                     WriteBytes,
> +  IN  UINT8                      *WriteBuffer,
> +  IN  UINT32                     ReadBytes,
> +  OUT UINT8                      *ReadBuffer
> +  );
> +
> +/**
> +  Update the SPI peripheral associated with this SPI 10 instance.
> +
> +  Support socketed SPI parts by allowing the SPI peripheral driver to replace
> +  the SPI peripheral after the connection is made. An example use is
> socketed
> +  SPI NOR flash parts, where the size and parameters change depending
> upon
> +  device is in the socket.
> +
> +  @param[in] This           Pointer to an EFI_SPI_IO_PROTOCOL structure.
> +  @param[in] SpiPeripheral  Pointer to an EFI_SPI_PERIPHERAL structure.
> +
> +  @retval EFI_SUCCESS            The SPI peripheral was updated successfully
> +  @retval EFI_INVALID_PARAMETER  The SpiPeripheral value is NULL,
> +                                 or the SpiPeripheral->SpiBus is NULL,
> +                                 or the SpiP eripheral - >SpiBus pointing at
> +                                 wrong bus,
> +                                 or the SpiP eripheral - >SpiPart is NULL
> +
> +**/
> +typedef EFI_STATUS
> +(EFIAPI *EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL) (
> +  IN CONST EFI_SPI_IO_PROTOCOL  *This,
> +  IN CONST EFI_SPI_PERIPHERAL   *SpiPeripheral
> +  );
> +
> +///
> +/// The EFI_SPI_BUS_ TRANSACTION data structure contains the
> description of the
> +/// SPI transaction to perform on the host controller.
> +///
> +typedef struct _EFI_SPI_BUS_TRANSACTION {
> +  ///
> +  /// Pointer to the SPI peripheral being manipulated.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL *SpiPeripheral;
> +
> +  ///
> +  /// Type of transaction specified by one of the
> EFI_SPI_TRANSACTION_TYPE
> +  /// values.
> +  ///
> +  EFI_SPI_TRANSACTION_TYPE TransactionType;
> +
> +  ///
> +  /// TRUE if the transaction is being debugged. Debugging may be turned
> on for
> +  /// a single SPI transaction. Only this transaction will display debugging
> +  /// messages. All other transactions with this value set to FALSE will not
> +  /// display any debugging messages.
> +  ///
> +  BOOLEAN                  DebugTransaction;
> +
> +  ///
> +  /// SPI bus width in bits: 1, 2, 4
> +  ///
> +  UINT32                   BusWidth;
> +
> +  ///
> +  /// Frame size in bits, range: 1 - 32
> +  ///
> +  UINT32                   FrameSize;
> +
> +  ///
> +  /// Length of the write buffer in bytes
> +  ///
> +  UINT32                   WriteBytes;
> +
> +  ///
> +  /// Buffer containing data to send to the SPI peripheral
> +  /// Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> +  /// Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> +  ///
> +  UINT8                    *WriteBuffer;
> +
> +  ///
> +  /// Length of the read buffer in bytes
> +  ///
> +  UINT32                   ReadBytes;
> +
> +  ///
> +  /// Buffer to receive the data from the SPI peripheral
> +  /// * Frame sizes 1 - 8 bits: UINT8 (one byte) per frame
> +  /// * Frame sizes 7 - 16 bits : UINT16 (two bytes) per frame
> +  /// * Frame sizes 17 - 32 bits : UINT32 (four bytes) per frame
> +  ///
> +  UINT8                    *ReadBuffer;
> +} EFI_SPI_BUS_TRANSACTION;
> +
> +///
> +/// Support managed SPI data transactions between the SPI controller and a
> SPI
> +/// chip.
> +///
> +struct _EFI_SPI_IO_PROTOCOL {
> +  ///
> +  /// Address of an EFI_SPI_PERIPHERAL data structure associated with this
> +  /// protocol instance.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                  *SpiPeripheral;
> +
> +  ///
> +  /// Address of the original EFI_SPI_PERIPHERAL data structure associated
> with
> +  /// this protocol instance.
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                  *OriginalSpiPeripheral;
> +
> +  ///
> +  /// Mask of frame sizes which the SPI 10 layer supports. Frame size of N-
> bits
> +  /// is supported when bit N-1 is set. The host controller must support a
> +  /// frame size of 8-bits. Frame sizes of 16, 24 and 32-bits are converted to
> +  /// 8-bit frame sizes by the SPI bus layer if the frame size is not supported
> +  /// by the SPI host controller.
> +  ///
> +  UINT32                                    FrameSizeSupportMask;
> +
> +  ///
> +  /// Maximum transfer size in bytes: 1 - Oxffffffff
> +  ///
> +  UINT32                                    MaximumTransferBytes;
> +
> +  ///
> +  /// Transaction attributes: One or more from:
> +  /// * SPI_10_SUPPORTS_2_B1T_DATA_BUS_W1DTH
> +  ///   - The SPI host and peripheral supports a 2-bit data bus
> +  /// * SPI_IO_SUPPORTS_4_BIT_DATA_BUS_W1DTH
> +  ///   - The SPI host and peripheral supports a 4-bit data bus
> +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_OPCODE
> +  ///   - Transfer size includes the opcode byte
> +  /// * SPI_IO_TRANSFER_SIZE_INCLUDES_ADDRESS
> +  ///   - Transfer size includes the 3 address bytes
> +  ///
> +  UINT32                                    Attributes;
> +
> +  ///
> +  /// Pointer to legacy SPI controller protocol
> +  ///
> +  CONST EFI_LEGACY_SPI_CONTROLLER_PROTOCOL  *LegacySpiProtocol;
> +
> +  ///
> +  /// Initiate a SPI transaction between the host and a SPI peripheral.
> +  ///
> +  EFI_SPI_IO_PROTOCOL_TRANSACTION           Transaction;
> +
> +  ///
> +  /// Update the SPI peripheral associated with this SPI 10 instance.
> +  ///
> +  EFI_SPI_IO_PROTOCOL_UPDATE_SPI_PERIPHERAL UpdateSpiPeripheral;
> +};
> +
> +#endif // __SPI_IO_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiNorFlash.h
> b/MdePkg/Include/Protocol/SpiNorFlash.h
> new file mode 100644
> index 000000000000..93d2adaa860e
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiNorFlash.h
> @@ -0,0 +1,289 @@
> +/** @file
> +  This file defines the SPI NOR Flash Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_NOR_FLASH_PROTOCOL_H__
> +#define __SPI_NOR_FLASH_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +
> +///
> +/// Global ID for the SPI NOR Flash Protocol
> +///
> +#define EFI_SPI_NOR_FLASH_PROTOCOL_GUID  \
> +  { 0xb57ec3fe, 0xf833, 0x4ba6,          \
> +    { 0x85, 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> +
> +typedef struct _EFI_SPI_NOR_FLASH_PROTOCOL
> EFI_SPI_NOR_FLASH_PROTOCOL;
> +
> +/**
> +  Read the 3 byte manufacture and device ID from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads the 3 byte manufacture and device ID from the flash
> part
> +  filling the buffer provided.
> +
> +  @param[in]  This    Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> structure.
> +  @param[out] Buffer  Pointer to a 3 byte buffer to receive the manufacture
> and
> +                      device ID.
> +
> +
> +
> +  @retval EFI_SUCCESS            The manufacture and device ID was read
> +                                 successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL
> +  @retval EFI_DEVICE_ERROR       Invalid data received from SPI flash part.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Read data from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads data from the SPI part in the buffer provided.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  FlashAddress   Address in the flash to start reading
> +  @param[in]  LengthInBytes  Read length in bytes
> +  @param[out] Buffer         Address of a buffer to receive the data
> +
> +  @retval EFI_SUCCESS            The data was read successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            FlashAddress,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Low frequency read data from the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads data from the SPI part in the buffer provided.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  FlashAddress   Address in the flash to start reading
> +  @param[in]  LengthInBytes  Read length in bytes
> +  @param[out] Buffer         Address of a buffer to receive the data
> +
> +  @retval EFI_SUCCESS            The data was read successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_LF_READ_DATA) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            FlashAddress,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *Buffer
> +  );
> +
> +/**
> +  Read the flash status register.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine reads the flash part status register.
> +
> +  @param[in]  This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                             structure.
> +  @param[in]  LengthInBytes  Number of status bytes to read.
> +  @param[out] FlashStatus    Pointer to a buffer to receive the flash status.
> +
> +  @retval EFI_SUCCESS  The status register was read successfully.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS) (
> +  IN  CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN  UINT32                            LengthInBytes,
> +  OUT UINT8                             *FlashStatus
> +  );
> +
> +/**
> +  Write the flash status register.
> +
> +  This routine must be called at or below TPL_N OTIFY.
> +  This routine writes the flash part status register.
> +
> +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                            structure.
> +  @param[in] LengthInBytes  Number of status bytes to write.
> +  @param[in] FlashStatus    Pointer to a buffer containing the new status.
> +
> +  @retval EFI_SUCCESS           The status write was successful.
> +  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the write buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            LengthInBytes,
> +  IN UINT8                             *FlashStatus
> +  );
> +
> +/**
> +  Write data to the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine breaks up the write operation as necessary to write the data
> to
> +  the SPI part.
> +
> +  @param[in] This           Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                            structure.
> +  @param[in] FlashAddress   Address in the flash to start writing
> +  @param[in] LengthInBytes  Write length in bytes
> +  @param[in] Buffer         Address of a buffer containing the data
> +
> +  @retval EFI_SUCCESS            The data was written successfully.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL, or
> +                                 FlashAddress >= This->FlashSize, or
> +                                 LengthInBytes > This->FlashSize - FlashAddress
> +  @retval EFI_OUT_OF_RESOURCES   Insufficient memory to copy buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            FlashAddress,
> +  IN UINT32                            LengthInBytes,
> +  IN UINT8                             *Buffer
> +  );
> +
> +/**
> +  Efficiently erases one or more 4KiB regions in the SPI flash.
> +
> +  This routine must be called at or below TPL_NOTIFY.
> +  This routine uses a combination of 4 KiB and larger blocks to erase the
> +  specified area.
> +
> +  @param[in] This          Pointer to an EFI_SPI_NOR_FLASH_PROTOCOL data
> +                           structure.
> +  @param[in] FlashAddress  Address within a 4 KiB block to start erasing
> +  @param[in] BlockCount    Number of 4 KiB blocks to erase
> +
> +  @retval EFI_SUCCESS            The erase was completed successfully.
> +  @retval EFI_INVALID_PARAMETER  FlashAddress >= This->FlashSize, or
> +                                 BlockCount * 4 KiB
> +                                   > This->FlashSize - FlashAddress
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_SPI_NOR_FLASH_PROTOCOL_ERASE) (
> +  IN CONST EFI_SPI_NOR_FLASH_PROTOCOL  *This,
> +  IN UINT32                            FlashAddress,
> +  IN UINT32                            BlockCount
> +  );
> +
> +///
> +/// The EFI_SPI_NOR_FLASH_PROTOCOL exists in the SPI peripheral layer.
> +/// This protocol manipulates the SPI NOR flash parts using a common set of
> +/// commands. The board layer provides the interconnection and
> configuration
> +/// details for the SPI NOR flash part. The SPI NOR flash driver uses this
> +/// configuration data to expose a generic interface which provides the
> +/// following APls:
> +/// * Read manufacture and device ID
> +/// * Read data
> +/// * Read data using low frequency
> +/// * Read status
> +/// * Write data
> +/// * Erase 4 KiB blocks
> +/// * Erase 32 or 64 KiB blocks
> +/// * Write status
> +/// The EFI_SPI_NOR_FLASH_PROTOCOL also exposes some APls to set the
> security
> +/// features on the legacy SPI flash controller.
> +///
> +struct _EFI_SPI_NOR_FLASH_PROTOCOL {
> +  ///
> +  /// Pointer to an EFI_SPI_PERIPHERAL data structure
> +  ///
> +  CONST EFI_SPI_PERIPHERAL                *SpiPeripheral;
> +
> +  ///
> +  /// Flash size in bytes
> +  ///
> +  UINT32                                  FlashSize;
> +
> +  ///
> +  /// Manufacture and Device ID
> +  ///
> +  UINT8                                   Deviceid[3];
> +
> +  ///
> +  /// Erase block size in bytes
> +  ///
> +  UINT32                                  EraseBlockBytes;
> +
> +  ///
> +  /// Read the 3 byte manufacture and device ID from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_GET_FLASH_ID GetFlashid;
> +
> +  ///
> +  /// Read data from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    ReadData;
> +
> +  ///
> +  /// Low frequency read data from the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_DATA    LfReadData;
> +
> +  ///
> +  /// Read the flash status register.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_READ_STATUS  ReadStatus;
> +
> +  ///
> +  /// Write the flash status register.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_STATUS WriteStatus;
> +
> +  ///
> +  /// Write data to the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_WRITE_DATA   WriteData;
> +
> +  ///
> +  /// Efficiently erases one or more 4KiB regions in the SPI flash.
> +  ///
> +  EFI_SPI_NOR_FLASH_PROTOCOL_ERASE        Erase;
> +};
> +
> +extern EFI_GUID gEfiSpiNorFlashProtocolGuid;
> +
> +#endif // __SPI_NOR_FLASH_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> new file mode 100644
> index 000000000000..913d4cbb46aa
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiSmmConfiguration.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the SPI SMM Configuration Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> +#define __SPI_SMM_CONFIGURATION_PROTOCOL_H__
> +
> +#include <Protocol/SpiConfiguration.h>
> +
> +///
> +/// Global ID for the SPI SMM Configuration Protocol
> +///
> +#define EFI_SPI_SMM_CONFIGURATION_PROTOCOL_GUID  \
> +  { 0x995c6eca, 0x171b, 0x45fd,                  \
> +    { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> +
> +typedef
> +struct _EFI_SPI_CONFIGURATION_PROTOCOL
> +EFI_SPI_SMM_CONFIGURATION_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiSmmConfigurationProtocolGuid;
> +
> +#endif // __SPI_SMM_CONFIGURATION_H__
> diff --git a/MdePkg/Include/Protocol/SpiSmmHc.h
> b/MdePkg/Include/Protocol/SpiSmmHc.h
> new file mode 100644
> index 000000000000..91d2312b74b4
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/SpiSmmHc.h
> @@ -0,0 +1,36 @@
> +/** @file
> +  This file defines the SPI SMM Host Controller Protocol.
> +
> +  Copyright (c) 2017, 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.
> +
> +  @par Revision Reference:
> +    This Protocol was introduced in UEFI PI Specification 1.6.
> +
> +**/
> +
> +#ifndef __SPI_SMM_HC_H__
> +#define __SPI_SMM_HC_H__
> +
> +#include <Protocol/SpiHc.h>
> +
> +///
> +/// Global ID for the SPI SMM Host Controller Protocol
> +///
> +#define EFI_SPI_SMM_HC_PROTOCOL_GUID  \
> +  { 0xe9f02217, 0x2093, 0x4470,       \
> +    { 0x8a, 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> +
> +typedef
> +struct _EFI_SPI_HC_PROTOCOL
> +EFI_SPI_SMM_HC_PROTOCOL;
> +
> +extern EFI_GUID gEfiSpiSmmHcProtocolGuid;
> +
> +#endif // __SPI_SMM_HC_H__
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> index 1867c54c3bc1..91af6c5c455c 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -1246,6 +1246,37 @@ [Protocols]
>    gEfiMmCommunicationProtocolGuid  = { 0xc68ed8e2, 0x9dc6, 0x4cbd,
> { 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 }}
> 
>    #
> +  # Protocols defined in PI 1.6.
> +  #
> +
> +  ## Include/Protocol/LegacySpiController.h
> +  gEfiLegacySpiControllerProtocolGuid    = { 0x39136fc7, 0x1a11, 0x49de,
> { 0xbf, 0x35, 0x0e, 0x78, 0xdd, 0xb5, 0x24, 0xfc }}
> +
> +  ## Include/Protocol/LegacySpiFlash.h
> +  gEfiLegacySpiFlashProtocolGuid         = { 0xf01bed57, 0x04bc, 0x4f3f, { 0x96,
> 0x60, 0xd6, 0xf2, 0xea, 0x22, 0x82, 0x59 }}
> +
> +  ## Include/Protocol/LegacySpiSmmController.h
> +  gEfiLegacySpiSmmControllerProtocolGuid = { 0x62331b78, 0xd8d0, 0x4c8c,
> { 0x8c, 0xcb, 0xd2, 0x7d, 0xfe, 0x32, 0xdb, 0x9b }}
> +
> +  ## Include/Protocol/LegacySpiSmmFlash.h
> +  gEfiLegacySpiSmmFlashProtocolGuid      = { 0x5e3848d4, 0x0db5, 0x4fc0,
> { 0x97, 0x29, 0x3f, 0x35, 0x3d, 0x4f, 0x87, 0x9f }}
> +
> +  ## Include/Protocol/SpiConfiguration.h
> +  gEfiSpiConfigurationProtocolGuid       = { 0x85a6d3e6, 0xb65b, 0x4afc, { 0xb3,
> 0x8f, 0xc6, 0xd5, 0x4a, 0xf6, 0xdd, 0xc8 }}
> +
> +  ## Include/Protocol/SpiHc.h
> +  gEfiSpiHcProtocolGuid                  = { 0xc74e5db2, 0xfa96, 0x4ae2, { 0xb3, 0x99,
> 0x15, 0x97, 0x7f, 0xe3, 0x0, 0x2d }}
> +
> +  ## Include/Protocol/SpiNorFlash.h
> +  gEfiSpiNorFlashProtocolGuid            = { 0xb57ec3fe, 0xf833, 0x4ba6, { 0x85,
> 0x78, 0x2a, 0x7d, 0x6a, 0x87, 0x44, 0x4b }}
> +
> +  ## Include/Protocol/SpiSmmConfiguration.h
> +  gEfiSpiSmmConfigurationProtocolGuid    = { 0x995c6eca, 0x171b, 0x45fd,
> { 0xa3, 0xaa, 0xfd, 0x4c, 0x9c, 0x9d, 0xef, 0x59 }}
> +
> +  ## Include/Protocol/SpiSmmHc.h
> +  gEfiSpiSmmHcProtocolGuid               = { 0xe9f02217, 0x2093, 0x4470, { 0x8a,
> 0x54, 0x5c, 0x2c, 0xff, 0xe7, 0x3e, 0xcb }}
> +
> +  #
>    # Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
>    #
> 
> --
> 2.12.2.windows.2
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel