瀏覽代碼

UefiCpuPkg: CpuIo2Smm: Abstract SMM specific functions into separate file

This change abstracts CpuIo2Smm driver entrypoint into separate file and
moves functions/definitions that are not substantially specific to
Traditional MM (SMM) into CpuIo2Mm.* in order to set ways for Standalone
MM support in the future.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>

Signed-off-by: Kun Qin <kun.q@outlook.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Kun Qin 3 年之前
父節點
當前提交
1ea21af13d
共有 4 個文件被更改,包括 421 次插入381 次删除
  1. 402 0
      UefiCpuPkg/CpuIo2Smm/CpuIo2Mm.c
  2. 12 0
      UefiCpuPkg/CpuIo2Smm/CpuIo2Mm.h
  3. 5 380
      UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c
  4. 2 1
      UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf

+ 402 - 0
UefiCpuPkg/CpuIo2Smm/CpuIo2Mm.c

@@ -0,0 +1,402 @@
+/** @file
+  Produces the SMM CPU I/O Protocol.
+
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuIo2Mm.h"
+
+//
+// Handle for the SMM CPU I/O Protocol
+//
+EFI_HANDLE  mHandle = NULL;
+
+//
+// SMM CPU I/O Protocol instance
+//
+EFI_SMM_CPU_IO2_PROTOCOL mSmmCpuIo2 = {
+  {
+    CpuMemoryServiceRead,
+    CpuMemoryServiceWrite
+  },
+  {
+    CpuIoServiceRead,
+    CpuIoServiceWrite
+  }
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mStride[] = {
+  1, // SMM_IO_UINT8
+  2, // SMM_IO_UINT16
+  4, // SMM_IO_UINT32
+  8  // SMM_IO_UINT64
+};
+
+/**
+  Check parameters to a SMM CPU I/O Protocol service request.
+
+  @param[in]  MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
+  @param[in]  Width          Signifies the width of the I/O operations.
+  @param[in]  Address        The base address of the I/O operations.  The caller is
+                             responsible for aligning the Address if required.
+  @param[in]  Count          The number of I/O operations to perform.
+  @param[in]  Buffer         For read operations, the destination buffer to store
+                             the results.  For write operations, the source buffer
+                             from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the device.
+  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
+
+**/
+EFI_STATUS
+CpuIoCheckParameter (
+  IN BOOLEAN           MmioOperation,
+  IN EFI_SMM_IO_WIDTH  Width,
+  IN UINT64            Address,
+  IN UINTN             Count,
+  IN VOID              *Buffer
+  )
+{
+  UINT64  MaxCount;
+  UINT64  Limit;
+
+  //
+  // Check to see if Buffer is NULL
+  //
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range
+  //
+  if ((UINT32)Width > SMM_IO_UINT64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range for I/O Port operations
+  //
+  if (!MmioOperation && (Width == SMM_IO_UINT64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if any address associated with this transfer exceeds the maximum
+  // allowed address.  The maximum address implied by the parameters passed in is
+  // Address + Size * Count.  If the following condition is met, then the transfer
+  // is not supported.
+  //
+  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
+  //
+  // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
+  // can also be the maximum integer value supported by the CPU, this range
+  // check must be adjusted to avoid all overflow conditions.
+  //
+  // The following form of the range check is equivalent but assumes that
+  // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
+  //
+  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
+  if (Count == 0) {
+    if (Address > Limit) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    MaxCount = RShiftU64 (Limit, Width);
+    if (MaxCount < (Count - 1)) {
+      return EFI_UNSUPPORTED;
+    }
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // Check to see if Address is aligned
+  //
+  if ((Address & ((UINT64)mStride[Width] - 1)) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested.  The caller is
+  responsible for any alignment and I/O width issues that the bus, device,
+  platform, or type of I/O might require.
+
+  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O operations.
+  @param[in]  Address  The base address of the I/O operations.  The caller is
+                       responsible for aligning the Address if required.
+  @param[in]  Count    The number of I/O operations to perform.
+  @param[out] Buffer   For read operations, the destination buffer to store
+                       the results.  For write operations, the source buffer
+                       from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the device.
+  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+  IN  CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
+  IN  EFI_SMM_IO_WIDTH                Width,
+  IN  UINT64                          Address,
+  IN  UINTN                           Count,
+  OUT VOID                            *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Stride;
+  UINT8       *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  Stride = mStride[Width];
+  for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+    if (Width == SMM_IO_UINT8) {
+      *Uint8Buffer = MmioRead8 ((UINTN)Address);
+    } else if (Width == SMM_IO_UINT16) {
+      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+    } else if (Width == SMM_IO_UINT32) {
+      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+    } else if (Width == SMM_IO_UINT64) {
+      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes memory-mapped registers.
+
+  The I/O operations are carried out exactly as requested.  The caller is
+  responsible for any alignment and I/O width issues that the bus, device,
+  platform, or type of I/O might require.
+
+  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O operations.
+  @param[in]  Address  The base address of the I/O operations.  The caller is
+                       responsible for aligning the Address if required.
+  @param[in]  Count    The number of I/O operations to perform.
+  @param[in]  Buffer   For read operations, the destination buffer to store
+                       the results.  For write operations, the source buffer
+                       from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the device.
+  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+  IN CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
+  IN EFI_SMM_IO_WIDTH                Width,
+  IN UINT64                          Address,
+  IN UINTN                           Count,
+  IN VOID                            *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Stride;
+  UINT8       *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  Stride = mStride[Width];
+  for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+    if (Width == SMM_IO_UINT8) {
+      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (Width == SMM_IO_UINT16) {
+      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (Width == SMM_IO_UINT32) {
+      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    } else if (Width == SMM_IO_UINT64) {
+      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads I/O registers.
+
+  The I/O operations are carried out exactly as requested.  The caller is
+  responsible for any alignment and I/O width issues that the bus, device,
+  platform, or type of I/O might require.
+
+  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O operations.
+  @param[in]  Address  The base address of the I/O operations.  The caller is
+                       responsible for aligning the Address if required.
+  @param[in]  Count    The number of I/O operations to perform.
+  @param[out] Buffer   For read operations, the destination buffer to store
+                       the results.  For write operations, the source buffer
+                       from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the device.
+  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+  IN  CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
+  IN  EFI_SMM_IO_WIDTH                Width,
+  IN  UINT64                          Address,
+  IN  UINTN                           Count,
+  OUT VOID                            *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Stride;
+  UINT8       *Uint8Buffer;
+
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  Stride = mStride[Width];
+  for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+    if (Width == SMM_IO_UINT8) {
+      *Uint8Buffer = IoRead8 ((UINTN)Address);
+    } else if (Width == SMM_IO_UINT16) {
+      *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);
+    } else if (Width == SMM_IO_UINT32) {
+      *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write I/O registers.
+
+  The I/O operations are carried out exactly as requested.  The caller is
+  responsible for any alignment and I/O width issues that the bus, device,
+  platform, or type of I/O might require.
+
+  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
+  @param[in]  Width    Signifies the width of the I/O operations.
+  @param[in]  Address  The base address of the I/O operations.  The caller is
+                       responsible for aligning the Address if required.
+  @param[in]  Count    The number of I/O operations to perform.
+  @param[in]  Buffer   For read operations, the destination buffer to store
+                       the results.  For write operations, the source buffer
+                       from which to write data.
+
+  @retval EFI_SUCCESS            The data was read from or written to the device.
+  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources
+
+**/
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+  IN CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
+  IN EFI_SMM_IO_WIDTH                Width,
+  IN UINT64                          Address,
+  IN UINTN                           Count,
+  IN VOID                            *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Stride;
+  UINT8       *Uint8Buffer;
+
+  //
+  // Make sure the parameters are valid
+  //
+  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  Stride = mStride[Width];
+  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
+    if (Width == SMM_IO_UINT8) {
+      IoWrite8 ((UINTN)Address, *Uint8Buffer);
+    } else if (Width == SMM_IO_UINT16) {
+      IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+    } else if (Width == SMM_IO_UINT32) {
+      IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The module Entry Point SmmCpuIoProtocol driver
+
+  @retval EFI_SUCCESS  The entry point is executed successfully.
+  @retval Other        Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+CommonCpuIo2Initialize (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Copy the SMM CPU I/O Protocol instance into the System Management System Table
+  //
+  CopyMem (&gMmst->MmIo, &mSmmCpuIo2, sizeof (mSmmCpuIo2));
+
+  //
+  // Install the SMM CPU I/O Protocol into the MM protocol database
+  //
+  Status = gMmst->MmInstallProtocolInterface (
+                    &mHandle,
+                    &gEfiSmmCpuIo2ProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &mSmmCpuIo2
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}

+ 12 - 0
UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.h → UefiCpuPkg/CpuIo2Smm/CpuIo2Mm.h

@@ -153,4 +153,16 @@ CpuIoServiceWrite (
   IN VOID                            *Buffer
   );
 
+/**
+  The module Entry Point SmmCpuIoProtocol driver
+
+  @retval EFI_SUCCESS  The entry point is executed successfully.
+  @retval Other        Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+CommonCpuIo2Initialize (
+  VOID
+  );
+
 #endif

+ 5 - 380
UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.c

@@ -2,374 +2,17 @@
   Produces the SMM CPU I/O Protocol.
 
 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
 
-#include "CpuIo2Smm.h"
+#include <PiSmm.h>
 
-//
-// Handle for the SMM CPU I/O Protocol
-//
-EFI_HANDLE  mHandle = NULL;
-
-//
-// SMM CPU I/O Protocol instance
-//
-EFI_SMM_CPU_IO2_PROTOCOL mSmmCpuIo2 = {
-  {
-    CpuMemoryServiceRead,
-    CpuMemoryServiceWrite
-  },
-  {
-    CpuIoServiceRead,
-    CpuIoServiceWrite
-  }
-};
-
-//
-// Lookup table for increment values based on transfer widths
-//
-UINT8 mStride[] = {
-  1, // SMM_IO_UINT8
-  2, // SMM_IO_UINT16
-  4, // SMM_IO_UINT32
-  8  // SMM_IO_UINT64
-};
-
-/**
-  Check parameters to a SMM CPU I/O Protocol service request.
-
-  @param[in]  MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
-  @param[in]  Width          Signifies the width of the I/O operations.
-  @param[in]  Address        The base address of the I/O operations.  The caller is
-                             responsible for aligning the Address if required.
-  @param[in]  Count          The number of I/O operations to perform.
-  @param[in]  Buffer         For read operations, the destination buffer to store
-                             the results.  For write operations, the source buffer
-                             from which to write data.
-
-  @retval EFI_SUCCESS            The data was read from or written to the device.
-  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
-  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
-
-**/
-EFI_STATUS
-CpuIoCheckParameter (
-  IN BOOLEAN           MmioOperation,
-  IN EFI_SMM_IO_WIDTH  Width,
-  IN UINT64            Address,
-  IN UINTN             Count,
-  IN VOID              *Buffer
-  )
-{
-  UINT64  MaxCount;
-  UINT64  Limit;
-
-  //
-  // Check to see if Buffer is NULL
-  //
-  if (Buffer == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check to see if Width is in the valid range
-  //
-  if ((UINT32)Width > SMM_IO_UINT64) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check to see if Width is in the valid range for I/O Port operations
-  //
-  if (!MmioOperation && (Width == SMM_IO_UINT64)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check to see if any address associated with this transfer exceeds the maximum
-  // allowed address.  The maximum address implied by the parameters passed in is
-  // Address + Size * Count.  If the following condition is met, then the transfer
-  // is not supported.
-  //
-  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
-  //
-  // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
-  // can also be the maximum integer value supported by the CPU, this range
-  // check must be adjusted to avoid all overflow conditions.
-  //
-  // The following form of the range check is equivalent but assumes that
-  // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
-  //
-  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
-  if (Count == 0) {
-    if (Address > Limit) {
-      return EFI_UNSUPPORTED;
-    }
-  } else {
-    MaxCount = RShiftU64 (Limit, Width);
-    if (MaxCount < (Count - 1)) {
-      return EFI_UNSUPPORTED;
-    }
-    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
-      return EFI_UNSUPPORTED;
-    }
-  }
-
-  //
-  // Check to see if Address is aligned
-  //
-  if ((Address & ((UINT64)mStride[Width] - 1)) != 0) {
-    return EFI_UNSUPPORTED;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Reads memory-mapped registers.
-
-  The I/O operations are carried out exactly as requested.  The caller is
-  responsible for any alignment and I/O width issues that the bus, device,
-  platform, or type of I/O might require.
-
-  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
-  @param[in]  Width    Signifies the width of the I/O operations.
-  @param[in]  Address  The base address of the I/O operations.  The caller is
-                       responsible for aligning the Address if required.
-  @param[in]  Count    The number of I/O operations to perform.
-  @param[out] Buffer   For read operations, the destination buffer to store
-                       the results.  For write operations, the source buffer
-                       from which to write data.
-
-  @retval EFI_SUCCESS            The data was read from or written to the device.
-  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
-  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
-  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
-                                 lack of resources
-
-**/
-EFI_STATUS
-EFIAPI
-CpuMemoryServiceRead (
-  IN  CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
-  IN  EFI_SMM_IO_WIDTH                Width,
-  IN  UINT64                          Address,
-  IN  UINTN                           Count,
-  OUT VOID                            *Buffer
-  )
-{
-  EFI_STATUS  Status;
-  UINT8       Stride;
-  UINT8       *Uint8Buffer;
-
-  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Select loop based on the width of the transfer
-  //
-  Stride = mStride[Width];
-  for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
-    if (Width == SMM_IO_UINT8) {
-      *Uint8Buffer = MmioRead8 ((UINTN)Address);
-    } else if (Width == SMM_IO_UINT16) {
-      *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
-    } else if (Width == SMM_IO_UINT32) {
-      *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
-    } else if (Width == SMM_IO_UINT64) {
-      *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
-    }
-  }
-  return EFI_SUCCESS;
-}
+#include "CpuIo2Mm.h"
 
 /**
-  Writes memory-mapped registers.
-
-  The I/O operations are carried out exactly as requested.  The caller is
-  responsible for any alignment and I/O width issues that the bus, device,
-  platform, or type of I/O might require.
-
-  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
-  @param[in]  Width    Signifies the width of the I/O operations.
-  @param[in]  Address  The base address of the I/O operations.  The caller is
-                       responsible for aligning the Address if required.
-  @param[in]  Count    The number of I/O operations to perform.
-  @param[in]  Buffer   For read operations, the destination buffer to store
-                       the results.  For write operations, the source buffer
-                       from which to write data.
-
-  @retval EFI_SUCCESS            The data was read from or written to the device.
-  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
-  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
-  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
-                                 lack of resources
-
-**/
-EFI_STATUS
-EFIAPI
-CpuMemoryServiceWrite (
-  IN CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
-  IN EFI_SMM_IO_WIDTH                Width,
-  IN UINT64                          Address,
-  IN UINTN                           Count,
-  IN VOID                            *Buffer
-  )
-{
-  EFI_STATUS  Status;
-  UINT8       Stride;
-  UINT8       *Uint8Buffer;
-
-  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Select loop based on the width of the transfer
-  //
-  Stride = mStride[Width];
-  for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
-    if (Width == SMM_IO_UINT8) {
-      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
-    } else if (Width == SMM_IO_UINT16) {
-      MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
-    } else if (Width == SMM_IO_UINT32) {
-      MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
-    } else if (Width == SMM_IO_UINT64) {
-      MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
-    }
-  }
-  return EFI_SUCCESS;
-}
-
-/**
-  Reads I/O registers.
-
-  The I/O operations are carried out exactly as requested.  The caller is
-  responsible for any alignment and I/O width issues that the bus, device,
-  platform, or type of I/O might require.
-
-  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
-  @param[in]  Width    Signifies the width of the I/O operations.
-  @param[in]  Address  The base address of the I/O operations.  The caller is
-                       responsible for aligning the Address if required.
-  @param[in]  Count    The number of I/O operations to perform.
-  @param[out] Buffer   For read operations, the destination buffer to store
-                       the results.  For write operations, the source buffer
-                       from which to write data.
-
-  @retval EFI_SUCCESS            The data was read from or written to the device.
-  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
-  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
-  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
-                                 lack of resources
-
-**/
-EFI_STATUS
-EFIAPI
-CpuIoServiceRead (
-  IN  CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
-  IN  EFI_SMM_IO_WIDTH                Width,
-  IN  UINT64                          Address,
-  IN  UINTN                           Count,
-  OUT VOID                            *Buffer
-  )
-{
-  EFI_STATUS  Status;
-  UINT8       Stride;
-  UINT8       *Uint8Buffer;
-
-  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Select loop based on the width of the transfer
-  //
-  Stride = mStride[Width];
-  for (Uint8Buffer = Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
-    if (Width == SMM_IO_UINT8) {
-      *Uint8Buffer = IoRead8 ((UINTN)Address);
-    } else if (Width == SMM_IO_UINT16) {
-      *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);
-    } else if (Width == SMM_IO_UINT32) {
-      *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Write I/O registers.
-
-  The I/O operations are carried out exactly as requested.  The caller is
-  responsible for any alignment and I/O width issues that the bus, device,
-  platform, or type of I/O might require.
-
-  @param[in]  This     The EFI_SMM_CPU_IO2_PROTOCOL instance.
-  @param[in]  Width    Signifies the width of the I/O operations.
-  @param[in]  Address  The base address of the I/O operations.  The caller is
-                       responsible for aligning the Address if required.
-  @param[in]  Count    The number of I/O operations to perform.
-  @param[in]  Buffer   For read operations, the destination buffer to store
-                       the results.  For write operations, the source buffer
-                       from which to write data.
-
-  @retval EFI_SUCCESS            The data was read from or written to the device.
-  @retval EFI_UNSUPPORTED        The Address is not valid for this system.
-  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.
-  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
-                                 lack of resources
-
-**/
-EFI_STATUS
-EFIAPI
-CpuIoServiceWrite (
-  IN CONST EFI_SMM_CPU_IO2_PROTOCOL  *This,
-  IN EFI_SMM_IO_WIDTH                Width,
-  IN UINT64                          Address,
-  IN UINTN                           Count,
-  IN VOID                            *Buffer
-  )
-{
-  EFI_STATUS  Status;
-  UINT8       Stride;
-  UINT8       *Uint8Buffer;
-
-  //
-  // Make sure the parameters are valid
-  //
-  Status = CpuIoCheckParameter (FALSE, Width, Address, Count, Buffer);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  //
-  // Select loop based on the width of the transfer
-  //
-  Stride = mStride[Width];
-  for (Uint8Buffer = (UINT8 *)Buffer; Count > 0; Address += Stride, Uint8Buffer += Stride, Count--) {
-    if (Width == SMM_IO_UINT8) {
-      IoWrite8 ((UINTN)Address, *Uint8Buffer);
-    } else if (Width == SMM_IO_UINT16) {
-      IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
-    } else if (Width == SMM_IO_UINT32) {
-      IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  The module Entry Point SmmCpuIoProtocol driver
+  The module Entry Point for Traditional MM CpuIoProtocol driver
 
   @param[in] ImageHandle  The firmware allocated handle for the EFI image.
   @param[in] SystemTable  A pointer to the EFI System Table.
@@ -385,23 +28,5 @@ SmmCpuIo2Initialize (
   IN EFI_SYSTEM_TABLE  *SystemTable
   )
 {
-  EFI_STATUS  Status;
-
-  //
-  // Copy the SMM CPU I/O Protocol instance into the System Management System Table
-  //
-  CopyMem (&gMmst->MmIo, &mSmmCpuIo2, sizeof (mSmmCpuIo2));
-
-  //
-  // Install the SMM CPU I/O Protocol into the MM protocol database
-  //
-  Status = gMmst->MmInstallProtocolInterface (
-                    &mHandle,
-                    &gEfiSmmCpuIo2ProtocolGuid,
-                    EFI_NATIVE_INTERFACE,
-                    &mSmmCpuIo2
-                    );
-  ASSERT_EFI_ERROR (Status);
-
-  return Status;
+  return CommonCpuIo2Initialize ();
 }

+ 2 - 1
UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf

@@ -24,7 +24,8 @@
 
 [Sources]
   CpuIo2Smm.c
-  CpuIo2Smm.h
+  CpuIo2Mm.c
+  CpuIo2Mm.h
 
 [Packages]
   MdePkg/MdePkg.dec