summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/StatusCode/Dxe
diff options
context:
space:
mode:
authoryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-21 14:25:43 +0000
committeryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-21 14:25:43 +0000
commit56836fe92b0a7284bc2e964065e00ad867145826 (patch)
tree6528bf8403b71144f6c7e33a2b51d305b032b1a8 /EdkModulePkg/Universal/StatusCode/Dxe
parent3f566587aea64bb986866c7f69a6b82891bf59db (diff)
downloadedk2-platforms-56836fe92b0a7284bc2e964065e00ad867145826.tar.xz
1) Check in Pei/Dxe status code;
2) OemHookStatusCodeLib and SerialPortLib class and null instance; 3) Remove all referenced code from EdkModulePkg,EdkNt32Pkg. 4) Add Nt32OemHookStatusCodeLib. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1067 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Universal/StatusCode/Dxe')
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c222
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/Common/StatusCode.dxs26
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c310
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.c149
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.h238
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.msa187
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/Ipf/DxeStatusCodeIpf.c201
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/Ipf/StatusCode.dxs27
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/RtMemoryStatusCodeWorker.c119
-rw-r--r--EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c184
10 files changed, 1663 insertions, 0 deletions
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c b/EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c
new file mode 100644
index 0000000000..ae45d886be
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/Common/DxeStatusCodeCommon.c
@@ -0,0 +1,222 @@
+/** @file
+ Status code driver for IA32/X64/EBC architecture.
+
+// Copyright (c) 2006, Intel Corporation. All rights reserved.
+// This software and associated documentation (if any) is furnished
+// under a license and may only be used or copied in accordance
+// with the terms of the license. Except as permitted by such
+// license, no part of this software or documentation may be
+// reproduced, stored in a retrieval system, or transmitted in any
+// form or by any means without the express written consent of
+// Intel Corporation.
+
+ Module Name: DxeStatusCodeCommon.c
+
+**/
+#include "DxeStatusCode.h"
+
+
+/**
+ Report status code to all supported device.
+ Calls into the workers which dispatches the platform specific
+ listeners.
+
+ @param Type Indicates the type of status code being reported.
+ The type EFI_STATUS_CODE_TYPE is defined in "Related Definitions" below.
+ @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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+ @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.
+ Type EFI_STATUS_CODE_DATA is defined in "Related Definitions" below.
+ The contents of this data type may have additional GUID-specific data. The standard GUIDs and
+ their associated data structures are defined in the Intel? Platform Innovation Framework for EFI Status Codes Specification.
+**/
+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
+ );
+
+//
+// Declaration of status code protocol.
+//
+EFI_STATUS_CODE_PROTOCOL mEfiStatusCodeProtocol = {
+ ReportDispatcher
+};
+
+//
+// Delaration of DXE status code controller
+//
+DXE_STATUS_CODE_CONTROLLER gDxeStatusCode = {
+ //
+ // Initialize nest status as non nested.
+ //
+ 0,
+ {NULL, NULL}
+};
+
+/**
+
+ Install the ReportStatusCode runtime service.
+
+ @param ImageHandle Image handle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @return The function always returns success.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeStatusCodeDriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+
+ //
+ // Dispatch initialization request to supported devices
+ //
+ InitializationDispatcherWorker ();
+
+ //
+ // Install Status Code Architectural Protocol implementation as defined in Tiano
+ // Architecture Specification.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiStatusCodeRuntimeProtocolGuid,
+ &mEfiStatusCodeProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Report status code to all supported device.
+ Calls into the workers which dispatches the platform specific
+ listeners.
+
+ @param CodeType Indicates the type of status code being reported.
+ The type EFI_STATUS_CODE_TYPE is defined in "Related Definitions" below.
+ @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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+ @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.
+ Type EFI_STATUS_CODE_DATA is defined in "Related Definitions" below.
+ The contents of this data type may have additional GUID-specific data. The standard GUIDs and
+ their associated data structures are defined in the Intel? Platform Innovation Framework for EFI Status Codes Specification.
+**/
+EFI_STATUS
+EFIAPI
+ReportDispatcher (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+{
+ //
+ // Use atom operation to avoid the reentant of report.
+ // If current status is not zero, then the function is reentrancy.
+ //
+ if (InterlockedCompareExchange32 (&gDxeStatusCode.StatusCodeNestStatus, 0, 1)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (FeaturePcdGet (PcdStatusCodeUseEfiSerial) || FeaturePcdGet (PcdStatusCodeUseHardSerial)) {
+ SerialStatusCodeReportWorker (
+ CodeType,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseRuntimeMemory)) {
+ RtMemoryStatusCodeReportWorker (
+ gDxeStatusCode.RtMemoryStatusCodeTable[PHYSICAL_MODE],
+ CodeType,
+ Value,
+ Instance
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseDataHub)) {
+ DataHubStatusCodeReportWorker (
+ CodeType,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseOEM)) {
+ OemHookStatusCodeReport (
+ CodeType,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+ }
+
+ //
+ // Restore the nest status of report
+ //
+ InterlockedCompareExchange32 (&gDxeStatusCode.StatusCodeNestStatus, 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
+ )
+{
+ //
+ // Convert memory status code table to virtual address;
+ //
+ EfiConvertPointer (
+ 0,
+ (VOID **) &gDxeStatusCode.RtMemoryStatusCodeTable[PHYSICAL_MODE]
+ );
+}
+
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/Common/StatusCode.dxs b/EdkModulePkg/Universal/StatusCode/Dxe/Common/StatusCode.dxs
new file mode 100644
index 0000000000..6371258e9a
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/Common/StatusCode.dxs
@@ -0,0 +1,26 @@
+#/*++
+#
+# Copyright (c) 2006, 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.
+#
+# Module Name:
+#
+# Ia32StatusCode.dxs
+#
+# Abstract:
+#
+# Dependency expression source file.
+#
+#--*/
+#include <AutoGen.h>
+#include <DxeDepex.h>
+
+DEPENDENCY_START
+ EFI_DATA_HUB_PROTOCOL_GUID AND EFI_CPU_IO_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c b/EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
new file mode 100644
index 0000000000..ca70bf4338
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
@@ -0,0 +1,310 @@
+/** @file
+ Data Hub status code worker in DXE.
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+ Module Name: DataHubStatusCodeWorker.c
+
+**/
+#include "DxeStatusCode.h"
+
+//
+// Initialize FIFO to cache records.
+//
+EFI_LOCK mFifoLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL);
+LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo);
+UINTN mNumberOfRecords = 0;
+
+EFI_EVENT mLogDataHubEvent;
+//
+// Cache data hub protocol.
+//
+EFI_DATA_HUB_PROTOCOL *mDataHubProtocol;
+
+
+/**
+ Return buffer of length DATAHUB_STATUSCODE_RECORD
+
+ @retval NULL Can not allocate free memeory for record.
+ @retval !NULL Point to buffer of record.
+
+**/
+DATAHUB_STATUSCODE_RECORD *
+AcquireRecordBuffer (
+ VOID
+ )
+{
+ DATAHUB_STATUSCODE_RECORD *Record;
+
+ Record = (DATAHUB_STATUSCODE_RECORD *) AllocateZeroPool (sizeof (DATAHUB_STATUSCODE_RECORD));
+ if (NULL == Record) {
+ return NULL;
+ }
+ Record->Signature = DATAHUB_STATUS_CODE_SIGNATURE;
+
+ EfiAcquireLock (&mFifoLock);
+ InsertTailList (&mRecordsFifo, &Record->Node);
+ mNumberOfRecords++;
+ EfiReleaseLock (&mFifoLock);
+
+ return Record;
+}
+
+
+/**
+ Release a mRecordBuffer entry allocated by AcquirRecordBuffer ().
+
+ @param Record Point to record buffer which is acquired by AcquirRecordBuffer()
+
+ @retval EFI_SUCCESS If DataRecord is valid.
+ @retval !EFI_SUCCESS The record list has empty.
+
+**/
+VOID
+FreeRecordBuffer (
+ IN DATAHUB_STATUSCODE_RECORD *Record
+ )
+/*++
+
+Routine Description:
+
+ Release a mRecordBuffer entry allocated by AquireEmptyRecordBuffer ().
+
+Arguments:
+
+ RecordBuffer - Data to free
+
+Returns:
+
+ EFI_SUCCESS - If DataRecord is valid
+ EFI_UNSUPPORTED - The record list has empty
+
+--*/
+{
+ ASSERT (Record != NULL);
+ ASSERT (mNumberOfRecords != 0);
+
+ EfiAcquireLock (&mFifoLock);
+ RemoveEntryList (&Record->Node);
+ mNumberOfRecords--;
+ EfiReleaseLock (&mFifoLock);
+
+ FreePool (Record);
+}
+
+
+/**
+ Report status code into DataHub.
+
+ @param CodeType Indicates the type of status code being reported. Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions¡± below.
+
+ @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. 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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+
+ @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.
+ Type EFI_GUID is defined in InstallProtocolInterface() in the EFI 1.10 Specification.
+
+
+ @param Data This optional parameter may be used to pass additional data
+
+ @retval EFI_OUT_OF_RESOURCES Can not acquire record buffer.
+ @retval EFI_SUCCESS Success to cache status code and signal log data event.
+
+**/
+EFI_STATUS
+DataHubStatusCodeReportWorker (
+ 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
+ )
+{
+ DATAHUB_STATUSCODE_RECORD *Record;
+ UINT32 ErrorLevel;
+ VA_LIST Marker;
+ CHAR8 *Format;
+ UINTN CharCount;
+
+ //
+ // See whether in runtime phase or not.
+ //
+ if (EfiAtRuntime ()) {
+ return EFI_SUCCESS;
+ }
+
+ Record = (DATAHUB_STATUSCODE_RECORD *) AcquireRecordBuffer ();
+ if (Record == NULL) {
+ //
+ // There are no empty record buffer in private buffers
+ //
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Construct Data Hub Extended Data
+ //
+ Record->CodeType = CodeType;
+ Record->Value = Value;
+ Record->Instance = Instance;
+
+ if (CallerId != NULL) {
+ CopyMem (&Record->CallerId, CallerId, sizeof (EFI_GUID));
+ }
+
+ if (Data != NULL) {
+ if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
+ CharCount = UnicodeVSPrintAsciiFormat (
+ (CHAR16 *) Record->ExtendData,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ Format,
+ Marker
+ );
+ //
+ // Change record data type from DebugType to String Type.
+ //
+ CopyGuid (&Record->Data.Type, &gEfiStatusCodeDataTypeStringGuid);
+ Record->Data.HeaderSize = Data->HeaderSize;
+ Record->Data.Size = (UINT16) ((CharCount + 1) * sizeof (CHAR16));
+ } else {
+ //
+ // Copy status code data header
+ //
+ CopyMem (&Record->Data, Data, sizeof (EFI_STATUS_CODE_DATA));
+
+ if (Data->Size > EFI_STATUS_CODE_DATA_MAX_SIZE) {
+ Record->Data.Size = EFI_STATUS_CODE_DATA_MAX_SIZE;
+ }
+ CopyMem (Record->ExtendData, Data + 1, Record->Data.Size);
+ }
+ }
+
+ gBS->SignalEvent (mLogDataHubEvent);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The Event handler which will be notified to log data in Data Hub.
+
+ @param Event Instance of the EFI_EVENT to signal whenever data is
+ available to be logged in the system.
+ @param Context Context of the event.
+
+**/
+VOID
+EFIAPI
+LogDataHubEventCallBack (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ DATAHUB_STATUSCODE_RECORD *Record;
+ UINTN Size;
+ UINT64 DataRecordClass;
+ LIST_ENTRY *Node;
+
+ //
+ // Log DataRecord in Data Hub.
+ // Journal records fifo to find all record entry.
+ //
+ //
+ for (Node = mRecordsFifo.ForwardLink; Node != &mRecordsFifo;) {
+ Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE);
+ Node = Node->ForwardLink;
+
+ //
+ // Add in the size of the header we added.
+ //
+ Size = sizeof (DATAHUB_STATUSCODE_RECORD) + Record->Data.Size;
+
+ if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+ DataRecordClass = EFI_DATA_RECORD_CLASS_PROGRESS_CODE;
+ } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+ DataRecordClass = EFI_DATA_RECORD_CLASS_ERROR;
+ } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
+ DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG;
+ } else {
+ //
+ // Should never get here.
+ //
+ DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG |
+ EFI_DATA_RECORD_CLASS_ERROR |
+ EFI_DATA_RECORD_CLASS_DATA |
+ EFI_DATA_RECORD_CLASS_PROGRESS_CODE;
+ }
+
+ //
+ // Log DataRecord in Data Hub
+ //
+
+ mDataHubProtocol->LogData (
+ mDataHubProtocol,
+ &gEfiStatusCodeGuid,
+ &gEfiStatusCodeRuntimeProtocolGuid,
+ DataRecordClass,
+ Record,
+ (UINT32) Size
+ );
+
+ FreeRecordBuffer (Record);
+ }
+}
+
+
+/**
+ Initialize data hubstatus code.
+ Create a data hub listener.
+
+ @return The function always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+DataHubStatusCodeInitializeWorker (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (
+ &gEfiDataHubProtocolGuid,
+ NULL,
+ (VOID **) &mDataHubProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create a Notify Event to log data in Data Hub
+ //
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ LogDataHubEventCallBack,
+ NULL,
+ &mLogDataHubEvent
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.c b/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.c
new file mode 100644
index 0000000000..4b942187d3
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.c
@@ -0,0 +1,149 @@
+/** @file
+ Status Code Architectural Protocol implementation as defined in Tiano
+ Architecture Specification.
+
+ This driver has limited functionality at runtime and will not log to Data Hub
+ at runtime.
+
+ Notes:
+ This driver assumes the following ReportStatusCode strategy:
+ PEI -> uses PeiReportStatusCode
+ DXE IPL -> uses PeiReportStatusCode
+ early DXE -> uses PeiReportStatusCode via HOB
+ DXE -> This driver
+ RT -> This driver
+
+// Copyright (c) 2006, Intel Corporation. All rights reserved.
+// This software and associated documentation (if any) is furnished
+// under a license and may only be used or copied in accordance
+// with the terms of the license. Except as permitted by such
+// license, no part of this software or documentation may be
+// reproduced, stored in a retrieval system, or transmitted in any
+// form or by any means without the express written consent of
+// Intel Corporation.
+
+ Module Name: StatusCode.c
+
+**/
+
+#include "DxeStatusCode.h"
+
+/**
+
+ Dispatch initialization request to sub status code devices based on
+ customized feature flags.
+
+**/
+VOID
+InitializationDispatcherWorker (
+ VOID
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader;
+ MEMORY_STATUSCODE_RECORD *Record;
+ UINTN ExpectedPacketIndex = 0;
+ UINTN Index;
+ VOID *HobStart;
+
+ //
+ // If enable UseSerial, then initialize serial port.
+ // if enable UseRuntimeMemory, then initialize runtime memory status code worker.
+ // if enable UseDataHub, then initialize data hub status code worker.
+ //
+ if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) {
+ EfiSerialStatusCodeInitializeWorker ();
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseHardSerial)) {
+ SerialPortInitialize ();
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseRuntimeMemory)) {
+ RtMemoryStatusCodeInitializeWorker ();
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseDataHub)) {
+ DataHubStatusCodeInitializeWorker ();
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseOEM)) {
+ OemHookStatusCodeInitialize ();
+ }
+
+ //
+ // Replay Status code which saved in GUID'ed HOB to all supported device.
+ //
+
+ //
+ // Journal GUID'ed HOBs to find all record entry, if found,
+ // then output record to support replay device.
+ //
+ 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 (PcdStatusCodeReplayInSerial) &&
+ (FeaturePcdGet (PcdStatusCodeUseHardSerial) ||
+ FeaturePcdGet (PcdStatusCodeUseEfiSerial))) {
+ SerialStatusCodeReportWorker (
+ Record[Index].CodeType,
+ Record[Index].Value,
+ Record[Index].Instance,
+ NULL,
+ NULL
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeReplayInRuntimeMemory) &&
+ FeaturePcdGet (PcdStatusCodeUseRuntimeMemory)) {
+ RtMemoryStatusCodeReportWorker (
+ gDxeStatusCode.RtMemoryStatusCodeTable[PHYSICAL_MODE],
+ Record[Index].CodeType,
+ Record[Index].Value,
+ Record[Index].Instance
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeReplayInDataHub) &&
+ FeaturePcdGet (PcdStatusCodeUseDataHub)) {
+ DataHubStatusCodeReportWorker (
+ Record[Index].CodeType,
+ Record[Index].Value,
+ Record[Index].Instance,
+ NULL,
+ NULL
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeReplayInOEM) &&
+ FeaturePcdGet (PcdStatusCodeUseOEM)) {
+ OemHookStatusCodeReport (
+ Record[Index].CodeType,
+ Record[Index].Value,
+ Record[Index].Instance,
+ NULL,
+ NULL
+ );
+ }
+ }
+ ExpectedPacketIndex++;
+
+ //
+ // See whether there is gap of packet or not
+ //
+ if (HobStart) {
+ 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);
+ }
+}
+
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.h b/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.h
new file mode 100644
index 0000000000..eeb6dcb720
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.h
@@ -0,0 +1,238 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ DxeStatusCode.h
+
+Abstract:
+
+ Header file of EFI DXE/RT Status Code.
+
+--*/
+
+#ifndef __DXE_STATUS_CODE_H__
+#define __DXE_STATUS_CODE_H__
+
+//
+// Data hub worker definition
+//
+#define MAX_NUMBER_DATAHUB_RECORDS 1000
+#define DATAHUB_BYTES_PER_RECORD EFI_STATUS_CODE_DATA_MAX_SIZE
+#define EMPTY_RECORD_TAG 0xFF
+#define DATAHUB_STATUS_CODE_SIGNATURE EFI_SIGNATURE_32 ('B', 'D', 'H', 'S')
+
+//
+// Address type of pointer.
+// The point type always equal to PHYSICAL_MODE on IA32/X64/EBC architecture
+// Otherwise, VIRTUAL_MODE/PHYSICAL_MODE would be used on Ipf architecture,
+//
+enum {
+ PHYSICAL_MODE,
+ VIRTUAL_MODE
+};
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Node;
+ EFI_STATUS_CODE_TYPE CodeType;
+ EFI_STATUS_CODE_VALUE Value;
+ UINT32 Instance;
+ EFI_GUID CallerId;
+ EFI_STATUS_CODE_DATA Data;
+ UINT8 ExtendData[EFI_STATUS_CODE_DATA_MAX_SIZE];
+} DATAHUB_STATUSCODE_RECORD;
+
+
+//
+// Runtime memory status code worker definition
+//
+typedef struct {
+ UINT32 RecordIndex;
+ UINT32 NumberOfRecords;
+ UINT32 MaxRecordsNumber;
+} RUNTIME_MEMORY_STATUSCODE_HEADER;
+
+
+typedef struct {
+ //
+ // Report operation nest status.
+ // If it is set, then the report operation has nested.
+ //
+ UINT32 StatusCodeNestStatus;
+ //
+ // Runtime status code management header, the records buffer is following it.
+ //
+ RUNTIME_MEMORY_STATUSCODE_HEADER *RtMemoryStatusCodeTable[2];
+} DXE_STATUS_CODE_CONTROLLER;
+
+
+/**
+
+ Dispatch initialization request to sub status code devices based on
+ customized feature flags.
+
+**/
+VOID
+InitializationDispatcherWorker (
+ VOID
+ );
+
+
+/**
+ Initialize serial status code worker.
+
+ @return The function always return EFI_SUCCESS
+
+**/
+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. Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions¡± below.
+
+ @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. 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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+
+ @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.
+ Type EFI_GUID is defined in InstallProtocolInterface() in the EFI 1.10 Specification.
+
+
+ @param Data This optional parameter may be used to pass additional data
+
+ @return The function always return EFI_SUCCESS.
+
+**/
+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.
+
+ @return The function always return EFI_SUCCESS
+
+**/
+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 RtMemoryStatusCodeTable
+ Point to Runtime memory table header.
+
+ @param CodeType Indicates the type of status code being reported. Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions¡± below.
+
+ @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. 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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+
+ @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.
+
+ @return The function always return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+RtMemoryStatusCodeReportWorker (
+ RUNTIME_MEMORY_STATUSCODE_HEADER *RtMemoryStatusCodeTable,
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance
+ );
+
+/**
+ Initialize data hubstatus code.
+ Create a data hub listener.
+
+ @return The function always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+DataHubStatusCodeInitializeWorker (
+ VOID
+ );
+
+
+/**
+ Report status code into DataHub.
+
+ @param CodeType Indicates the type of status code being reported. Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions¡± below.
+
+ @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. 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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+
+ @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.
+ Type EFI_GUID is defined in InstallProtocolInterface() in the EFI 1.10 Specification.
+
+
+ @param Data This optional parameter may be used to pass additional data
+
+ @retval EFI_OUT_OF_RESOURCES Can not acquire record buffer.
+ @retval EFI_SUCCESS Success to cache status code and signal log data event.
+
+**/
+EFI_STATUS
+DataHubStatusCodeReportWorker (
+ 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
+ );
+
+//
+// declaration of DXE status code controller.
+//
+extern DXE_STATUS_CODE_CONTROLLER gDxeStatusCode;
+
+#endif
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.msa b/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.msa
new file mode 100644
index 0000000000..061ea92b30
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/DxeStatusCode.msa
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Copyright (c) 2006, 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.-->
+<ModuleSurfaceArea xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd" xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>DxeStatusCode</ModuleName>
+ <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>
+ <GuidValue>FEDE0A1B-BCA2-4A9F-BB2B-D9FD7DEC2E9F</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>DXE status code driver.</Abstract>
+ <Description>
+ Status Code Architectural Protocol implementation as defined in Tiano
+ Architecture Specification. This driver has limited functionality
+ at runtime and will not log to Data Hub at runtime.
+ </Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation.</Copyright>
+ <License>All rights reserved.
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>DxeStatusCode</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>ReportStatusCodeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PrintLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PcdLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>HobLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiRuntimeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>SerialPortLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>OemHookStatusCodeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>EdkDxeSalLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>DxeStatusCode.c</Filename>
+ <Filename>DataHubStatusCodeWorker.c</Filename>
+ <Filename>RtMemoryStatusCodeWorker.c</Filename>
+ <Filename>SerialStatusCodeWorker.c</Filename>
+ <Filename SupArchList="IA32">Common/DxeStatusCodeCommon.c</Filename>
+ <Filename SupArchList="IA32">Common/StatusCode.dxs</Filename>
+ <Filename SupArchList="X64">Common/DxeStatusCodeCommon.c</Filename>
+ <Filename SupArchList="X64">Common/StatusCode.dxs</Filename>
+ <Filename SupArchList="EBC">Common/DxeStatusCodeCommon.c</Filename>
+ <Filename SupArchList="EBC">Common/StatusCode.dxs</Filename>
+ <Filename SupArchList="IPF">Ipf/DxeStatusCodeIpf.c</Filename>
+ <Filename SupArchList="IPF">Ipf/StatusCode.dxs</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5E0E9358-46B6-4AE2-8218-4AB8B9BBDCEC"/>
+ <Package PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiExtendedSalStatusCodeServicesProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiSerialIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDataHubProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gMemoryStatusCodeRecordGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiStatusCodeDataTypeStringGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="SOMETIMES_CONSUMED">
+ <GuidCName>gEfiStatusCodeGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <ModuleEntryPoint>DxeStatusCodeDriverEntry</ModuleEntryPoint>
+ </Extern>
+ <Extern>
+ <SetVirtualAddressMapCallBack>VirtualAddressChangeCallBack</SetVirtualAddressMapCallBack>
+ </Extern>
+ </Externs>
+ <PcdCoded>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeUseHardSerial</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeUseEfiSerial</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeUseRuntimeMemory</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeUseDataHub</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeUseOEM</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeReplayInSerial</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeReplayInDataHub</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeReplayInRuntimeMemory</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG">
+ <C_Name>PcdStatusCodeReplayInOEM</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdStatusCodeRuntimeMemory</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText/>
+ </PcdEntry>
+ </PcdCoded>
+</ModuleSurfaceArea> \ No newline at end of file
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/Ipf/DxeStatusCodeIpf.c b/EdkModulePkg/Universal/StatusCode/Dxe/Ipf/DxeStatusCodeIpf.c
new file mode 100644
index 0000000000..756c274495
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/Ipf/DxeStatusCodeIpf.c
@@ -0,0 +1,201 @@
+/** @file
+ Status code driver for IA32/X64/EBC architecture.
+
+// Copyright (c) 2006, Intel Corporation. All rights reserved.
+// This software and associated documentation (if any) is furnished
+// under a license and may only be used or copied in accordance
+// with the terms of the license. Except as permitted by such
+// license, no part of this software or documentation may be
+// reproduced, stored in a retrieval system, or transmitted in any
+// form or by any means without the express written consent of
+// Intel Corporation.
+
+ Module Name: DxeStatusCodeIpf.c
+
+**/
+
+#include "DxeStatusCode.h"
+
+
+//
+// Delaration of DXE status code controller
+//
+DXE_STATUS_CODE_CONTROLLER gDxeStatusCode = {
+ //
+ // Initialize nest status as non nested.
+ //
+ 0,
+ {NULL, NULL}
+};
+
+/**
+
+ Main entry for Extended SAL ReportStatusCode Services
+
+ @param FunctionId Function Id which needed to be called
+ @param Arg2 Efi status code type
+ @param Arg3 Efi status code value
+ @param Arg4 Instance number
+ @param Arg5 Caller Id
+ @param Arg6 Efi status code data
+ @param Arg7 Not used
+ @param Arg8 Not used
+ @param ExtendedSalProc Esal Proc pointer
+ @param VirtualMode If this function is called in virtual mode
+ @param Global This module's global variable pointer
+
+ @return Value returned in SAL_RETURN_REGS
+
+--*/
+SAL_RETURN_REGS
+EFIAPI
+ReportEsalServiceEntry (
+ IN UINT64 FunctionId,
+ IN UINT64 Arg2,
+ IN UINT64 Arg3,
+ IN UINT64 Arg4,
+ IN UINT64 Arg5,
+ IN UINT64 Arg6,
+ IN UINT64 Arg7,
+ IN UINT64 Arg8,
+ IN SAL_EXTENDED_SAL_PROC ExtendedSalProc,
+ IN BOOLEAN VirtualMode,
+ IN VOID *Global
+ )
+{
+ SAL_RETURN_REGS ReturnVal;
+ DXE_STATUS_CODE_CONTROLLER *DxeStatusCode;
+
+ switch (FunctionId) {
+
+ case ReportStatusCodeService:
+
+ DxeStatusCode = (DXE_STATUS_CODE_CONTROLLER *) Global;
+
+ //
+ // Use atom operation to avoid the reentant of report.
+ // If current status is not zero, then the function is reentrancy.
+ //
+ if (InterlockedCompareExchange32 (&DxeStatusCode->StatusCodeNestStatus, 0, 1)) {
+ ReturnVal.Status = EFI_DEVICE_ERROR ;
+ return ReturnVal;
+ }
+
+ if (FeaturePcdGet (PcdStatusCodeUseEfiSerial) || FeaturePcdGet (PcdStatusCodeUseHardSerial)) {
+ SerialStatusCodeReportWorker (
+ (EFI_STATUS_CODE_TYPE) Arg2,
+ (EFI_STATUS_CODE_VALUE) Arg3,
+ (UINT32) Arg4,
+ (EFI_GUID *) Arg5,
+ (EFI_STATUS_CODE_DATA *) Arg6
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseRuntimeMemory)) {
+ RtMemoryStatusCodeReportWorker (
+ DxeStatusCode->RtMemoryStatusCodeTable[VirtualMode],
+ (EFI_STATUS_CODE_TYPE) Arg2,
+ (EFI_STATUS_CODE_VALUE) Arg3,
+ (UINT32) Arg4
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseDataHub)) {
+ DataHubStatusCodeReportWorker (
+ (EFI_STATUS_CODE_TYPE) Arg2,
+ (EFI_STATUS_CODE_VALUE) Arg3,
+ (UINT32) Arg4,
+ (EFI_GUID *) Arg5,
+ (EFI_STATUS_CODE_DATA *) Arg6
+ );
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseOEM)) {
+ OemHookStatusCodeReport (
+ (EFI_STATUS_CODE_TYPE) Arg2,
+ (EFI_STATUS_CODE_VALUE) Arg3,
+ (UINT32) Arg4,
+ (EFI_GUID *) Arg5,
+ (EFI_STATUS_CODE_DATA *) Arg6
+ );
+ }
+
+ //
+ // Restore the nest status of report
+ //
+ InterlockedCompareExchange32 (&DxeStatusCode->StatusCodeNestStatus, 1, 0);
+
+ ReturnVal.Status = EFI_SUCCESS;
+
+ break;
+
+ default:
+ ReturnVal.Status = EFI_SAL_INVALID_ARGUMENT;
+ break;
+ }
+
+ return ReturnVal;
+}
+
+/**
+
+ Install the ReportStatusCode runtime service.
+
+ @param ImageHandle Image handle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @return The function always returns success.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeStatusCodeDriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //
+ // Dispatch initialization request to supported devices
+ //
+ InitializationDispatcherWorker ();
+
+ //
+ // Initialize ESAL capabilities.
+ //
+ RegisterEsalClass (
+ &gEfiExtendedSalStatusCodeServicesProtocolGuid,
+ &gDxeStatusCode,
+ ReportEsalServiceEntry,
+ StatusCode,
+ NULL
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Virtual address change notification call back. It converts physical mode global pointer to
+ virtual mode.
+
+ @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
+ )
+{
+ gDxeStatusCode.RtMemoryStatusCodeTable[VIRTUAL_MODE] =
+ gDxeStatusCode.RtMemoryStatusCodeTable[PHYSICAL_MODE];
+
+ //
+ // Convert the physical mode pointer to virtual mode point.
+ //
+ EfiConvertPointer (
+ 0,
+ (VOID **) &gDxeStatusCode.RtMemoryStatusCodeTable[VIRTUAL_MODE]
+ );
+}
+
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/Ipf/StatusCode.dxs b/EdkModulePkg/Universal/StatusCode/Dxe/Ipf/StatusCode.dxs
new file mode 100644
index 0000000000..9d94fd79fa
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/Ipf/StatusCode.dxs
@@ -0,0 +1,27 @@
+#/*++
+#
+// Copyright (c) 2006, Intel Corporation. All rights reserved.
+// This software and associated documentation (if any) is furnished
+// under a license and may only be used or copied in accordance
+// with the terms of the license. Except as permitted by such
+// license, no part of this software or documentation may be
+// reproduced, stored in a retrieval system, or transmitted in any
+// form or by any means without the express written consent of
+// Intel Corporation.
+#
+# Module Name:
+#
+# IpfStatusCode.dxs
+#
+# Abstract:
+#
+# Dependency expression source file.
+#
+#--*/
+
+#include <AutoGen.h>
+#include <DxeDepex.h>
+
+DEPENDENCY_START
+ EFI_DATA_HUB_PROTOCOL_GUID AND EFI_EXTENDED_SAL_BASE_IO_SERVICES_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/RtMemoryStatusCodeWorker.c b/EdkModulePkg/Universal/StatusCode/Dxe/RtMemoryStatusCodeWorker.c
new file mode 100644
index 0000000000..a0b70b8d95
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/RtMemoryStatusCodeWorker.c
@@ -0,0 +1,119 @@
+/** @file
+ Runtime memory status code worker in DXE.
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+ Module Name: RtMemoryStatusCodeWorker.c
+
+**/
+
+#include "DxeStatusCode.h"
+
+/**
+ Initialize runtime memory status code.
+
+ @return The function always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+RtMemoryStatusCodeInitializeWorker (
+ VOID
+ )
+{
+ RUNTIME_MEMORY_STATUSCODE_HEADER *RtMemoryStatusCodeTable;
+
+ //
+ // Allocate runtime memory status code pool.
+ //
+ RtMemoryStatusCodeTable =
+ (RUNTIME_MEMORY_STATUSCODE_HEADER *) AllocatePool (
+ sizeof (RUNTIME_MEMORY_STATUSCODE_HEADER) + PcdGet16 (PcdStatusCodeRuntimeMemorySize) * 1024
+ );
+
+ ASSERT (NULL != RtMemoryStatusCodeTable);
+
+ RtMemoryStatusCodeTable->RecordIndex = 0;
+ RtMemoryStatusCodeTable->NumberOfRecords = 0;
+ RtMemoryStatusCodeTable->MaxRecordsNumber =
+ (PcdGet16 (PcdStatusCodeRuntimeMemorySize) * 1024) / sizeof (MEMORY_STATUSCODE_RECORD);
+
+ gDxeStatusCode.RtMemoryStatusCodeTable[PHYSICAL_MODE] = RtMemoryStatusCodeTable;
+ 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 RtMemoryStatusCodeTable
+ Point to Runtime memory table header.
+
+ @param CodeType Indicates the type of status code being reported. Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions¡± below.
+
+ @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. 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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+
+ @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.
+
+ @return The function always return EFI_SUCCESS.
+
+**/
+EFI_STATUS
+RtMemoryStatusCodeReportWorker (
+ RUNTIME_MEMORY_STATUSCODE_HEADER *RtMemoryStatusCodeTable,
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance
+ )
+{
+ MEMORY_STATUSCODE_RECORD *Record;
+
+ ASSERT (NULL != RtMemoryStatusCodeTable);
+
+ //
+ // Locate current record buffer.
+ //
+ Record = (MEMORY_STATUSCODE_RECORD *) (RtMemoryStatusCodeTable + 1);
+ Record = &Record[RtMemoryStatusCodeTable->RecordIndex++];
+
+ //
+ // Save status code.
+ //
+ Record->CodeType = CodeType;
+ Record->Value = Value;
+ Record->Instance = Instance;
+
+ //
+ // Record total number of records, we compare the number with max records number,
+ // if it is bigger than the max number, then the roll back had happened, the record index points to
+ // the first record. if it is less then max number, then the zero index is the first record.
+ //
+ RtMemoryStatusCodeTable->NumberOfRecords++;
+ if (RtMemoryStatusCodeTable->RecordIndex == RtMemoryStatusCodeTable->MaxRecordsNumber) {
+ //
+ // Roll back record index.
+ //
+ RtMemoryStatusCodeTable->RecordIndex = 0;
+ }
+
+
+ return EFI_SUCCESS;
+}
+
+
+
diff --git a/EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c b/EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c
new file mode 100644
index 0000000000..9f1f922269
--- /dev/null
+++ b/EdkModulePkg/Universal/StatusCode/Dxe/SerialStatusCodeWorker.c
@@ -0,0 +1,184 @@
+
+/** @file
+ Serial I/O status code reporting worker.
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+ Module Name: SerialStatusCodeWorker.c
+
+**/
+
+EFI_SERIAL_IO_PROTOCOL *SerialIoProtocol;
+
+/**
+ Initialize serial status code worker.
+
+ @return The function always return EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiSerialStatusCodeInitializeWorker (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (
+ &gEfiSerialIoProtocolGuid,
+ NULL,
+ (VOID **) &SerialIoProtocol
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ 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. Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions¡± below.
+
+ @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. 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.
+ Type EFI_STATUS_CODE_VALUE is defined in ¡°Related Definitions¡± below.
+ Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
+
+ @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.
+ Type EFI_GUID is defined in InstallProtocolInterface() in the EFI 1.10 Specification.
+
+
+ @param Data This optional parameter may be used to pass additional data
+
+ @return The function always return EFI_SUCCESS.
+
+**/
+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;
+ VA_LIST Marker;
+ EFI_DEBUG_INFO *DebugInfo;
+
+ Buffer[0] = '\0';
+
+ if (Data != NULL &&
+ ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
+ //
+ // Print ASSERT() information into output buffer.
+ //
+ CharCount = AsciiSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ "\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 = AsciiVSPrint (
+ Buffer,
+ EFI_STATUS_CODE_DATA_MAX_SIZE,
+ Format,
+ Marker
+ );
+ } else if (Data != NULL &&
+ CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&
+ (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
+ //
+ // Print specific data into output buffer.
+ //
+ DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);
+ Marker = (VA_LIST) (DebugInfo + 1);
+ Format = (CHAR8 *) (((UINT64 *) Marker) + 12);
+
+ CharCount = AsciiVSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);
+ } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+ //
+ // Print ERROR information into output buffer.
+ //
+ CharCount = AsciiSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, "ERROR: C%x:V%x I%x", CodeType, Value, Instance);
+
+ //
+ // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
+ //
+
+ if (CallerId != NULL) {
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ " %g",
+ CallerId
+ );
+ }
+
+ if (Data) {
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ " %x",
+ Data
+ );
+ }
+
+ CharCount += AsciiSPrint (
+ &Buffer[CharCount - 1],
+ (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),
+ "\n\r"
+ );
+ } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+ CharCount = AsciiSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, "PROGRESS CODE: V%x I%x\n\r", Value, Instance);
+ } else {
+ CharCount = AsciiSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, "Undefined: C%x:V%x I%x\n\r", CodeType, Value, Instance);
+ }
+
+
+ if (FeaturePcdGet (PcdStatusCodeUseHardSerial)) {
+ //
+ // Callout to SerialPort Lib function to do print.
+ //
+ SerialPortWrite (Buffer, CharCount);
+ }
+ if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) {
+ SerialIoProtocol->Write (
+ SerialIoProtocol,
+ &CharCount,
+ Buffer
+ );
+ }
+
+ return EFI_SUCCESS;
+}