diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
index 7996c05dfe..ea77789d2a 100644
--- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
+++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
@@ -211,7 +211,10 @@
 
 [Components.IA32]
   IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+  IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
 
 [Components.X64]
   IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
-
+  IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/MemoryStausCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/MemoryStausCodeWorker.c
new file mode 100644
index 0000000000..f04a17495a
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/MemoryStausCodeWorker.c
@@ -0,0 +1,153 @@
+/** @file
+  PEI memory status code worker.
+
+  Copyright (c) 2006 - 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "StatusCodeHandlerPei.h"
+
+/**
+  Worker function to create one memory status code GUID'ed HOB,
+  using PacketIndex to identify the packet.
+
+  @param   PacketIndex    Index of records packet.
+
+  @return  Pointer to the memory status code packet.
+
+**/
+MEMORY_STATUSCODE_PACKET_HEADER *
+CreateMemoryStatusCodePacket (
+  UINT16 PacketIndex
+  )
+{
+  MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader;
+
+  //
+  // Build GUID'ed HOB with PCD defined size.
+  //
+  PacketHeader = BuildGuidHob (
+                   &gMemoryStatusCodeRecordGuid,
+                   PcdGet16 (PcdStatusCodeMemorySize) * 1024 + sizeof (MEMORY_STATUSCODE_PACKET_HEADER)
+                   );
+  ASSERT (PacketHeader != NULL);
+
+  PacketHeader->MaxRecordsNumber = (PcdGet16 (PcdStatusCodeMemorySize) * 1024) / sizeof (MEMORY_STATUSCODE_RECORD);
+  PacketHeader->PacketIndex      = PacketIndex;
+  PacketHeader->RecordIndex      = 0;
+
+  return PacketHeader;
+}
+
+/**
+  Create the first memory status code GUID'ed HOB as initialization for memory status code worker.
+
+  @retval EFI_SUCCESS  The GUID'ed HOB is created successfully.
+
+**/
+EFI_STATUS
+MemoryStatusCodeInitializeWorker (
+  VOID
+  )
+{
+  //
+  // Create first memory status code GUID'ed HOB.
+  //
+  CreateMemoryStatusCodePacket (0);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Report status code into GUID'ed HOB.
+
+  This function reports status code into GUID'ed HOB. If not all packets are full, then
+  write status code into available entry. Otherwise, create a new packet for it.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      The function always return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+MemoryStatusCodeReportWorker (
+  IN CONST  EFI_PEI_SERVICES    **PeiServices,
+  IN EFI_STATUS_CODE_TYPE       CodeType,
+  IN EFI_STATUS_CODE_VALUE      Value,
+  IN UINT32                     Instance,
+  IN CONST EFI_GUID             *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
+  )
+{
+
+  EFI_PEI_HOB_POINTERS              Hob;
+  MEMORY_STATUSCODE_PACKET_HEADER   *PacketHeader;
+  MEMORY_STATUSCODE_RECORD          *Record;
+  UINT16                            PacketIndex;
+
+  Record      = NULL;
+  PacketIndex = 0;
+
+  //
+  // Journal GUID'ed HOBs to find empty record entry. if found, then save status code in it.
+  // otherwise, create a new GUID'ed HOB.
+  //
+  Hob.Raw = GetFirstGuidHob (&gMemoryStatusCodeRecordGuid);
+  while (Hob.Raw != NULL) {
+    PacketHeader = (MEMORY_STATUSCODE_PACKET_HEADER *) GET_GUID_HOB_DATA (Hob.Guid);
+
+    //
+    // Check whether pccket is full or not.
+    //
+    if (PacketHeader->RecordIndex < PacketHeader->MaxRecordsNumber) {
+      Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1);
+      Record = &Record[PacketHeader->RecordIndex++];
+      break;
+    }
+    //
+    // Cache number of found packet in PacketIndex.
+    //
+    PacketIndex++;
+
+    Hob.Raw = GetNextGuidHob (&gMemoryStatusCodeRecordGuid, Hob.Raw);
+  }
+
+  if (Record == NULL) {
+    //
+    // No available entry found, so create new packet.
+    //
+    PacketHeader = CreateMemoryStatusCodePacket (PacketIndex);
+
+    Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1);
+    Record = &Record[PacketHeader->RecordIndex++];
+  }
+
+  Record->CodeType = CodeType;
+  Record->Instance = Instance;
+  Record->Value    = Value;
+
+  return EFI_SUCCESS;
+}
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/SerialStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/SerialStatusCodeWorker.c
new file mode 100644
index 0000000000..e6ff3d078f
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/SerialStatusCodeWorker.c
@@ -0,0 +1,152 @@
+/** @file
+  Serial I/O status code reporting worker.
+
+  Copyright (c) 2006 - 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include "StatusCodeHandlerPei.h"
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
+
+**/
+EFI_STATUS
+SerialStatusCodeReportWorker (
+  IN CONST  EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  CHAR8           *Filename;
+  CHAR8           *Description;
+  CHAR8           *Format;
+  CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  UINT32          ErrorLevel;
+  UINT32          LineNumber;
+  UINTN           CharCount;
+  BASE_LIST       Marker;
+
+  Buffer[0] = '\0';
+
+  if (Data != NULL &&
+      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+    //
+    // Print ASSERT() information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "\n\rPEI_ASSERT!: %a (%d): %a\n\r",
+                  Filename,
+                  LineNumber,
+                  Description
+                  );
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+    //
+    // Print DEBUG() information into output buffer.
+    //
+    CharCount = AsciiBSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  Format,
+                  Marker
+                  );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    //
+    // Print ERROR information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "ERROR: C%x:V%x I%x",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+
+    if (CallerId != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount - 1],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %g",
+                     CallerId
+                     );
+    }
+
+    if (Data != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount - 1],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %x",
+                     Data
+                     );
+    }
+
+    CharCount += AsciiSPrint (
+                   &Buffer[CharCount - 1],
+                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                   "\n\r"
+                   );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    //
+    // Print PROGRESS information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "PROGRESS CODE: V%x I%x\n\r",
+                  Value,
+                  Instance
+                  );
+  } else {
+    //
+    // Code type is not defined.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "Undefined: C%x:V%x I%x\n\r",
+                  CodeType,
+                  Value,
+                  Instance
+                  );
+  }
+
+  //
+  // Call SerialPort Lib function to do print.
+  //
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.c b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.c
new file mode 100644
index 0000000000..cdd532537c
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.c
@@ -0,0 +1,69 @@
+/** @file
+  Report Status Code Handler PEIM which produces general handlers and hook them
+  onto the PEI status code router.
+
+  Copyright (c) 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "StatusCodeHandlerPei.h"
+
+/**
+  Entry point of Status Code PEIM.
+  
+  This function is the entry point of this Status Code PEIM.
+  It initializes supported status code devices according to PCD settings,
+  and installs Status Code PPI.
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+StatusCodeHandlerPeiEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PEI_RSC_HANDLER_PPI     *RscHandlerPpi;
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiRscHandlerPpiGuid,
+             0,
+             NULL,
+             (VOID **) &RscHandlerPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Dispatch initialization request to sub-statuscode-devices.
+  // If enable UseSerial, then initialize serial port.
+  // if enable UseMemory, then initialize memory status code worker.
+  //
+  if (FeaturePcdGet (PcdStatusCodeUseSerial)) {
+    Status = SerialPortInitialize();
+    ASSERT_EFI_ERROR (Status);
+    Status = RscHandlerPpi->Register (SerialStatusCodeReportWorker);                     
+    ASSERT_EFI_ERROR (Status);
+  }
+  if (FeaturePcdGet (PcdStatusCodeUseMemory)) {
+    Status = MemoryStatusCodeInitializeWorker ();
+    ASSERT_EFI_ERROR (Status);
+    Status = RscHandlerPpi->Register (MemoryStatusCodeReportWorker);                     
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.h b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.h
new file mode 100644
index 0000000000..31c998bb5c
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.h
@@ -0,0 +1,117 @@
+/** @file
+  Internal include file for Status Code Handler PEIM.
+
+  Copyright (c) 2006 - 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __STATUS_CODE_HANDLER_PEI_H__
+#define __STATUS_CODE_HANDLER_PEI_H__
+
+
+#include <Ppi/ReportStatusCodeHandler.h>
+
+#include <Guid/MemoryStatusCodeRecord.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
+
+**/
+EFI_STATUS
+SerialStatusCodeReportWorker (
+  IN CONST  EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  );
+
+
+/**
+  Create the first memory status code GUID'ed HOB as initialization for memory status code worker.
+
+  @retval EFI_SUCCESS  The GUID'ed HOB is created successfully.
+
+**/
+EFI_STATUS
+MemoryStatusCodeInitializeWorker (
+  VOID
+  );
+
+/**
+  Report status code into GUID'ed HOB.
+
+  This function reports status code into GUID'ed HOB. If not all packets are full, then
+  write status code into available entry. Otherwise, create a new packet for it.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      The function always return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+MemoryStatusCodeReportWorker (
+  IN CONST  EFI_PEI_SERVICES    **PeiServices,
+  IN EFI_STATUS_CODE_TYPE       CodeType,
+  IN EFI_STATUS_CODE_VALUE      Value,
+  IN UINT32                     Instance,
+  IN CONST EFI_GUID             *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
+  );
+
+#endif
+
+
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
new file mode 100644
index 0000000000..db4ad8f176
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
@@ -0,0 +1,64 @@
+#/** @file
+#  Report Status Code Handler PEIM which produces general handlers and hook them
+#  onto the PEI status code router.
+#
+#  Copyright (c) 2009, Intel Corporation.
+#
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StatusCodeHandlerPei
+  FILE_GUID                      = 9D225237-FA01-464C-A949-BAABC02D31D0
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = StatusCodeHandlerPeiEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is only for build)
+#
+
+[Sources.common]
+  StatusCodeHandlerPei.c
+  StatusCodeHandlerPei.h
+  SerialStatusCodeWorker.c
+  MemoryStausCodeWorker.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PeiServicesLib
+  PcdLib
+  HobLib
+  SerialPortLib
+  ReportStatusCodeLib
+  PrintLib
+  DebugLib
+
+[Guids]
+  gMemoryStatusCodeRecordGuid                   ## SOMETIMES_CONSUMES ## HOB
+
+[Ppis]
+  gEfiPeiRscHandlerPpiGuid                      ## CONSUMES
+
+[FeaturePcd.common]
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial
+
+[Pcd.common]
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1|PcdStatusCodeUseMemory
+
+[Depex]
+  gEfiPeiRscHandlerPpiGuid
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/MemoryStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/MemoryStatusCodeWorker.c
new file mode 100644
index 0000000000..2d8fcadf56
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/MemoryStatusCodeWorker.c
@@ -0,0 +1,110 @@
+/** @file
+  Runtime memory status code worker.
+
+  Copyright (c) 2006 - 2009, Intel Corporation                                                         
+  All rights reserved. This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+                                                                                            
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#include "StatusCodeHandlerRuntimeDxe.h"
+
+RUNTIME_MEMORY_STATUSCODE_HEADER  *mRtMemoryStatusCodeTable;
+
+/**
+  Initialize runtime memory status code table as initialization for runtime memory status code worker
+ 
+  @retval EFI_SUCCESS  Runtime memory status code table successfully initialized.
+
+**/
+EFI_STATUS
+RtMemoryStatusCodeInitializeWorker (
+  VOID
+  )
+{
+  //
+  // Allocate runtime memory status code pool.
+  //
+  mRtMemoryStatusCodeTable = AllocateRuntimePool (
+                               sizeof (RUNTIME_MEMORY_STATUSCODE_HEADER) +
+                               PcdGet16 (PcdStatusCodeMemorySize) * 1024
+                               );
+  ASSERT (mRtMemoryStatusCodeTable != NULL);
+
+  mRtMemoryStatusCodeTable->RecordIndex      = 0;
+  mRtMemoryStatusCodeTable->NumberOfRecords  = 0;
+  mRtMemoryStatusCodeTable->MaxRecordsNumber = 
+    (PcdGet16 (PcdStatusCodeMemorySize) * 1024) / sizeof (MEMORY_STATUSCODE_RECORD);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Report status code into runtime memory. If the runtime pool is full, roll back to the 
+  first record and overwrite it.
+ 
+  @param  CodeType                Indicates the type of status code being reported.
+  @param  Value                   Describes the current status of a hardware or software entity.
+                                  This included information about the class and subclass that is used to
+                                  classify the entity as well as an operation.
+  @param  Instance                The enumeration of a hardware or software entity within
+                                  the system. Valid instance numbers start with 1.
+  @param  CallerId                This optional parameter may be used to identify the caller.
+                                  This parameter allows the status code driver to apply different rules to
+                                  different callers.
+  @param  Data                    This optional parameter may be used to pass additional data.
+ 
+  @retval EFI_SUCCESS             Status code successfully recorded in runtime memory status code table.
+
+**/
+EFI_STATUS
+RtMemoryStatusCodeReportWorker (
+  IN EFI_STATUS_CODE_TYPE               CodeType,
+  IN EFI_STATUS_CODE_VALUE              Value,
+  IN UINT32                             Instance,
+  IN EFI_GUID                           *CallerId,
+  IN EFI_STATUS_CODE_DATA               *Data OPTIONAL
+  )
+{
+  MEMORY_STATUSCODE_RECORD              *Record;
+
+  //
+  // Locate current record buffer.
+  //
+  Record = (MEMORY_STATUSCODE_RECORD *) (mRtMemoryStatusCodeTable + 1);
+  Record = &Record[mRtMemoryStatusCodeTable->RecordIndex++];
+
+  //
+  // Save status code.
+  //
+  Record->CodeType = CodeType;
+  Record->Value    = Value;
+  Record->Instance = Instance;
+
+  //
+  // If record index equals to max record number, then wrap around record index to zero.
+  //
+  // The reader of status code should compare the number of records with max records number,
+  // If it is equal to or larger than the max number, then the wrap-around had happened,
+  // so the first record is pointed by record index.
+  // If it is less then max number, index of the first record is zero.
+  //
+  mRtMemoryStatusCodeTable->NumberOfRecords++;
+  if (mRtMemoryStatusCodeTable->RecordIndex == mRtMemoryStatusCodeTable->MaxRecordsNumber) {
+    //
+    // Wrap around record index.
+    //
+    mRtMemoryStatusCodeTable->RecordIndex = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/SerialStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/SerialStatusCodeWorker.c
new file mode 100644
index 0000000000..879eec3bc7
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/SerialStatusCodeWorker.c
@@ -0,0 +1,148 @@
+/** @file
+  Serial I/O status code reporting worker.
+
+  Copyright (c) 2006 - 2009, Intel Corporation                                                         
+  All rights reserved. This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+                                                                                            
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#include "StatusCodeHandlerRuntimeDxe.h"
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
+ 
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or software entity.
+                           This included information about the class and subclass that is used to
+                           classify the entity as well as an operation.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
+  @retval EFI_DEVICE_ERROR EFI serial device cannot work after ExitBootService() is called.
+  @retval EFI_DEVICE_ERROR EFI serial device cannot work with TPL higher than TPL_CALLBACK.
+
+**/
+EFI_STATUS
+SerialStatusCodeReportWorker (
+  IN EFI_STATUS_CODE_TYPE     CodeType,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 *CallerId,
+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  CHAR8           *Filename;
+  CHAR8           *Description;
+  CHAR8           *Format;
+  CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+  UINT32          ErrorLevel;
+  UINT32          LineNumber;
+  UINTN           CharCount;
+  BASE_LIST       Marker;
+
+  Buffer[0] = '\0';
+
+  if (Data != NULL &&
+      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+    //
+    // Print ASSERT() information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer,
+                  sizeof (Buffer),
+                  "\n\rDXE_ASSERT!: %a (%d): %a\n\r",
+                  Filename,
+                  LineNumber,
+                  Description
+                  );
+  } else if (Data != NULL &&
+             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+    //
+    // Print DEBUG() information into output buffer.
+    //
+    CharCount = AsciiBSPrint (
+                  Buffer, 
+                  sizeof (Buffer), 
+                  Format, 
+                  Marker
+                  );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    //
+    // Print ERROR information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer, 
+                  sizeof (Buffer), 
+                  "ERROR: C%x:V%x I%x", 
+                  CodeType, 
+                  Value, 
+                  Instance
+                  );
+   
+    if (CallerId != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount - 1],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %g",
+                     CallerId
+                     );
+    }
+
+    if (Data != NULL) {
+      CharCount += AsciiSPrint (
+                     &Buffer[CharCount - 1],
+                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                     " %x",
+                     Data
+                     );
+    }
+
+    CharCount += AsciiSPrint (
+                   &Buffer[CharCount - 1],
+                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
+                   "\n\r"
+                   );
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    //
+    // Print PROGRESS information into output buffer.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer, 
+                  sizeof (Buffer), 
+                  "PROGRESS CODE: V%x I%x\n\r", 
+                  Value, 
+                  Instance
+                  );
+  } else {
+    //
+    // Code type is not defined.
+    //
+    CharCount = AsciiSPrint (
+                  Buffer, 
+                  sizeof (Buffer), 
+                  "Undefined: C%x:V%x I%x\n\r", 
+                  CodeType, 
+                  Value, 
+                  Instance
+                  );
+  }
+
+  //
+  // Call SerialPort Lib function to do print.
+  //
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+  return EFI_SUCCESS;
+}
+
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.c b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.c
new file mode 100644
index 0000000000..497afaa5dc
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.c
@@ -0,0 +1,222 @@
+/** @file
+  Status Code Handler Driver which produces general handlers and hook them
+  onto the DXE status code router.
+
+  Copyright (c) 2006 - 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "StatusCodeHandlerRuntimeDxe.h"
+
+EFI_EVENT                 mVirtualAddressChangeEvent = NULL;
+EFI_EVENT                 mExitBootServicesEvent     = NULL;
+EFI_RSC_HANDLER_PROTOCOL  *mRscHandlerProtocol       = NULL;
+
+/**
+  Unregister status code callback functions only available at boot time from
+  report status code router when exiting boot services.
+
+  @param  Event         Event whose notification function is being invoked.
+  @param  Context       Pointer to the notification function's context, which is
+                        always zero in current implementation.
+
+**/
+VOID
+EFIAPI
+UnregisterBootTimeHandlers (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  if (FeaturePcdGet (PcdStatusCodeUseSerial)) {
+    mRscHandlerProtocol->Unregister (SerialStatusCodeReportWorker);
+  }
+}
+
+/**
+  Virtual address change notification call back. It converts global pointer
+  to virtual address.
+
+  @param  Event         Event whose notification function is being invoked.
+  @param  Context       Pointer to the notification function's context, which is
+                        always zero in current implementation.
+
+**/
+VOID
+EFIAPI
+VirtualAddressChangeCallBack (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  //
+  // Convert memory status code table to virtual address;
+  //
+  EfiConvertPointer (
+    0,
+    (VOID **) &mRtMemoryStatusCodeTable
+    );
+}
+
+/**
+  Dispatch initialization request to sub status code devices based on 
+  customized feature flags.
+ 
+**/
+VOID
+InitializationDispatcherWorker (
+  VOID
+  )
+{
+  EFI_PEI_HOB_POINTERS              Hob;
+  EFI_STATUS                        Status;
+  MEMORY_STATUSCODE_PACKET_HEADER   *PacketHeader;
+  MEMORY_STATUSCODE_RECORD          *Record;
+  UINTN                             ExpectedPacketIndex;
+  UINTN                             Index;
+  VOID                              *HobStart;
+
+  //
+  // If enable UseSerial, then initialize serial port.
+  // if enable UseRuntimeMemory, then initialize runtime memory status code worker.
+  //
+  if (FeaturePcdGet (PcdStatusCodeUseSerial)) {
+    //
+    // Call Serial Port Lib API to initialize serial port.
+    //
+    Status = SerialPortInitialize ();
+    ASSERT_EFI_ERROR (Status);
+  }
+  if (FeaturePcdGet (PcdStatusCodeUseMemory)) {
+    Status = RtMemoryStatusCodeInitializeWorker ();
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  //
+  // Replay Status code which saved in GUID'ed HOB to all supported devices. 
+  //
+  if (FeaturePcdGet (PcdStatusCodeReplayIn)) {
+    // 
+    // Journal GUID'ed HOBs to find all record entry, if found, 
+    // then output record to support replay device.
+    //
+    ExpectedPacketIndex = 0;
+    Hob.Raw   = GetFirstGuidHob (&gMemoryStatusCodeRecordGuid);
+    HobStart  = Hob.Raw;
+    while (Hob.Raw != NULL) {
+      PacketHeader = (MEMORY_STATUSCODE_PACKET_HEADER *) GET_GUID_HOB_DATA (Hob.Guid);
+      if (PacketHeader->PacketIndex == ExpectedPacketIndex) {
+        Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1);
+        for (Index = 0; Index < PacketHeader->RecordIndex; Index++) {
+          //
+          // Dispatch records to devices based on feature flag.
+          //
+          if (FeaturePcdGet (PcdStatusCodeUseSerial)) {
+            SerialStatusCodeReportWorker (
+              Record[Index].CodeType,
+              Record[Index].Value,
+              Record[Index].Instance,
+              NULL,
+              NULL
+              );
+          }
+          if (FeaturePcdGet (PcdStatusCodeUseMemory)) {
+            RtMemoryStatusCodeReportWorker (
+              Record[Index].CodeType,
+              Record[Index].Value,
+              Record[Index].Instance,
+              NULL,
+              NULL
+              );
+          }
+        }
+        ExpectedPacketIndex++;
+  
+        //
+        // See whether there is gap of packet or not
+        //
+        if (HobStart != NULL) {
+          HobStart  = NULL;
+          Hob.Raw   = HobStart;
+          continue;
+        }
+      } else if (HobStart != NULL) {
+        //
+        // Cache the found packet for improve the performance
+        //
+        HobStart = Hob.Raw;
+      }
+  
+      Hob.Raw = GetNextGuidHob (&gMemoryStatusCodeRecordGuid, Hob.Raw);
+    }
+  }
+}
+
+/**
+  Entry point of DXE Status Code Driver.
+
+  This function is the entry point of this DXE Status Code Driver.
+  It initializes registers status code handlers, and registers event for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+  @param  ImageHandle       The firmware allocated handle for the EFI image.
+  @param  SystemTable       A pointer to the EFI System Table.
+  
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+StatusCodeHandlerRuntimeDxeEntry (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiRscHandlerProtocolGuid,
+                  NULL,
+                  (VOID **) &mRscHandlerProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Dispatch initialization request to supported devices
+  //
+  InitializationDispatcherWorker ();
+
+  if (FeaturePcdGet (PcdStatusCodeUseSerial)) {
+    mRscHandlerProtocol->Register (SerialStatusCodeReportWorker, TPL_HIGH_LEVEL);
+  }
+  if (FeaturePcdGet (PcdStatusCodeUseMemory)) {
+    mRscHandlerProtocol->Register (RtMemoryStatusCodeReportWorker, TPL_HIGH_LEVEL);
+  }
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UnregisterBootTimeHandlers,
+                  NULL,
+                  &gEfiEventExitBootServicesGuid,
+                  &mExitBootServicesEvent
+                  );
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  VirtualAddressChangeCallBack,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &mVirtualAddressChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.h b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.h
new file mode 100644
index 0000000000..9986f1140f
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.h
@@ -0,0 +1,126 @@
+/** @file
+  Internal include file for Status Code Handler Driver.
+
+  Copyright (c) 2006 - 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __STATUS_CODE_HANDLER_RUNTIME_DXE_H__
+#define __STATUS_CODE_HANDLER_RUNTIME_DXE_H__
+
+#include <Protocol/ReportStatusCodeHandler.h>
+
+#include <Guid/MemoryStatusCodeRecord.h>
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Guid/StatusCodeDataTypeDebug.h>
+#include <Guid/EventGroup.h>
+
+#include <Library/SynchronizationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/SerialPortLib.h>
+
+//
+// Runtime memory status code worker definition
+//
+typedef struct {
+  UINT32   RecordIndex;
+  UINT32   NumberOfRecords;
+  UINT32   MaxRecordsNumber;
+} RUNTIME_MEMORY_STATUSCODE_HEADER;
+
+extern RUNTIME_MEMORY_STATUSCODE_HEADER  *mRtMemoryStatusCodeTable;
+
+/**
+  Locates Serial I/O Protocol as initialization for serial status code worker.
+ 
+  @retval EFI_SUCCESS  Serial I/O Protocol is successfully located.
+
+**/
+EFI_STATUS
+EfiSerialStatusCodeInitializeWorker (
+  VOID
+  );
+
+
+/**
+  Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
+ 
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or software entity.
+                           This included information about the class and subclass that is used to
+                           classify the entity as well as an operation.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
+  @retval EFI_DEVICE_ERROR EFI serial device cannot work after ExitBootService() is called.
+  @retval EFI_DEVICE_ERROR EFI serial device cannot work with TPL higher than TPL_CALLBACK.
+
+**/
+EFI_STATUS
+SerialStatusCodeReportWorker (
+  IN EFI_STATUS_CODE_TYPE     CodeType,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 *CallerId,
+  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  );
+
+/**
+  Initialize runtime memory status code table as initialization for runtime memory status code worker
+ 
+  @retval EFI_SUCCESS  Runtime memory status code table successfully initialized.
+
+**/
+EFI_STATUS
+RtMemoryStatusCodeInitializeWorker (
+  VOID
+  );
+
+/**
+  Report status code into runtime memory. If the runtime pool is full, roll back to the 
+  first record and overwrite it.
+ 
+  @param  CodeType                Indicates the type of status code being reported.
+  @param  Value                   Describes the current status of a hardware or software entity.
+                                  This included information about the class and subclass that is used to
+                                  classify the entity as well as an operation.
+  @param  Instance                The enumeration of a hardware or software entity within
+                                  the system. Valid instance numbers start with 1.
+  @param  CallerId                This optional parameter may be used to identify the caller.
+                                  This parameter allows the status code driver to apply different rules to
+                                  different callers.
+  @param  Data                    This optional parameter may be used to pass additional data.
+ 
+  @retval EFI_SUCCESS             Status code successfully recorded in runtime memory status code table.
+
+**/
+EFI_STATUS
+RtMemoryStatusCodeReportWorker (
+  IN EFI_STATUS_CODE_TYPE               CodeType,
+  IN EFI_STATUS_CODE_VALUE              Value,
+  IN UINT32                             Instance,
+  IN EFI_GUID                           *CallerId,
+  IN EFI_STATUS_CODE_DATA               *Data OPTIONAL
+  );
+
+#endif
diff --git a/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
new file mode 100644
index 0000000000..a69a0dc248
--- /dev/null
+++ b/IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
@@ -0,0 +1,71 @@
+#/** @file
+#  Status Code Handler Driver which produces general handlers and hook them
+#  onto the DXE status code router.
+#
+#  Copyright (c) 2006 - 2009, Intel Corporation.
+#
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StatusCodeHandlerRuntimeDxe
+  FILE_GUID                      = 6C2004EF-4E0E-4BE4-B14C-340EB4AA5891
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  ENTRY_POINT                    = StatusCodeHandlerRuntimeDxeEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+  StatusCodeHandlerRuntimeDxe.c
+  StatusCodeHandlerRuntimeDxe.h
+  SerialStatusCodeWorker.c
+  MemoryStatusCodeWorker.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  SerialPortLib
+  UefiRuntimeLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  HobLib
+  PcdLib
+  PrintLib
+  ReportStatusCodeLib
+  DebugLib
+  SynchronizationLib
+
+[Guids]
+  gEfiStatusCodeDataTypeDebugGuid               ## SOMETIMES_CONSUMES (Needed if Data Hub is supported for status code.)
+  gMemoryStatusCodeRecordGuid                   ## CONSUMES ## HOB
+  gEfiEventVirtualAddressChangeGuid             ## CONSUMES ## Event
+  gEfiEventExitBootServicesGuid                 ## CONSUMES ## Event
+
+[Protocols]
+  gEfiRscHandlerProtocolGuid                    ## CONSUMES
+
+[FeaturePcd]
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeReplayIn
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial
+
+[Pcd]
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize |128| PcdStatusCodeUseMemory
+
+[Depex]
+  gEfiRscHandlerProtocolGuid
diff --git a/MdeModulePkg/Include/Guid/StatusCodeCallbackGuid.h b/MdeModulePkg/Include/Guid/StatusCodeCallbackGuid.h
new file mode 100644
index 0000000000..ab4a8cbe27
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/StatusCodeCallbackGuid.h
@@ -0,0 +1,26 @@
+/** @file
+  GUID used to identify HOB for pointers to callback functios registered on
+  PEI report status code router.
+  
+  Copyright (c) 2009, Intel Corporation                                                         
+  All rights reserved. This program and the accompanying materials                          
+  are licensed and made available under the terms and conditions of the BSD License         
+  which accompanies this distribution.  The full text of the license may be found at        
+  http://opensource.org/licenses/bsd-license.php                                            
+                                                                                            
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+**/
+
+#ifndef __STATUS_CODE_CALLBACK_H__
+#define __STATUS_CODE_CALLBACK_H__
+
+#define STATUS_CODE_CALLBACK_GUID \
+  { \
+    0xe701458c, 0x4900, 0x4ca5, {0xb7, 0x72, 0x3d, 0x37, 0x94, 0x9f, 0x79, 0x27} \
+  }
+
+extern EFI_GUID gStatusCodeCallbackGuid;
+
+#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index d3ca875c22..4cbafb42c4 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -124,6 +124,9 @@
   ## Include/Guid/NicIp4ConfigNvData.h
   gEfiNicIp4ConfigVariableGuid   = {0xd8944553, 0xc4dd, 0x41f4, { 0x9b, 0x30, 0xe1, 0x39, 0x7c, 0xfb, 0x26, 0x7b }}
 
+  ## Include/Guid/StatusCodeCallbackGuid.h
+  gStatusCodeCallbackGuid   = {0xe701458c, 0x4900, 0x4ca5, {0xb7, 0x72, 0x3d, 0x37, 0x94, 0x9f, 0x79, 0x27}}
+
 [Protocols.common]
   ## Load File protocol provides capability to load and unload EFI image into memory and execute it.
   #  Include/Protocol/LoadPe32Image.h
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 4d1d941848..c6773224eb 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -305,6 +305,10 @@
   MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
   MdeModulePkg/Universal/PCD/Pei/Pcd.inf
   MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+
   MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
   MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
   MdeModulePkg/Application/VariableInfo/VariableInfo.inf
diff --git a/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.c b/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.c
new file mode 100644
index 0000000000..eb5b490d1b
--- /dev/null
+++ b/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.c
@@ -0,0 +1,268 @@
+/** @file
+  Report Status Code Router PEIM which produces Report Stataus Code Handler PPI and Status Code PPI.
+
+  Copyright (c) 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "ReportStatusCodeRouterPei.h"
+
+EFI_PEI_RSC_HANDLER_PPI     mRscHandlerPpi = {
+  Register,
+  Unregister
+  };
+
+EFI_PEI_PROGRESS_CODE_PPI     mStatusCodePpi = {
+  ReportDispatcher
+  };
+
+EFI_PEI_PPI_DESCRIPTOR   mStatusCodePpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gEfiPeiRscHandlerPpiGuid,
+    &mRscHandlerPpi
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiStatusCodePpiGuid,
+    &mStatusCodePpi
+  }
+};
+
+/**
+  Worker function to create one memory status code GUID'ed HOB,
+  using PacketIndex to identify the packet.
+
+  @param   PacketIndex    Index of records packet.
+
+  @return  Pointer to the memory status code packet.
+
+**/
+UINTN *
+CreateRscHandlerCallbackPacket (
+  VOID
+  )
+{
+  UINTN  *NumberOfEntries;
+
+  //
+  // Build GUID'ed HOB with PCD defined size.
+  //
+  NumberOfEntries = BuildGuidHob (
+                      &gStatusCodeCallbackGuid,
+                      sizeof (EFI_PEI_RSC_HANDLER_CALLBACK) * 64 + sizeof (UINTN)
+                      );
+  ASSERT (NumberOfEntries != NULL);
+
+  *NumberOfEntries = 0;
+
+  return NumberOfEntries;
+}
+
+/**
+  Register the callback function for ReportStatusCode() notification.
+  
+  When this function is called the function pointer is added to an internal list and any future calls to
+  ReportStatusCode() will be forwarded to the Callback function.
+
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is called
+                                when a call to ReportStatusCode() occurs.
+                        
+  @retval EFI_SUCCESS           Function was successfully registered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_OUT_OF_RESOURCES  The internal buffer ran out of space. No more functions can be
+                                registered.
+  @retval EFI_ALREADY_STARTED   The function was already registered. It can't be registered again.
+  
+**/
+EFI_STATUS
+EFIAPI
+Register (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  )
+{
+  EFI_PEI_HOB_POINTERS          Hob;
+  EFI_PEI_RSC_HANDLER_CALLBACK  *CallbackEntry;
+  UINTN                         *NumberOfEntries;
+  UINTN                         Index;
+  UINTN                         *FreePacket;
+
+  if (Callback == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Hob.Raw  = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+  FreePacket = NULL;
+  while (Hob.Raw != NULL) {
+    NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+    CallbackEntry   = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+    if (*NumberOfEntries < 64) {
+      FreePacket = NumberOfEntries;
+    }
+    for (Index = 0; Index < *NumberOfEntries; Index++) {
+      if (CallbackEntry[Index] == Callback) {
+        //
+        // If the function was already registered. It can't be registered again.
+        //
+        return EFI_ALREADY_STARTED;
+      }
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+    Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw);
+  }
+
+  if (FreePacket == NULL) {
+    FreePacket = CreateRscHandlerCallbackPacket();
+  }
+
+  CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (FreePacket + 1);
+  CallbackEntry[*FreePacket] = Callback;
+  *FreePacket += 1;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Remove a previously registered callback function from the notification list.
+  
+  ReportStatusCode() messages will no longer be forwarded to the Callback function.
+  
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is to be
+                                unregistered.
+
+  @retval EFI_SUCCESS           The function was successfully unregistered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_NOT_FOUND         The callback function was not found to be unregistered.
+                        
+**/
+EFI_STATUS
+EFIAPI
+Unregister (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  )
+{
+  EFI_PEI_HOB_POINTERS            Hob;
+  EFI_PEI_RSC_HANDLER_CALLBACK    *CallbackEntry;
+  UINTN                           *NumberOfEntries;
+  UINTN                           Index;
+
+  if (Callback == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Hob.Raw  = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+  while (Hob.Raw != NULL) {
+    NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+    CallbackEntry   = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+    for (Index = 0; Index < *NumberOfEntries; Index++) {
+      if (CallbackEntry[Index] == Callback) {
+        CallbackEntry[Index] = CallbackEntry[*NumberOfEntries - 1];
+        *NumberOfEntries -= 1;
+        return EFI_SUCCESS;
+      }
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+    Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw);
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Publishes an interface that allows PEIMs to report status codes.
+
+  This function implements EFI_PEI_PROGRESS_CODE_PPI.ReportStatusCode().
+  It publishes an interface that allows PEIMs to report status codes.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ReportDispatcher (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId OPTIONAL,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  )
+{
+  EFI_PEI_HOB_POINTERS            Hob;
+  EFI_PEI_RSC_HANDLER_CALLBACK    *CallbackEntry;
+  UINTN                           *NumberOfEntries;
+  UINTN                           Index;
+
+  Hob.Raw  = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+  while (Hob.Raw != NULL) {
+    NumberOfEntries = GET_GUID_HOB_DATA (Hob);
+    CallbackEntry   = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+    for (Index = 0; Index < *NumberOfEntries; Index++) {
+      CallbackEntry[Index](
+        PeiServices,
+        CodeType,
+        Value,
+        Instance,
+        CallerId,
+        Data
+        );
+    }
+    Hob.Raw = GET_NEXT_HOB (Hob);
+    Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Entry point of Status Code PEIM.
+  
+  This function is the entry point of this Status Code Router PEIM.
+  It produces Report Stataus Code Handler PPI and Status Code PPI.
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GenericStatusCodePeiEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS     Status;
+
+  CreateRscHandlerCallbackPacket ();
+
+  Status = PeiServicesInstallPpi (mStatusCodePpiList);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.h b/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.h
new file mode 100644
index 0000000000..2fd2c7b591
--- /dev/null
+++ b/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.h
@@ -0,0 +1,109 @@
+/** @file
+  Internal include file for Report Status Code Router PEIM.
+
+  Copyright (c) 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PEI_REPORT_STATUS_CODE_ROUTER_H__
+#define __PEI_REPORT_STATUS_CODE_ROUTER_H__
+
+
+#include <Ppi/ReportStatusCodeHandler.h>
+#include <Ppi/StatusCode.h>
+
+#include <Guid/StatusCodeCallbackGuid.h>
+
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+
+/**
+  Register the callback function for ReportStatusCode() notification.
+  
+  When this function is called the function pointer is added to an internal list and any future calls to
+  ReportStatusCode() will be forwarded to the Callback function.
+
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is called
+                                when a call to ReportStatusCode() occurs.
+                        
+  @retval EFI_SUCCESS           Function was successfully registered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_OUT_OF_RESOURCES  The internal buffer ran out of space. No more functions can be
+                                registered.
+  @retval EFI_ALREADY_STARTED   The function was already registered. It can't be registered again.
+
+**/
+EFI_STATUS
+EFIAPI
+Register (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  );
+
+/**
+  Remove a previously registered callback function from the notification list.
+  
+  ReportStatusCode() messages will no longer be forwarded to the Callback function.
+  
+  @param[in] Callback           A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is to be
+                                unregistered.
+
+  @retval EFI_SUCCESS           The function was successfully unregistered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_NOT_FOUND         The callback function was not found to be unregistered.
+                        
+**/
+EFI_STATUS
+EFIAPI
+Unregister (
+  IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+  );
+
+/**
+  Publishes an interface that allows PEIMs to report status codes.
+
+  This function implements EFI_PEI_PROGRESS_CODE_PPI.ReportStatusCode().
+  It publishes an interface that allows PEIMs to report status codes.
+
+  @param  PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param  CodeType         Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or
+                           software entity. This includes information about the class and
+                           subclass that is used to classify the entity as well as an operation.
+                           For progress codes, the operation is the current activity.
+                           For error codes, it is the exception.For debug codes,it is not defined at this time.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. A system may contain multiple entities that match a class/subclass
+                           pairing. The instance differentiates between them. An instance of 0 indicates
+                           that instance information is unavailable, not meaningful, or not relevant.
+                           Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS      The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+ReportDispatcher (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN EFI_STATUS_CODE_TYPE           CodeType,
+  IN EFI_STATUS_CODE_VALUE          Value,
+  IN UINT32                         Instance,
+  IN CONST EFI_GUID                 *CallerId OPTIONAL,
+  IN CONST EFI_STATUS_CODE_DATA     *Data OPTIONAL
+  );
+
+#endif
+
+
diff --git a/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf b/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
new file mode 100644
index 0000000000..f87d2d8753
--- /dev/null
+++ b/MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
@@ -0,0 +1,53 @@
+#/** @file
+#  Report Status Code Router PEIM which produces Report Stataus Code Handler PPI and Status Code PPI.
+#
+#  Copyright (c) 2009, Intel Corporation.
+#
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ReportStatusCodeRouterPei
+  FILE_GUID                      = A3610442-E69F-4DF3-82CA-2360C4031A23
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = GenericStatusCodePeiEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC (EBC is only for build)
+#
+
+[Sources.common]
+  ReportStatusCodeRouterPei.c
+  ReportStatusCodeRouterPei.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PeiServicesLib
+  DebugLib
+  HobLib
+
+[Guids]
+  gStatusCodeCallbackGuid                       ## CONSUMES ## HOB
+
+[Ppis]
+  gEfiPeiRscHandlerPpiGuid                      ## PRODUCES
+  gEfiPeiStatusCodePpiGuid                      ## PRODUCES
+
+
+[Depex]
+  TRUE
diff --git a/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c
new file mode 100644
index 0000000000..aa2fa100f0
--- /dev/null
+++ b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c
@@ -0,0 +1,334 @@
+/** @file
+  Report Status Code Router Driver which produces Report Stataus Code Handler Protocol
+  and Status Code Runtime Protocol.
+
+  Copyright (c) 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "ReportStatusCodeRouterRuntimeDxe.h"
+
+EFI_HANDLE   mHandle                    = NULL;
+LIST_ENTRY   mCallbackListHead          = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackListHead);
+EFI_EVENT    mVirtualAddressChangeEvent = NULL;
+
+//
+// Report operation nest status.
+// If it is set, then the report operation has nested.
+//
+UINT32       mStatusCodeNestStatus = 0;
+
+EFI_STATUS_CODE_PROTOCOL  mStatusCodeProtocol  = {
+  ReportDispatcher
+};
+
+EFI_RSC_HANDLER_PROTOCOL  mRscHandlerProtocol = {
+  Register,
+  Unregister
+  };
+
+/**
+  Register the callback function for ReportStatusCode() notification.
+  
+  When this function is called the function pointer is added to an internal list and any future calls to
+  ReportStatusCode() will be forwarded to the Callback function. During the bootservices,
+  this is the callback for which this service can be invoked. The report status code router
+  will create an event such that the callback function is only invoked at the TPL for which it was
+  registered. The entity that registers for the callback should also register for an event upon
+  generation of exit boot services and invoke the unregister service.
+  If the handler does not have a TPL dependency, it should register for a callback at TPL high. The
+  router infrastructure will support making callbacks at runtime, but the caller for runtime invocation
+  must meet the following criteria:
+  1. must be a runtime driver type so that its memory is not reclaimed
+  2. not unregister at exit boot services so that the router will still have its callback address
+  3. the caller must be self-contained (eg. Not call out into any boot-service interfaces) and be
+  runtime safe, in general.
+  
+  @param[in] Callback   A pointer to a function of type EFI_RSC_HANDLER_CALLBACK that is called when
+                        a call to ReportStatusCode() occurs.
+  @param[in] Tpl        TPL at which callback can be safely invoked.   
+  
+  @retval  EFI_SUCCESS              Function was successfully registered.
+  @retval  EFI_INVALID_PARAMETER    The callback function was NULL.
+  @retval  EFI_OUT_OF_RESOURCES     The internal buffer ran out of space. No more functions can be
+                                    registered.
+  @retval  EFI_ALREADY_STARTED      The function was already registered. It can't be registered again.
+
+**/
+EFI_STATUS
+EFIAPI
+Register (
+  IN EFI_RSC_HANDLER_CALLBACK   Callback,
+  IN EFI_TPL                    Tpl
+  )
+{
+  LIST_ENTRY                    *Link;
+  RSC_HANDLER_CALLBACK_ENTRY    *CallbackEntry;
+
+  if (Callback == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  for (Link = GetFirstNode (&mCallbackListHead); !IsNull (&mCallbackListHead, Link); Link = GetNextNode (&mCallbackListHead, Link)) {
+    CallbackEntry = CR (Link, RSC_HANDLER_CALLBACK_ENTRY, Node, RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE);
+    if (CallbackEntry->RscHandlerCallback == Callback) {
+      //
+      // If the function was already registered. It can't be registered again.
+      //
+      return EFI_ALREADY_STARTED;
+    }
+  }
+
+  CallbackEntry = AllocatePool (sizeof (RSC_HANDLER_CALLBACK_ENTRY));
+  ASSERT (CallbackEntry != NULL);
+
+  CallbackEntry->Signature          = RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE;
+  CallbackEntry->RscHandlerCallback = Callback;
+  CallbackEntry->Tpl                = Tpl;
+
+  InsertTailList (&mCallbackListHead, &CallbackEntry->Node);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Remove a previously registered callback function from the notification list.
+  
+  A callback function must be unregistered before it is deallocated. It is important that any registered
+  callbacks that are not runtime complaint be unregistered when ExitBootServices() is called.
+  
+  @param[in]  Callback  A pointer to a function of type EFI_RSC_HANDLER_CALLBACK that is to be
+                        unregistered.
+                        
+  @retval EFI_SUCCESS           The function was successfully unregistered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_NOT_FOUND         The callback function was not found to be unregistered.
+
+**/
+EFI_STATUS
+EFIAPI
+Unregister (
+  IN EFI_RSC_HANDLER_CALLBACK Callback
+  )
+{
+  LIST_ENTRY                    *Link;
+  RSC_HANDLER_CALLBACK_ENTRY    *CallbackEntry;
+
+  if (Callback == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  for (Link = GetFirstNode (&mCallbackListHead); !IsNull (&mCallbackListHead, Link); Link = GetNextNode (&mCallbackListHead, Link)) {
+    CallbackEntry = CR (Link, RSC_HANDLER_CALLBACK_ENTRY, Node, RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE);
+    if (CallbackEntry->RscHandlerCallback == Callback) {
+      //
+      // If the function is found in list, delete it and return.
+      //
+      RemoveEntryList (&CallbackEntry->Node);
+      FreePool (CallbackEntry);
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Event callback function to invoke status code handler in list.
+
+  @param  Event         Event whose notification function is being invoked.
+  @param  Context       Pointer to the notification function's context, which is
+                        always zero in current implementation.
+
+**/
+VOID
+EFIAPI
+RscHandlerNotification (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  RSC_EVENT_CONTEXT  *RscContext;
+
+  RscContext = (RSC_EVENT_CONTEXT *) Context;
+
+  RscContext->RscHandlerCallback (
+                RscContext->Type,
+                RscContext->Value,
+                RscContext->Instance,
+                RscContext->CallerId,
+                RscContext->Data
+                );
+}
+
+/**
+  Provides an interface that a software module can call to report a status code.
+
+  @param  Type             Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or software entity.
+                           This included information about the class and subclass that is used to
+                           classify the entity as well as an operation.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS           The function completed successfully
+  @retval EFI_DEVICE_ERROR      The function should not be completed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+ReportDispatcher (
+  IN EFI_STATUS_CODE_TYPE     Type,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 *CallerId  OPTIONAL,
+  IN EFI_STATUS_CODE_DATA     *Data      OPTIONAL
+  )
+{
+  LIST_ENTRY                    *Link;
+  RSC_HANDLER_CALLBACK_ENTRY    *CallbackEntry;
+  RSC_EVENT_CONTEXT             Context;
+  EFI_EVENT                     Event;
+  EFI_STATUS                    Status;
+
+  //
+  // Use atom operation to avoid the reentant of report.
+  // If current status is not zero, then the function is reentrancy.
+  //
+  if (InterlockedCompareExchange32 (&mStatusCodeNestStatus, 0, 1) == 1) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  for (Link = GetFirstNode (&mCallbackListHead); !IsNull (&mCallbackListHead, Link); Link = GetNextNode (&mCallbackListHead, Link)) {
+    CallbackEntry = CR (Link, RSC_HANDLER_CALLBACK_ENTRY, Node, RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE);
+
+    if ((CallbackEntry->Tpl == TPL_HIGH_LEVEL) || EfiAtRuntime ()) {
+      CallbackEntry->RscHandlerCallback (
+                       Type,
+                       Value,
+                       Instance,
+                       CallerId,
+                       Data
+                       );
+      continue;
+    }
+
+    Context.RscHandlerCallback = CallbackEntry->RscHandlerCallback;
+    Context.Type               = Type;
+    Context.Value              = Value;
+    Context.Instance           = Instance;
+    Context.CallerId           = CallerId;
+    Context.Data               = Data;
+
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL,
+                    CallbackEntry->Tpl,
+                    RscHandlerNotification,
+                    &Context,
+                    &Event
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    Status = gBS->SignalEvent (Event);
+    ASSERT_EFI_ERROR (Status);
+
+    Status = gBS->CloseEvent (Event);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  //
+  // Restore the nest status of report
+  //
+  InterlockedCompareExchange32 (&mStatusCodeNestStatus, 1, 0);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Virtual address change notification call back. It converts global pointer
+  to virtual address.
+
+  @param  Event         Event whose notification function is being invoked.
+  @param  Context       Pointer to the notification function's context, which is
+                        always zero in current implementation.
+
+**/
+VOID
+EFIAPI
+VirtualAddressChangeCallBack (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  EFI_STATUS					Status;
+  LIST_ENTRY                    *Link;
+  RSC_HANDLER_CALLBACK_ENTRY    *CallbackEntry;
+
+  for (Link = GetFirstNode (&mCallbackListHead); !IsNull (&mCallbackListHead, Link); Link = GetNextNode (&mCallbackListHead, Link)) {
+    CallbackEntry = CR (Link, RSC_HANDLER_CALLBACK_ENTRY, Node, RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE);
+    Status = EfiConvertFunctionPointer (0, (VOID **) &CallbackEntry->RscHandlerCallback);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = EfiConvertList (
+             0,
+             &mCallbackListHead
+             );
+  ASSERT_EFI_ERROR (Status);
+}
+
+/**
+  Entry point of Generic Status Code Driver.
+
+  This function is the entry point of this Generic Status Code Driver.
+  It installs eport Stataus Code Handler Protocol  and Status Code Runtime Protocol,
+  and registers event for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+
+  @param  ImageHandle       The firmware allocated handle for the EFI image.
+  @param  SystemTable       A pointer to the EFI System Table.
+  
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+GenericStatusCodeRuntimeDxeEntry (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS     Status;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mHandle,
+                  &gEfiRscHandlerProtocolGuid,
+                  &mRscHandlerProtocol,
+                  &gEfiStatusCodeRuntimeProtocolGuid,
+                  &mStatusCodeProtocol,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  VirtualAddressChangeCallBack,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &mVirtualAddressChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.h b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.h
new file mode 100644
index 0000000000..a87ad5fdb8
--- /dev/null
+++ b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.h
@@ -0,0 +1,137 @@
+/** @file
+  Internal include file for Report Status Code Router Driver.
+
+  Copyright (c) 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __REPORT_STATUS_CODE_ROUTER_RUNTIME_DXE_H__
+#define __REPORT_STATUS_CODE_ROUTER_RUNTIME_DXE_H__
+
+
+#include <Protocol/ReportStatusCodeHandler.h>
+#include <Protocol/StatusCode.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Library/BaseLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/HobLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeLib.h>
+
+#define RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE  SIGNATURE_32 ('r', 'h', 'c', 'e')
+
+typedef struct {
+  UINTN                     Signature;
+  EFI_RSC_HANDLER_CALLBACK  RscHandlerCallback;
+  EFI_TPL                   Tpl;
+  LIST_ENTRY                Node;
+} RSC_HANDLER_CALLBACK_ENTRY;
+
+typedef struct {
+  EFI_RSC_HANDLER_CALLBACK RscHandlerCallback;
+  EFI_STATUS_CODE_TYPE     Type;
+  EFI_STATUS_CODE_VALUE    Value;
+  UINT32                   Instance;
+  EFI_GUID                 *CallerId;
+  EFI_STATUS_CODE_DATA     *Data;
+} RSC_EVENT_CONTEXT;
+
+/**
+  Register the callback function for ReportStatusCode() notification.
+  
+  When this function is called the function pointer is added to an internal list and any future calls to
+  ReportStatusCode() will be forwarded to the Callback function. During the bootservices,
+  this is the callback for which this service can be invoked. The report status code router
+  will create an event such that the callback function is only invoked at the TPL for which it was
+  registered. The entity that registers for the callback should also register for an event upon
+  generation of exit boot services and invoke the unregister service.
+  If the handler does not have a TPL dependency, it should register for a callback at TPL high. The
+  router infrastructure will support making callbacks at runtime, but the caller for runtime invocation
+  must meet the following criteria:
+  1. must be a runtime driver type so that its memory is not reclaimed
+  2. not unregister at exit boot services so that the router will still have its callback address
+  3. the caller must be self-contained (eg. Not call out into any boot-service interfaces) and be
+  runtime safe, in general.
+  
+  @param[in] Callback   A pointer to a function of type EFI_RSC_HANDLER_CALLBACK that is called when
+                        a call to ReportStatusCode() occurs.
+  @param[in] Tpl        TPL at which callback can be safely invoked.   
+  
+  @retval  EFI_SUCCESS              Function was successfully registered.
+  @retval  EFI_INVALID_PARAMETER    The callback function was NULL.
+  @retval  EFI_OUT_OF_RESOURCES     The internal buffer ran out of space. No more functions can be
+                                    registered.
+  @retval  EFI_ALREADY_STARTED      The function was already registered. It can't be registered again.
+
+**/
+EFI_STATUS
+EFIAPI
+Register (
+  IN EFI_RSC_HANDLER_CALLBACK   Callback,
+  IN EFI_TPL                    Tpl
+  );
+
+/**
+  Remove a previously registered callback function from the notification list.
+  
+  A callback function must be unregistered before it is deallocated. It is important that any registered
+  callbacks that are not runtime complaint be unregistered when ExitBootServices() is called.
+  
+  @param[in]  Callback  A pointer to a function of type EFI_RSC_HANDLER_CALLBACK that is to be
+                        unregistered.
+                        
+  @retval EFI_SUCCESS           The function was successfully unregistered.
+  @retval EFI_INVALID_PARAMETER The callback function was NULL.
+  @retval EFI_NOT_FOUND         The callback function was not found to be unregistered.
+
+**/
+EFI_STATUS
+EFIAPI
+Unregister (
+  IN EFI_RSC_HANDLER_CALLBACK Callback
+  );
+
+/**
+  Provides an interface that a software module can call to report a status code.
+
+  @param  Type             Indicates the type of status code being reported.
+  @param  Value            Describes the current status of a hardware or software entity.
+                           This included information about the class and subclass that is used to
+                           classify the entity as well as an operation.
+  @param  Instance         The enumeration of a hardware or software entity within
+                           the system. Valid instance numbers start with 1.
+  @param  CallerId         This optional parameter may be used to identify the caller.
+                           This parameter allows the status code driver to apply different rules to
+                           different callers.
+  @param  Data             This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS           The function completed successfully
+  @retval EFI_DEVICE_ERROR      The function should not be completed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+ReportDispatcher (
+  IN EFI_STATUS_CODE_TYPE     Type,
+  IN EFI_STATUS_CODE_VALUE    Value,
+  IN UINT32                   Instance,
+  IN EFI_GUID                 *CallerId  OPTIONAL,
+  IN EFI_STATUS_CODE_DATA     *Data      OPTIONAL
+  );
+
+#endif
+
+
diff --git a/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
new file mode 100644
index 0000000000..b740db4267
--- /dev/null
+++ b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
@@ -0,0 +1,58 @@
+#/** @file
+#  Report Status Code Router Driver which produces Report Stataus Code Handler Protocol
+#  and Status Code Runtime Protocol.
+#
+#  Copyright (c) 2009, Intel Corporation.
+#
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ReportStatusCodeRouterRuntimeDxe
+  FILE_GUID                      = D93CE3D8-A7EB-4730-8C8E-CC466A9ECC3C
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  ENTRY_POINT                    = GenericStatusCodeRuntimeDxeEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+  ReportStatusCodeRouterRuntimeDxe.c
+  ReportStatusCodeRouterRuntimeDxe.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  UefiRuntimeLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  HobLib
+  PcdLib
+  DebugLib
+  BaseLib
+  SynchronizationLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid               ## CONSUMES ## Event
+
+[Protocols]
+  gEfiRscHandlerProtocolGuid                      ## PRODUCES
+  gEfiStatusCodeRuntimeProtocolGuid               ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc
index 8b130f04c8..406ef8ffe5 100644
--- a/Nt32Pkg/Nt32Pkg.dsc
+++ b/Nt32Pkg/Nt32Pkg.dsc
@@ -363,7 +363,9 @@
    <LibraryClasses>
       PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
   }
-  IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.inf
   Nt32Pkg/BootModePei/BootModePei.inf
   Nt32Pkg/WinNtFlashMapPei/WinNtFlashMapPei.inf
   MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
@@ -400,7 +402,9 @@
   IntelFrameworkModulePkg/Universal/DataHubStdErrDxe/DataHubStdErrDxe.inf
   Nt32Pkg/MiscSubClassPlatformDxe/MiscSubClassPlatformDxe.inf
   Nt32Pkg/TimerDxe/TimerDxe.inf
-  IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.inf
   MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
   MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
   MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
diff --git a/Nt32Pkg/Nt32Pkg.fdf b/Nt32Pkg/Nt32Pkg.fdf
index 15d070a145..d2d8ccea76 100644
--- a/Nt32Pkg/Nt32Pkg.fdf
+++ b/Nt32Pkg/Nt32Pkg.fdf
@@ -1,6 +1,6 @@
 # This is NT32 FDF file with UEFI HII features enabled
 #
-# Copyright (c) 2007, Intel Corporation
+# Copyright (c) 2007 - 2009, Intel Corporation
 #
 #  All rights reserved. This program and the accompanying materials
 #    are licensed and made available under the terms and conditions of the BSD License
@@ -154,7 +154,9 @@ FvNameGuid         = 6D99E806-3D38-42c2-A095-5F4300BFD7DC
   ##
 APRIORI PEI {
   INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
-  INF  IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+  INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  INF  IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  INF  Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.inf
   }
 APRIORI DXE {
   INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
@@ -163,7 +165,9 @@ APRIORI DXE {
 
 INF  MdeModulePkg/Core/Pei/PeiMain.inf
 INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
-INF  IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF  IntelFrameworkModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF  Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.inf
 INF  Nt32Pkg/BootModePei/BootModePei.inf
 INF  Nt32Pkg/WinNtFlashMapPei/WinNtFlashMapPei.inf
 INF  Nt32Pkg/WinNtAutoScanPei/WinNtAutoScanPei.inf
@@ -194,7 +198,9 @@ INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
 INF  IntelFrameworkModulePkg/Universal/DataHubStdErrDxe/DataHubStdErrDxe.inf
 INF  Nt32Pkg/MiscSubClassPlatformDxe/MiscSubClassPlatformDxe.inf
 INF  Nt32Pkg/TimerDxe/TimerDxe.inf
-INF  IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.inf
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF  IntelFrameworkModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF  Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.inf
 INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
 INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
 INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
diff --git a/Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.c b/Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.c
new file mode 100644
index 0000000000..dce9f96576
--- /dev/null
+++ b/Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.c
@@ -0,0 +1,68 @@
+/** @file
+  OEM hook status code handler driver which produces general handler and hook it
+  onto the DXE status code router.
+
+  Copyright (c) 2006 - 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <WinNtDxe.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/ReportStatusCodeHandler.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/OemHookStatusCodeLib.h>
+
+/**
+  Entry point of OEM hook status code handler driver.
+
+  This function is the entry point of this OEM hook status code handler driver.
+  It initializes registers OEM status code handler.
+
+  @param  ImageHandle       The firmware allocated handle for the EFI image.
+  @param  SystemTable       A pointer to the EFI System Table.
+  
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+WinNtOemHookStatusCodeHandlerDxeEntry (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                Status;
+  EFI_RSC_HANDLER_PROTOCOL  *RscHandlerProtocol;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiRscHandlerProtocolGuid,
+                  NULL,
+                  (VOID **) &RscHandlerProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  OemHookStatusCodeInitialize ();
+
+  RscHandlerProtocol->Register (OemHookStatusCodeReport, TPL_HIGH_LEVEL);
+
+  return EFI_SUCCESS;
+}
diff --git a/Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.inf b/Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.inf
new file mode 100644
index 0000000000..dfd3c062e9
--- /dev/null
+++ b/Nt32Pkg/WinNtOemHookStatusCodeHandlerDxe/WinNtOemHookStatusCodeHandlerDxe.inf
@@ -0,0 +1,51 @@
+#/** @file
+# OEM hook status code handler driver which produces general handler and hook it
+# onto the DXE status code router.
+#
+# Copyright (c) 2007 - 2009, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = WinNtOemHookStatusCodeHandlerDxe
+  FILE_GUID                      = CA4233AD-847E-4E5D-AD3F-21CABFE5E23C
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = WinNtOemHookStatusCodeHandlerDxeEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+#  HOB Guid C Name: gEfiWinNtThunkProtocolGuid Hob Type: GUID_EXTENSION
+#
+
+[Sources.common]
+  WinNtOemHookStatusCodeHandlerDxe.c
+
+
+[Packages]
+  Nt32Pkg/Nt32Pkg.dec
+  MdePkg/MdePkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  OemHookStatusCodeLib
+
+[Protocols]
+  gEfiRscHandlerProtocolGuid                    ## CONSUMES
+
+[Depex]
+  gEfiRscHandlerProtocolGuid
diff --git a/Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.c b/Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.c
new file mode 100644
index 0000000000..e9ab12a267
--- /dev/null
+++ b/Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.c
@@ -0,0 +1,89 @@
+/** @file
+  OEM hook status code handler PEIM which produces general handler and hook it
+  onto the PEI status code router.
+
+  Copyright (c) 2006 - 2009, Intel Corporation
+  All rights reserved. This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <WinNtPeim.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Ppi/ReportStatusCodeHandler.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/OemHookStatusCodeLib.h>
+
+EFI_STATUS
+EFIAPI
+OemHookStatusCodeReportWrapper (
+  IN CONST EFI_PEI_SERVICES         **PeiServices,
+  IN       EFI_STATUS_CODE_TYPE     CodeType,
+  IN       EFI_STATUS_CODE_VALUE    Value,
+  IN       UINT32                   Instance,
+  IN CONST EFI_GUID                 *CallerId, OPTIONAL
+  IN CONST EFI_STATUS_CODE_DATA     *Data      OPTIONAL
+  )
+{
+  return OemHookStatusCodeReport (
+           CodeType,
+           Value,
+           Instance,
+           (EFI_GUID *) CallerId,
+           (EFI_STATUS_CODE_DATA *) Data
+           );
+}
+
+/**
+  Entry point of OEM hook status code handler PEIM.
+  
+  This function is the entry point of this OEM hook status code handler PEIM.
+  It initializes and registers OEM status code handler.
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCESS  The entry point executes successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+WinNtOemHookStatusCodeHandlerPeiEntry (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PEI_RSC_HANDLER_PPI     *RscHandlerPpi;
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiRscHandlerPpiGuid,
+             0,
+             NULL,
+             (VOID **) &RscHandlerPpi
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  OemHookStatusCodeInitialize ();
+
+  Status = RscHandlerPpi->Register (OemHookStatusCodeReportWrapper);                     
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.inf b/Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.inf
new file mode 100644
index 0000000000..b5a18a7188
--- /dev/null
+++ b/Nt32Pkg/WinNtOemHookStatusCodeHandlerPei/WinNtOemHookStatusCodeHandlerPei.inf
@@ -0,0 +1,51 @@
+#/** @file
+# OEM hook status code handler PEIM which produces general handler and hook it
+# onto the PEI status code router.
+#
+# Copyright (c) 2007 - 2009, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = WinNtOemHookStatusCodeHandlerPei
+  FILE_GUID                      = D233D6BD-F1B1-425A-BF45-5CAF2B88EDDC
+  MODULE_TYPE                    = PEIM
+  ENTRY_POINT                    = WinNtOemHookStatusCodeHandlerPeiEntry
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources.common]
+  WinNtOemHookStatusCodeHandlerPei.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  Nt32Pkg/Nt32Pkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  PeiServicesLib
+  DebugLib
+  OemHookStatusCodeLib
+
+[Ppis]
+  gEfiPeiRscHandlerPpiGuid                      ## CONSUMES
+
+[Depex]
+  gEfiPeiRscHandlerPpiGuid