audk/EdkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCode.c

173 lines
4.3 KiB
C

/*++
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:
StatusCode.c
Abstract:
Status Code Architectural Protocol implementation as defined in Tiano
Architecture Specification.
This driver also depends on the DataHub, and will log all status code info
to the DataHub. Fatal Errors are Printed to Standard Error (StdErr) and not
logged to the data hub (If you crash what good is the data in the data hub).
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
--*/
#include "StatusCode.h"
EFI_LOCK mStatusCodeLock;
BOOLEAN mStatusCodeFlag = FALSE;
//
// Function implemenations
//
EFI_STATUS
EFIAPI
StatusCodeReportStatusCode (
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
)
/*++
Routine Description:
Calls into the platform library which dispatches the platform specific
listeners. For NT environments we still call back into PEI because the
ReportStatusCode functionality requires Win32 services and is built into
the SecMain.exe utility.
Arguments:
(See Tiano Runtime Specification)
Returns:
None
--*/
{
EFI_STATUS Status;
//
// Acquire the lock required to update mStatusCodeFlag
//
Status = EfiAcquireLockOrFail (&mStatusCodeLock);
if (EFI_ERROR (Status)) {
//
// Check for reentrancy of the lock
//
return EFI_DEVICE_ERROR;
}
//
// Check to see if we are already in the middle of a ReportStatusCode()
//
if (mStatusCodeFlag) {
EfiReleaseLock (&mStatusCodeLock);
return EFI_DEVICE_ERROR;
}
//
// Set the flag to show we are in the middle of a ReportStatusCode()
//
mStatusCodeFlag = TRUE;
//
// Release the lock for updating mStatusCodeFlag
//
EfiReleaseLock (&mStatusCodeLock);
//
// Go do the work required to report a status code
//
RtPlatformReportStatusCode (CodeType, Value, Instance, CallerId, Data);
//
// Acquire the lock required to update mStatusCodeFlag
//
Status = EfiAcquireLockOrFail (&mStatusCodeLock);
if (EFI_ERROR (Status)) {
//
// Check for reentrancy of the lock
//
return EFI_DEVICE_ERROR;
}
//
// Clear the flag to show we are no longer in the middle of a ReportStatusCode()
//
mStatusCodeFlag = FALSE;
//
// Release the lock for updating mStatusCodeFlag
//
EfiReleaseLock (&mStatusCodeLock);
return EFI_SUCCESS;
}
//
// Protocol instance, there can be only one.
//
EFI_STATUS
InitializeStatusCode (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Install Driver to produce Report Status Code Arch Protocol
Arguments:
(Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
Returns:
EFI_SUCCESS - Logging Hub protocol installed
Other - No protocol installed, unload driver.
--*/
{
EfiInitializeLock (&mStatusCodeLock, EFI_TPL_HIGH_LEVEL);
//
// Call the platform hook to initialize the different listeners.
//
RtPlatformStatusCodeInitialize ();
//
// Register a protocol that EfiUtilityLib can use to implement DEBUG () and ASSERT ()
// Macros.
//
InstallStatusCodeDebugAssert ();
return EFI_SUCCESS;
}