diff options
Diffstat (limited to 'Core/EM/StatusCode')
-rw-r--r-- | Core/EM/StatusCode/SerialStatusCode.c | 358 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCode.chm | bin | 0 -> 87667 bytes | |||
-rw-r--r-- | Core/EM/StatusCode/StatusCode.cif | 17 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCode.mak | 200 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCode.sdl | 280 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCodeCommon.c | 1142 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCodeDxe.c | 883 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCodeInt.h | 125 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCodeMap.c | 278 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCodePei.c | 492 | ||||
-rw-r--r-- | Core/EM/StatusCode/StatusCodeRuntime.c | 768 |
11 files changed, 4543 insertions, 0 deletions
diff --git a/Core/EM/StatusCode/SerialStatusCode.c b/Core/EM/StatusCode/SerialStatusCode.c new file mode 100644 index 0000000..1aefcde --- /dev/null +++ b/Core/EM/StatusCode/SerialStatusCode.c @@ -0,0 +1,358 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/StatusCode/SerialStatusCode.c 13 1/22/13 4:56p Oleksiyy $ +// +// $Revision: 13 $ +// +// $Date: 1/22/13 4:56p $ +//***************************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/StatusCode/SerialStatusCode.c $ +// +// 13 1/22/13 4:56p Oleksiyy +// [TAG] EIP112774 +// [Category] Bug Fix +// [Severity:] Normal +// [Symptom:] CPU Exception occurs when TRACE is used in SMM Handler +// [Root Cause] pBS, used in Delay function, do not exist during runtime. +// [Solution] Delay replaced with dummy "for" cycle in SerialOutput +// function. +// [Files] StatusCodeCommon.c +// +// +// 12 3/18/11 12:33p Oleksiyy +// [TAG] EIP54959 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] No debug output in projects with no SIO. +// [RootCause] Dependency from SIO added to sdl. +// [Solution] Dependency from SIO removed from SerialOutput eLink and +// moved directly to SerialOutput function body. +// +// [Files] SeriaStatusCode.c and StatusCode.sdl +// +// 11 10/01/10 6:08p Oleksiyy +// Issue Number: 43888 +// +// Category: Bug Fix +// +// Symptom: System hang endlesly if com port not working and Debug is ON +// +// Severity: Normal +// +// Root Cause: Infinite loop in SerialOutput. +// +// Solution: SEND_BYTE_DELEY and SEND_BYTE_ATEMPTS values is added. In +// SendByte SEND_BYTE_DELEY atempts will be made in loop until the serial +// port is ready for the next byte. +// +// Files: SeriaStatusCode.c, StausCode.sdl +// +// 10 5/03/10 1:17a Rameshr +// Issue:Need to handle different Base Hz values for SerialStatusCode, +// Terminal, and Legacy Serial Redirection. +// Solution: Moved Uart input clock into Core.sdl token and used in all +// the above modules. +// EIP: 37332 +// +// 9 11/13/09 4:30p Felixp +// Buffer overflow protection is added (calls to Sprintf replaced with +// Sprintf_s). +// +// 8 7/09/09 5:18p Oleksiyy +// Files clean-up some headers added +// +// 7 3/05/09 1:41p Felixp +// Major update of the StatusCode module. +// See Label Comments and Release Notes in StatusCode.chm for more +// details. +// +// 5 8/24/06 3:33p Felixp +// Preliminary x64 support (work in progress) +// +// 4 5/04/06 12:01p Robert +// Updated to support core release 4.4.10 +// +// 15 6/07/05 7:23p Felixp +// Moving toward generic Status Code module +// +// 13 1/20/05 11:31a Felixp +// StatusCodes.h renamed to AmiStatusCode.h +// +// 12 1/18/05 3:21p Felixp +// PrintDebugMessage renamed to Trace +// +// 11 11/15/04 10:35 Dougm +// Change the initialization of SIO +// +// 9 11/10/04 5:21p Felixp +// Serial output implementation changed to send '\r' before every '\n' +// +//***************************************************************************** +//<AMI_FHDR_START> +// +// Name: SerialStatusCode.c +// +// Description: Implementation of the serial port status code handler. +// +//<AMI_FHDR_END> +//***************************************************************************** +#include <PEI.h> +#include <StatusCodes.h> +#include <AMILIB.h> +#include <token.h> + +//---------------------------------------------------------------------------- +// Local constant definitions +#define CONFIG_PORT0 0x2E +#define INDEX_PORT0 0x2E +#define DATA_PORT0 0x2F +#define SEND_BYTE_DELEY 0x200 +#define SEND_BYTE_ATEMPTS 0x10 + +#ifdef DEBUG_COM_PORT_ADDR +#define COM_BASE_ADDR DEBUG_COM_PORT_ADDR +#else +#define COM_BASE_ADDR 0x03f8 +#endif +#define LSR_OFFSET 0x05 +#define LCR_OFFSET 0x03 +#define DIV_MSB 0x01 +#define DIV_LSB 0 + +#define TRANSMIT_READY_BIT 0x020 +#ifdef UART_INPUT_CLOCK +UINTN UartInputClock=UART_INPUT_CLOCK; +#else +// +// Set the default value((24000000/13)MHz input clock) if the UART_INPUT_CLOCK SDL token is not present. +// +UINTN UartInputClock=1843200; +#endif + +#define BAUD_RATE_DIVISOR 115200 + +#define DATA_BITS 3 // 0 - 5 bits / 1 - 6 bits +// 2 - 7 bits / 3 - 8 bits +// RSP BUGBUG #define STOP_BIT 0 // 0 - 1 stop bit +#define STOP_BIT 1 // 0 - 1 stop bit +// 1 - mutiple bits depending on the databits +#define PARITY_BITS 0 // 0 - None / 1 enables parity +#define BREAK_BIT 0 // 0 - No break +#define DLAB_BIT 1 // 0 - Divisor Latch Disabled +// 1 - Divisor Latch Enabled + +//---------------------------------------------------------------------------- +// Module specific type definitions + + +//---------------------------------------------------------------------------- +// Function Prototypes +EFI_STATUS SerialData( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN EFI_STATUS_CODE_DATA *Data, + OUT UINT8 *String +); +VOID Delay(EFI_PEI_SERVICES **PeiServices, UINT32 Microseconds); +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SendByte +// +// Description: Writes the given byte to the serial port +// +// Input: +// UINT8 Byte - a byte to write to the serial port +// +// Output: TRUE - Byte was sent, FALSE - serial port was not ready +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +BOOLEAN SendByte(UINT8 Byte) +{ + UINT8 Buffer8; + UINT32 Cntr = 0; + + do + { + // Read the ready signal to see if the serial port is + // ready for the next byte. + Buffer8 = IoRead8(COM_BASE_ADDR + LSR_OFFSET); + // Increment timeout counter. + Cntr++; + // Loop until the serial port is ready for the next byte. + } + while ( (Cntr < SEND_BYTE_DELEY) && + ((Buffer8 & TRANSMIT_READY_BIT) == FALSE) ); + if (Cntr < SEND_BYTE_DELEY){ + + IoWrite8(COM_BASE_ADDR, Byte); + return TRUE; + } else return FALSE; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SerialOutput +// +// Description: Writes the given string to the serial port byte by byte +// using the function SendByte. +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices - pointer to the PEI Boot Services table +// CHAR8 *String - String to be sent over the serial port +// +// Output: EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SerialOutput( + IN EFI_PEI_SERVICES **PeiServices, + IN CHAR8 *String +) +{ +#if SERIAL_STATUS_SUPPORT + UINT8 *Buffer, i; + UINT32 Delay; + BOOLEAN ByteSent; + + if (String == NULL) return EFI_SUCCESS; + // first make data useable + Buffer = String; + + // now send data one byte at a time until the string hits the end of string + // or we hit the max number of characters + while (*Buffer) + { + // replace "\n" with "\r\n" + for (i = 0; i <= SEND_BYTE_ATEMPTS; i++){ + ByteSent = TRUE; + + if (*Buffer=='\n') ByteSent = SendByte('\r'); + + if (ByteSent) ByteSent = SendByte(*Buffer); + + if (ByteSent) break; + else + for (Delay = 0; Delay <= 100000; Delay++); + } + + // move Data pointer to the next byte if previous was sent + if (ByteSent) Buffer++; + else return EFI_SUCCESS; + } +#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SerialStatusInit +// +// Description: +// The function programs the stop bits, data bits, and baud rate +// of the com port and outputs the debug message "Status Code Available." +// NOTE: This function does not assumes Super I/O has already been initialized. +// +// Input: +// IN EFI_FFS_FILE_HEADER *FfsHeader +// IN EFI_PEI_SERVICES **PeiServices - pointer to the PEI Boot Services table +// Output: +// EFI_SUCCESS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SerialStatusInit( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +) +{ + UINT8 Data8; + UINT16 Divisor; + UINTN Remainder; + + // + // Compute the baud rate divisor. + // + Divisor = (UINT32) Div64 (UartInputClock, + ((UINT32)BAUD_RATE_DIVISOR * 16), + &Remainder); + if ( Remainder ) { + Divisor += 1; + } + + if ((Divisor == 0) || (Divisor & 0xffff0000)) { + return EFI_INVALID_PARAMETER; + } + + // Programm Serial port + // Set Line Control Register (LCR) + Data8 = DLAB_BIT << 7 | STOP_BIT << 2 | DATA_BITS; + IoWrite8(COM_BASE_ADDR + LCR_OFFSET, Data8 ); + + IoWrite8(COM_BASE_ADDR + DIV_LSB, Divisor & 0xFF); + IoWrite8(COM_BASE_ADDR + DIV_MSB, Divisor >> 8); + + // Clear DLAB bit in LCR + Data8 &= ~((UINT8)DLAB_BIT << 7); + IoWrite8(COM_BASE_ADDR + LCR_OFFSET, Data8 ); +#ifdef EFI_DEBUG +#ifndef PEI_STATUS_CODE + SerialOutput(PeiServices, "DXE Status Code Available\n"); +#else + SerialOutput(PeiServices, "Status Code Available\n"); +#endif +#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SerialStatusInit +// +// Description: +// The function sends "Checkpoint #" string to serial port +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices - pointer to the PEI Boot Services table +// UINT8 Checkpoint - Checkpoint to send +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SerialCheckpoint(EFI_PEI_SERVICES **PeiServices, UINT8 Checkpoint) +{ + char s[20]; + Sprintf_s(s, sizeof(s), "Checkpoint %X\n",Checkpoint); + SerialOutput(PeiServices, s); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/StatusCode/StatusCode.chm b/Core/EM/StatusCode/StatusCode.chm Binary files differnew file mode 100644 index 0000000..5acc724 --- /dev/null +++ b/Core/EM/StatusCode/StatusCode.chm diff --git a/Core/EM/StatusCode/StatusCode.cif b/Core/EM/StatusCode/StatusCode.cif new file mode 100644 index 0000000..d13f4bb --- /dev/null +++ b/Core/EM/StatusCode/StatusCode.cif @@ -0,0 +1,17 @@ +<component> + name = "StatusCode" + category = eModule + LocalRoot = "Core\EM\StatusCode\" + RefName = "StatusCode" +[files] +"StatusCode.mak" +"StatusCode.sdl" +"StatusCodePei.c" +"StatusCodeDxe.c" +"StatusCodeCommon.c" +"StatusCodeInt.h" +"SerialStatusCode.c" +"StatusCodeMap.c" +"StatusCode.chm" +"StatusCodeRuntime.c" +<endComponent> diff --git a/Core/EM/StatusCode/StatusCode.mak b/Core/EM/StatusCode/StatusCode.mak new file mode 100644 index 0000000..05522b3 --- /dev/null +++ b/Core/EM/StatusCode/StatusCode.mak @@ -0,0 +1,200 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/BIN/Modules/StatusCode/StatusCode.mak 17 10/07/10 4:39p Oleksiyy $ +# +# $Revision: 17 $ +# +# $Date: 10/07/10 4:39p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Modules/StatusCode/StatusCode.mak $ +# +# 17 10/07/10 4:39p Oleksiyy +# Minor fix of StatusCodeRuntime support. +# +# 16 10/06/10 4:31p Oleksiyy +# Issue Number: 39752 +# +# Category: Improvement +# +# Description: Runtime Staus Code support is added. +# +# Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c, +# CsmLib.c, AmiDxeLib.h and StatusCode eModule. +# +# 15 3/05/09 1:41p Felixp +# Major update of the StatusCode module. +# See Label Comments and Release Notes in StatusCode.chm for more +# details. +# +# 14 4/22/08 5:56p Felixp +# Bug fix (project did not compile in IA32 mode). +# +# 8 3/06/08 4:12p Felixp +# Differences in IA32 and x64 build rules has been removed. +# +# 6 4/20/07 5:10p Felixp +# Updated to use new Status Code infrastructure +# +# 2 6/16/05 11:10a Felixp +# module reallocated to RAM once it is available +# +# 22 6/08/05 5:59p Felixp +# Beep Codes added +# SerialStatusCode.c moved to StatusCode component +# +# 21 6/07/05 7:23p Felixp +# Moving toward generic Status Code module +# +# 20 1/18/05 3:21p Felixp +# PrintDebugMessage renamed to Trace +# +# 19 11/01/04 8:44a Felixp +# +# 18 10/22/04 10:24a Felixp +# Status Code updated to use PEIM_HOB to pass status code pointer to DXE +# +# 17 9/21/04 10:50a Robert +# added standard library support in the build process +# +# 16 7/13/04 10:42a Felixp +# +# 15 4/10/04 2:17p Felixp +# +# 14 4/09/04 11:49a Robert +# Adding string support for displaying, Type, Severity, Class, and +# SubClass for unknown error types +# +# 13 4/07/04 5:21p Robert +# fixed up DXE part of status Code Protocol, the mak file should now make +# the available to both DXE and PEI. In addition, it should add a +# dependency expression +# +# 12 3/29/04 12:41p Markw +# Moved EfiStatusCode.h into include component. Deleted this reference in +# makefile. +# +# 4 2/06/04 2:46a Felixp +# - Support for VC6 tools +# - bug fixes +# - component AddOn added +# +# 2 1/18/04 8:32a Felixp +# From now on, OBJ files are created in a component specific subdirectory +# of $(BUILD_DIR) +# +# 1 1/15/04 5:18p Robert +# +#********************************************************************** +#<AMI_FHDR_START> +# +# Name: StatusCode.mak +# +# Description: +# Builds PEI and DXE StatusCode modules. +# Two libraries StatusCodePei.lib and StatusCodeDxe.lib +# are built and these are linked with CORE_PEI and CORE_DXE +# respectively. +# +#<AMI_FHDR_END> +#********************************************************************** +all : StatusCode + +STATUS_CODE_COMMON_OBJECTS=\ +$$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeCommon.obj\ +$$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeMap.obj\ +$$(BUILD_DIR)\$(STATUS_CODE_DIR)\SerialStatusCode.obj\ + +STATUS_CODE_PEI_OBJECTS=\ +$(STATUS_CODE_COMMON_OBJECTS)\ +$$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodePei.obj + +STATUS_CODE_DXE_OBJECTS=\ +$(STATUS_CODE_COMMON_OBJECTS)\ +$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeDxe.obj + +STATUS_CODE_RUNTIME_OBJECTS=\ +$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeRuntime.obj + +STATUS_CODE_EXT_HEADERS=\ +$(BUILD_DIR)\token.h\ +$(BUILD_DIR)\StatusCodeELinks.h + +StatusCode : StatusCodePei StatusCodeDxe StatusCodeRuntime + +StatusCodePei : $(BUILD_DIR)\StatusCodeELinks.h StatusCodePeiBin +StatusCodeDxe : $(BUILD_DIR)\StatusCodeELinks.h StatusCodeDxeBin +StatusCodeRuntime : $(BUILD_DIR)\StatusCodeELinks.h StatusCodeRuntimeBin + +$(BUILD_DIR)\StatusCode.mak : $(STATUS_CODE_DIR)\$(@B).cif $(STATUS_CODE_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(STATUS_CODE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +CORE_PEIBin : $(BUILD_DIR)\StatusCodePei.lib +CORE_DXEBin : $(BUILD_DIR)\StatusCodeDxe.lib +RUNTIMEBin : $(BUILD_DIR)\StatusCodeRuntime.lib + +$(BUILD_DIR)\StatusCodePei.lib : StatusCodePei +$(BUILD_DIR)\StatusCodeDxe.lib : StatusCodeDxe +$(BUILD_DIR)\StatusCodeRuntime.lib : StatusCodeRuntime + +$(BUILD_DIR)\StatusCodeELinks.h : $(BUILD_DIR)\token.h $(BUILD_DIR)\StatusCode.mak + $(ECHO) #define INIT_LIST $(StatusCodeInitialize) > $@ + $(ECHO) #define STRING_LIST $(ReportStringStatus) >> $@ + $(ECHO) #define SIMPLE_LIST $(ReportSimpleStatus) >> $@ + $(ECHO) #define MISC_LIST $(ReportMiscStatus) >> $@ + $(ECHO) #define CHECKPOINT_LIST $(ReportCheckpoint) >> $@ + $(ECHO) #define PEI_ERROR_CODE_ACTIONS $(PeiErrorCodeActions) >> $@ + $(ECHO) #define DXE_ERROR_CODE_ACTIONS $(DxeErrorCodeActions) >> $@ + +StatusCodePeiBin : $(AMIPEILIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\StatusCode.mak all\ + BUILD_DIR=$(BUILD_DIR)\IA32\ + "OBJECTS=$(STATUS_CODE_PEI_OBJECTS)"\ + "EXT_HEADERS=$(STATUS_CODE_EXT_HEADERS)"\ + "MY_DEFINES=/DPEI_STATUS_CODE"\ + TYPE=PEI_LIBRARY LIBRARY_NAME=$(BUILD_DIR)\StatusCodePei.lib + +StatusCodeDxeBin: $(AMIDXELIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\StatusCode.mak all\ + "OBJECTS=$(STATUS_CODE_DXE_OBJECTS)"\ + "EXT_HEADERS=$(STATUS_CODE_EXT_HEADERS)"\ + "MY_DEFINES=/DDXE_STATUS_CODE"\ + TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\StatusCodeDxe.lib + +StatusCodeRuntimeBin: $(BUILD_DIR)\StatusCodeDxe.lib + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\StatusCode.mak all\ + "OBJECTS=$(STATUS_CODE_RUNTIME_OBJECTS)"\ + "EXT_HEADERS=$(STATUS_CODE_EXT_HEADERS)"\ + "MY_DEFINES=/DRUNTIME_STATUS_CODE"\ + TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\StatusCodeRuntime.lib + +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2010, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** diff --git a/Core/EM/StatusCode/StatusCode.sdl b/Core/EM/StatusCode/StatusCode.sdl new file mode 100644 index 0000000..5ced211 --- /dev/null +++ b/Core/EM/StatusCode/StatusCode.sdl @@ -0,0 +1,280 @@ +TOKEN + Name = "StatusCode_SUPPORT" + Value = "1" + Help = "Main switch to enable Status Code support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "STRING_STATUS_SUPPORT" + Value = "1" + Help = "Enables/Disables all string-based status code routines \defined by the ReportStringStatus eLink" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "SERIAL_STATUS_SUPPORT" + Value = "1" + Help = "Enables/Disables serail port status code routine" + TokenType = Boolean + TargetH = Yes + Token = "STRING_STATUS_SUPPORT" "=" "1" + Token = "SIO_SUPPORT" "=" "1" +End + +TOKEN + Name = "RUNTIME_TRACE_SUPPORT" + Value = "1" + Help = "Enables/Disables support of trace messages in Runtime" + TokenType = Boolean + TargetH = Yes + Token = "DEBUG_MODE" "!=" "0" +End + +TOKEN + Name = "DATAHUB_STATUS_SUPPORT" + Value = "1" + Help = "Enables/Disables logging of the status codes into a data hub" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "CONOUT_CHECKPOINTS_SUPPORT" + Value = "1" + Help = "Enables/Disables checkpoint display on the ConOut devices\(right bottom corner)" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "CON_OUT_CHECKPOINTS_IN_QUIET_MODE" + Value = "1" + Help = "Enables/Disables checkpoints display on the ConOut devices\in quiet mode (only in effect when CONOUT_CHECKPOINTS_SUPPORT is enabled)" + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "CHECKPOINT_PROGRESS_CODES_MAP" + Value = "ProgressCheckpointMap" + Help = "Name of the table that establishes mapping between progress codes and checkpoints.\Clone this token to support custom checkpoint lists." + TokenType = Expression + TargetH = Yes +End + +TOKEN + Name = "CHECKPOINT_ERROR_CODES_MAP" + Value = "ErrorCheckpointMap" + Help = "Name of the table that establishes mapping between error codes and checkpoints.\Clone this token to support custom checkpoint lists." + TokenType = Expression + TargetH = Yes +End + +TOKEN + Name = "BEEP_PROGRESS_CODES_MAP" + Value = "ProgressBeepMap" + Help = "Name of the table that establishes mapping between progress codes and number of beeps.\Clone this token to support custom beep codes." + TokenType = Expression + TargetH = Yes +End + +TOKEN + Name = "BEEP_ERROR_CODES_MAP" + Value = "ErrorBeepMap" + Help = "Name of the table that establishes mapping between error codes and number of beeps.\Clone this token to support custom beep codes." + TokenType = Expression + TargetH = Yes +End + +TOKEN + Name = "STATUS_CODE_VERSION" + Value = "16" + Help = "Version of the status code module." + TokenType = Integer + TargetMAK = Yes + TargetH = Yes + Lock = Yes +End + +PATH + Name = "STATUS_CODE_DIR" +End + +MODULE + Help = "Includes StatusCode.mak to Project" + File = "StatusCode.mak" +End + +ELINK + Name = "StatusCodeInitialize" + Help = "This is a list of initialization routines for status code subcomponents. The routines are called during initialization of the StatusCode module\The child eLink can be in one of the following formats:\'InitFunctionName,' - The function will be called in PEI as well as in DXE\'PEI(InitFunctionName),' - The function will only be called in PEI\'DXE(InitFunctionName),' - The function will only be called in DXE\" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "ReportSimpleStatus" + Help = "This is a list of status code routines that consume only status code type and value. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "ReportMiscStatus" + Help = "This is a list of status code routines that consume all available status code data. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "CheckPointStatus," + Parent = "ReportSimpleStatus" + Help = "This is a list of checkpoint routines. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\" + InvokeOrder = AfterParent +End + +ELINK + Name = "RUNTIME(CheckPointStatus)," + Parent = "ReportSimpleStatus" + Help = "This is a list of checkpoint routines. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\" + InvokeOrder = AfterParent +End + +ELINK + Name = "PeiInitStatusCode," + Parent = "PeiCoreInitialize" + InvokeOrder = AfterParent +End + +ELINK + Name = "BeepService," + Parent = "ReportMiscStatus" + Token = "BEEP_ENABLE" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "BeepStatus," + Parent = "ReportSimpleStatus" + Token = "BEEP_ENABLE" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "ReportStringStatus" + Help = "This is a list of status code routines that consume strings. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\" + Token = "STRING_STATUS_SUPPORT" "=" "1" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "ReportCheckpoint" + Help = "This is a list of checkpoint display routines. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "Port80Checkpoint," + Parent = "ReportCheckpoint" + Help = "Port 0x80 checkpoints" + InvokeOrder = AfterParent +End + +ELINK + Name = "RUNTIME(Port80Checkpoint)," + Parent = "ReportCheckpoint" + Help = "Port 0x80 checkpoints" + InvokeOrder = AfterParent +End + +ELINK + Name = "DXE(DataHubStatusCode)," + Parent = "ReportMiscStatus" + Help = "DataHub status code routine (DXE only).\Logs prorgess and error status codes into data hub" + Token = "DATAHUB_STATUS_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "SerialOutput," + Parent = "ReportStringStatus" + Help = "Serial port string status code" + InvokeOrder = AfterParent +End + +ELINK + Name = "RUNTIME(SerialOutput)," + Parent = "ReportStringStatus" + Help = "Serial port string status code" + Token = "SERIAL_STATUS_SUPPORT" "=" "1" + Token = "RUNTIME_TRACE_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "DXE(ConOutCheckpoint)," + Parent = "ReportCheckpoint" + Help = "ConOut Checkpoints (DXE only)" + Token = "CONOUT_CHECKPOINTS_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "SerialCheckpoint," + Parent = "ReportCheckpoint" + Help = "Checkpoints over Serial Port" + Token = "SERIAL_STATUS_SUPPORT" "=" "1" + Disable = Yes + InvokeOrder = AfterParent +End + +ELINK + Name = "SerialStatusInit," + Parent = "StatusCodeInitialize" + Help = "Serial port status code initialization routine" + Token = "SERIAL_STATUS_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "DXE(ConOutCpInit)," + Parent = "StatusCodeInitialize" + Help = "ConOut checkpoints initialization routine (DXE only)" + Token = "CONOUT_CHECKPOINTS_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "DXE(DataHubInit)," + Parent = "StatusCodeInitialize" + Help = "DataHub status code initialization routine (DXE only).\Logs prorgess and error status codes into data hub" + Token = "DATAHUB_STATUS_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "PeiErrorCodeActions" + Help = "List of actions to perform when error of a particular type is detected in PEI.\The child eLink has the following format: \ERROR_ACTION(Value,Action)\where\Value - error code value (error values are defined in AmiStatusCodes.h)\Action - error action. Function with the following interface:\VOID (ERROR_CODE_ACTION)(\ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value\);\Custom or standard action can be used.\The following standard actions are defined:\Halt, ResetOrHalt, ResetOrResume\" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "DxeErrorCodeActions" + Help = "List of actions to perform when error of a particular type is detected in DXE.\The child eLink has the following format: \ERROR_ACTION(Value,Action)\where\Value - error code value (error values are defined in AmiStatusCodes.h)\Action - error action. Function with the following interface:\VOID (ERROR_CODE_ACTION)(\ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value\);\Custom or standard action can be used.\The following standard actions are defined:\Halt, ResetOrHalt, ResetOrResume\" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "StatusCodeSmmEntry," + Parent = "RuntimeSmmInitialize" + InvokeOrder = BeforeParent +End + +ELINK + Name = "DxeInitStatusCode," + Parent = "DxeCoreInitialize" + InvokeOrder = BeforeParent +End + diff --git a/Core/EM/StatusCode/StatusCodeCommon.c b/Core/EM/StatusCode/StatusCodeCommon.c new file mode 100644 index 0000000..e694c8c --- /dev/null +++ b/Core/EM/StatusCode/StatusCodeCommon.c @@ -0,0 +1,1142 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeCommon.c 7 6/23/11 6:10p Oleksiyy $ +// +// $Revision: 7 $ +// +// $Date: 6/23/11 6:10p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeCommon.c $ +// +// 7 6/23/11 6:10p Oleksiyy +// [TAG] EIP56644 +// [Category] New Feature +// [Description] Implemented PPI and Protocols, described in a PI 1.2 +// Report Status Code Router specification. +// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h, +// StatusCodeCommon.c and StatusCodeRuntime.c +// +// 6 10/06/10 4:34p Oleksiyy +// Issue Number: 39752 +// +// Category: Improvement +// +// Description: Runtime Staus Code support is added. +// +// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c, +// CsmLib.c, AmiDxeLib.h and StatusCode eModule. +// +// 5 8/12/09 2:09p Felixp +// 1. Replace Sprintf calls with Sprint_s (to protect from buffer +// overflow). +// 2. Fix format string in ReportData function. +// +// 4 7/30/09 10:51a Felixp +// Minor Bug fix: EIP 24740. ReportData updated to extract status code +// type from the 'Type' parameter. +// +// 3 7/28/09 5:11p Vyacheslava +// Bug fix. EIP#24453: Synopsis: CPU exception when printing long +// debug messages. +// +// 2 7/09/09 5:18p Oleksiyy +// Files clean-up some headers added +// +// 1 3/05/09 1:40p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: StatusCodeCommon.c +// +// Description: +// This file contains routines used in PEI and DXE status code modules. +// It contains two main function groups: +// - Status Code Library (functions utilized throughout the component). +// - Status Code initialization code. The initialization code enables +// support of the multiple eLinks exposed by the status code module. +// The eLinks are described in the AMI Aptio 4.x StatusCode Porting Guide. +// +//<AMI_FHDR_END> +//********************************************************************** +#include <AmiLib.h> +#include <Token.h> +#include <StatusCodeELinks.h> +#include "StatusCodeInt.h" +#if PI_SPECIFICATION_VERSION >= 0x00010014 + +BOOLEAN RouterRecurciveStatus = FALSE; +#ifndef PEI_STATUS_CODE +extern BOOLEAN InRscHandlerNotification; +#include <Protocol/ReportStatusCodeHandler.h> + +extern EFI_BOOT_SERVICES *pBS; +ROUTER_STRUCT_HEADER *RouterCallbackStr = NULL; + +BOOLEAN SmmRouter = FALSE; +#endif +#endif +//------------------------------RouterEnd +BOOLEAN StatusRuntime = FALSE; +#ifdef PEI_STATUS_CODE +#define PEI(x) x +#define DXE(x) DUMMY_HANDLER +#define RUNTIME(x) DUMMY_HANDLER +#elif defined(DXE_STATUS_CODE) +#define PEI(x) DUMMY_HANDLER +#define DXE(x) x +#define RUNTIME(x) DUMMY_HANDLER +#endif + +#pragma pack(1) +typedef struct +{ + UINT32 ErrorLevel; + // 12 * sizeof (UINT64) Var Arg stack + // ascii EFI_DEBUG () Format string +} EFI_DEBUG_INFO; +#pragma pack() +#ifdef PEI_STATUS_CODE +#define EFI_MAX_STRING_LENGTH 256 +#else +#define EFI_MAX_STRING_LENGTH 2048 +#endif + +//---------------------------------------------------------------------------- +// GUID Definitions +#define EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID \ + {0x9A4E9246, 0xD553, 0x11D5, 0x87, 0xE2, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xb9} +#define EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID \ + {0xDA571595, 0x4D99, 0x487C, 0x82, 0x7C, 0x26, 0x22, 0x67, 0x7D, 0x33, 0x07} +static EFI_GUID gEfiStatusCodeDataTypeDebugGuid = EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID; +static EFI_GUID gEfiStatusCodeDataTypeAssertGuid = EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID; +EFI_GUID gDataTypeStringGuid = EFI_STATUS_CODE_DATA_TYPE_STRING_GUID; +EFI_GUID gSpecificDataGuid = EFI_STATUS_CODE_SPECIFIC_DATA_GUID; + + +//********************************************************************** +// Status Code Library (functions used throughout the module) +//********************************************************************** +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: FindByteCode +// +// Description: Match "Value" to Map->Value and return Map->Byte. +// +// Input: +// STATUS_CODE_TO_BYTE_MAP *Map - Pointer to a table (array of structures) that maps status code value (EFI_STATUS_CODE_VALUE) to a byte (UINT8) domain specific value. +// EFI_STATUS_CODE_VALUE Value - status code to map +// +// Output: +// UINT8 - domain specific mapping of the Value +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +UINT8 FindByteCode(STATUS_CODE_TO_BYTE_MAP *Map, EFI_STATUS_CODE_VALUE Value) +{ + while (Map->Value!=0) + { + if (Map->Value==Value) + { + return Map->Byte; + } + + Map++; + } + + return 0; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReportAssertString +// +// Description: This function creates a string from the ASSERT data +// +// Input: +// IN EFI_STATUS_CODE_DATA *Data - Pointer to the beginning of the ASSERT data +// OUT UINT8 *String - Pointer to the beginning of a byte String array +// +// Output: *String - Contains information from the ASSERT data +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReportAssertString(IN EFI_STATUS_CODE_DATA *Data, OUT UINT8 *String) +{ + EFI_DEBUG_ASSERT_DATA *AssertData; + CHAR8 *FileName; + UINT32 LineNum; + CHAR8 *Desc; + + // gather the data for the different parts of the Assert Info + AssertData = (EFI_DEBUG_ASSERT_DATA *)Data; + +// TODO: Change this to use the FileName member of the data structure +// be aware that the FileName member is another data structure + // get filename +// FileName = AssertData->FileName.String; + FileName = (CHAR8 *) (AssertData + 1); + + // get line number + LineNum = AssertData->LineNumber; + +// TODO: Change this to use the FileNameSize in the Data Structure. +// Intel does not fill this in their worker function, so it is a junk value + + // get description +// Desc = Filename + AssertData->FileNameSize; + Desc = FileName + Strlen(FileName) + 1; + + Sprintf_s(String, EFI_MAX_STRING_LENGTH, "ASSERT: %s, (%d) - %s", FileName, LineNum, Desc); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReportData +// +// Description: This function creates a string for error types that have not +// been predefined by the spec. This string contains the information in +// the Type and Value parameters. +// +// Input: +// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error +// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused +// the error +// IN EFI_STATUS_CODE_DATA *Data - Data field that contains strings and values to be reported +// OUT UINT8 *String - Pointer to the beginning of a byte String array +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReportData( + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value, + IN EFI_STATUS_CODE_DATA *Data, OUT UINT8 *String +) +{ + if (STATUS_CODE_TYPE(Type)!=EFI_ERROR_CODE) return EFI_UNSUPPORTED; + + Sprintf_s( + String, EFI_MAX_STRING_LENGTH, + "ERROR: Type:%X; Severity:%X; Class:%X; Subclass:%X; Operation: %X\n", + Type&0xFF, Type>>24, Value >> 24, (Value >> 16)& 0xFF, Value & 0xFFFF + ); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReportDebugInfo +// +// Description: This function creates a string from the debug informatoin packaged into +// Intel-specific(not defined in the standard spec) EFI_DEBUG_INFO structure. +// +// Input: IN EFI_STATUS_CODE_DATA *Data - Pointer to the beginning of the ASSERT data +// +// Output: OUT UINT8 *String - Contains information in the ASSERT data +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReportDebugInfo(IN EFI_STATUS_CODE_DATA *Data, OUT UINT8 *String) +{ + va_list Marker; + CHAR8 *Format; + EFI_DEBUG_INFO *DebugInfo = (EFI_DEBUG_INFO *)(Data + 1); + + // The first 12 * UINTN bytes of the string are really an + // argument stack to support varargs on the Format string. + Marker = (va_list) (DebugInfo + 1); + Format = (CHAR8 *)(((UINT64 *)Marker) + 12); + + Sprintf_s_va_list(String, EFI_MAX_STRING_LENGTH, Format, Marker); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CreateString +// +// Description: This function converts the Type, Value, and Data into a string +// that can be easily output to any console: serial, screen, data storage, etc. +// +// Input: +// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error +// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused +// the error +// IN EFI_STATUS_CODE_DATA *Data - Data field that contains strings and values to be reported +// OUT UINT8 *String - Pointer to the beginning of a byte String array +// +// Output: EFI_STATUS +// *String - points to the string that was created +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS CreateString( + IN EFI_STATUS_CODE_TYPE Type, + IN EFI_STATUS_CODE_VALUE Value, + IN EFI_STATUS_CODE_DATA *Data, + OUT UINT8 *String +) +{ + EFI_STATUS_CODE_STRING_DATA *StrData; + CHAR8 *StrAscii; + CHAR16 *StrUnicode; + UINT16 Count = 0; + + if (Data != NULL) + { + // Check to see if the optional Data parameter is a standard string or + // if it is a more complex data structure + if (!guidcmp(&(Data->Type), &gDataTypeStringGuid)) + { + // set pointers to different parts of the data structure for + // easier access to the data it contains + StrData = ( EFI_STATUS_CODE_STRING_DATA *)Data; + + // Set up pointer to the beginning of both parts of the union + StrAscii = StrData->String.Ascii; + StrUnicode = StrData->String.Unicode; + + // check for end of string or max length of output string + while ( ( ((StrData->StringType == EfiStringAscii) + && (*StrAscii != '\0')) + || ((StrData->StringType == EfiStringUnicode) + && (*StrUnicode != '\0')) ) + && (Count < (EFI_MAX_STRING_LENGTH -1)) + ) + { + if (StrData->StringType == EfiStringAscii) + { + String[Count++] = *(StrAscii++); + } + + else if (StrData->StringType == EfiStringUnicode) + { + String[Count] = (UINT8)(*(StrUnicode++)); + // advance to the next character in the string + Count+=2; + } + + else + { + return EFI_UNSUPPORTED; + } + } + + String[Count] = '\0'; + return EFI_SUCCESS; + } + + else if ( !guidcmp (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid) ) + { + ReportDebugInfo(Data, String); + } + + else if (!guidcmp(&(Data->Type), &gSpecificDataGuid)) + { + // This checks for an assert statement. Make a string of the data + // field + if ( ((Type & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) + && ((Type & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) + && ((Value & EFI_STATUS_CODE_OPERATION_MASK)== EFI_SW_EC_ILLEGAL_SOFTWARE_STATE) + && (Data != NULL) + ) + { + ReportAssertString(Data, String); + } + + else + { + ReportData(Type, Value, Data, String); + } + } + + else if ( !guidcmp (&Data->Type, &gEfiStatusCodeDataTypeAssertGuid) ) + { + //this is Intel specific GUID + //we have to use Data+1 because of Intel specific bug + ReportAssertString(Data+1, String); + } + + else + { + ReportData(Type, Value, Data, String); + } + } + + else // if (Data != NULL) + { + // If Data is NULL just report required data + ReportData(Type, Value, NULL, String); + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Halt +// +// Description: Error Code Action. +// Halts the execution. +// +// Input: +// VOID *PeiServices - not used +// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action. +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID Halt( + IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value +) +{ + EFI_DEADLOOP(); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ResetOrHalt +// +// Description: Error Code Action. +// Attempts to perform a system reset. If reset fails, halts the execution (calls Halt function). +// +// Input: +// VOID *PeiServices - not used +// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action. +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ResetOrHalt( + IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value +) +{ + ResetOrResume(PeiServices,Value); + Halt(PeiServices, Value); +} + +//********************************************************************** +// Status Code Initialization +//********************************************************************** +typedef EFI_STATUS (INIT_FUNCTION)(IN VOID *ImageHandler, IN VOID *ServicesTable); +typedef EFI_STATUS (STRING_FUNCTION)(IN VOID *PeiServices, IN CHAR8 *String); +typedef EFI_STATUS (SIMPLE_FUNCTION)( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +); +typedef EFI_STATUS (MISC_FUNCTION)( + IN VOID *PeiServices, + 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 +); +typedef VOID (CHECKPOINT_FUNCTION)(IN VOID *PeiServices, IN UINT8 Checkpoint); + +EFI_STATUS DummyInitHandler(IN VOID *ImageHandler, IN VOID *ServicesTable) {return EFI_SUCCESS;} +EFI_STATUS DummyStringHandler(IN VOID *PeiServices, IN CHAR8 *String) {return EFI_SUCCESS;} +EFI_STATUS DummySimpleHandler( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +) {return EFI_SUCCESS;} +EFI_STATUS DummyMiscHandler( + IN VOID *PeiServices, + 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 +) {return EFI_SUCCESS;} +VOID DummyCheckpointHandler(IN VOID *PeiServices, IN UINT8 Checkpoint) {} + +#define DUMMY_HANDLER DummyInitHandler +extern INIT_FUNCTION INIT_LIST EndOfInitList; +INIT_FUNCTION* InitPartsList[] = {INIT_LIST NULL}; +#undef DUMMY_HANDLER + +#define DUMMY_HANDLER DummyStringHandler +extern STRING_FUNCTION STRING_LIST EndOfStringList; +STRING_FUNCTION* StringList[] = {STRING_LIST NULL}; +#undef DUMMY_HANDLER + +#define DUMMY_HANDLER DummySimpleHandler +extern SIMPLE_FUNCTION SIMPLE_LIST EndOfSimpleList; +SIMPLE_FUNCTION* SimpleList[] = {SIMPLE_LIST NULL}; +#undef DUMMY_HANDLER + +#define DUMMY_HANDLER DummyMiscHandler +extern MISC_FUNCTION MISC_LIST EndOfMiscList; +MISC_FUNCTION* MiscList[] = {MISC_LIST NULL}; +#undef DUMMY_HANDLER + +#define DUMMY_HANDLER DummyCheckpointHandler +extern CHECKPOINT_FUNCTION CHECKPOINT_LIST EndOfCheckpointList; +CHECKPOINT_FUNCTION* CheckpointList[] = {CHECKPOINT_LIST NULL}; +#undef DUMMY_HANDLER + +typedef STATUS_CODE_TO_BYTE_MAP STATUS_CODE_TO_BYTE_MAP_ARRAY[]; + +extern STATUS_CODE_TO_BYTE_MAP_ARRAY +CHECKPOINT_PROGRESS_CODES_MAP, CHECKPOINT_ERROR_CODES_MAP, +BEEP_PROGRESS_CODES_MAP, BEEP_ERROR_CODES_MAP +; + +STATUS_CODE_TO_BYTE_MAP* CheckPointStatusCodes[] = +{ + //#define EFI_PROGRESS_CODE 0x00000001 + CHECKPOINT_PROGRESS_CODES_MAP, + //#define EFI_ERROR_CODE 0x00000002 + CHECKPOINT_ERROR_CODES_MAP + //#define EFI_DEBUG_CODE 0x00000003 +}; + +STATUS_CODE_TO_BYTE_MAP* BeepStatusCodes[] = +{ + //#define EFI_PROGRESS_CODE 0x00000001 + BEEP_PROGRESS_CODES_MAP, + //#define EFI_ERROR_CODE 0x00000002 + BEEP_ERROR_CODES_MAP + //#define EFI_DEBUG_CODE 0x00000003 +}; + +#define ERROR_ACTION(Value,Action) Action +#ifdef PEI_STATUS_CODE +extern ERROR_CODE_ACTION PEI_ERROR_CODE_ACTIONS EndOfActionList; +#else +extern ERROR_CODE_ACTION DXE_ERROR_CODE_ACTIONS EndOfActionList; +#endif +#undef ERROR_ACTION +#define ERROR_ACTION(Value,Action) {Value,&Action} + +ERROR_CODE_ACTION_MAP ErrorCodeActions[] = +{ +#ifdef PEI_STATUS_CODE + PEI_ERROR_CODE_ACTIONS +#endif +#ifdef DXE_STATUS_CODE + DXE_ERROR_CODE_ACTIONS +#endif + {0,0} +}; + + +#undef PEI +#undef DXE +#undef RUNTIME + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitStatusCodeParts +// +// Description: calls initialization routines of status code subcomponents +// registered under StatusCodeInitialize eLink. +// +// Input: +// IN VOID *ImageHandler +// IN VOID *ServicesTable +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID InitStatusCodeParts(IN VOID *ImageHandler, IN VOID *ServicesTable) +{ + UINTN i; + + for (i=0; InitPartsList[i]; i++) InitPartsList[i](ImageHandler,ServicesTable); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: StringStatusReport +// +// Description: Calls the string satus code handlers registered under ReportStringStatus eLink. +// +// Input: +// IN EFI_FFS_FILE_HEADER *FfsHeader +// IN CHAR8 *String +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID StringStatusReport(IN VOID *PeiServices, IN CHAR8 *String) +{ + UINTN i; + + for (i=0; StringList[i]; i++) StringList[i](PeiServices,String); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SimpleStatusReport +// +// Description: Calls simple status code handlers registered under ReportSimpleStatus eLink +// +// Input: +// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services +// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error +// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused +// the error +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID SimpleStatusReport( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +) +{ + UINTN i; + + for (i=0; SimpleList[i]; i++) SimpleList[i](PeiServices,Type,Value); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: MiscStatusReport +// +// Description: Calls Misc. status code handlers +// (handlers that consume all available status code data) +// registered under ReportMiscStatus eLink +// +// Input: +// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services +// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error +// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused +// the error +// IN UINT32 Instance - Instance +// IN EFI_GUID *CallerId OPTIONAL - The GUID of the caller function +// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID MiscStatusReport( + IN VOID *PeiServices, + 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 +) +{ + UINTN i; + + for (i=0; MiscList[i]; i++) MiscList[i](PeiServices,Type,Value,Instance,CallerId,Data); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckpointStatusReport +// +// Description: Calls checkpoint status code handlers registered under ReportCheckpoint eLink. +// +// Input: +// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services +// IN UINT8 Checkpoint - checkpoint +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID CheckpointStatusReport(IN VOID *PeiServices, IN UINT8 Checkpoint) +{ + UINTN i; + + for (i=0; CheckpointList[i]; i++) CheckpointList[i](PeiServices,Checkpoint); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PerformErrorCodeAction +// +// Description: +// Scans list of error actions defined by the PeiErrorCodeActions/DxeErrorCodeActions lists. +// If action corresponding to the passed in Value is found, performs the action. +// +// Input: +// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services +// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error +// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused +// the error +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID PerformErrorCodeAction( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +) +{ + ERROR_CODE_ACTION_MAP *Map = ErrorCodeActions; + + while (Map->Value!=0) + { + if (Map->Value==Value) + { + if (Map->Action!=NULL) + { + Map->Action(PeiServices,Value); + return; + } + } + + Map++; + } +} + +#if PI_SPECIFICATION_VERSION >= 0x00010014 + +BOOLEAN IsItRecursiveCall ( + IN OUT BOOLEAN *Value, + IN BOOLEAN CompareWith, + IN BOOLEAN SvitchTo + ) +{ + if (*Value == CompareWith) + { + *Value = SvitchTo; + return CompareWith; + } + else return *Value; + +} + +#ifndef PEI_STATUS_CODE +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReportDxeAndRtRouter +// +// Description: +// Top level status code reporting routine exposed by the status code protocol/PPI. +// Calls the various types of status code handlers +// (SimpleStatusReport, StringStatusReport, MiscStatusReport, PerformErrorCodeAction) +// Generates string from the status code data to pass to StringStatusReport function. +// +// Input: +// IN VOID *PeiServices - pointer to the PEI Boot Services table +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance - +// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function +// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReportDxeAndRtRouter ( + 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 + ) +{ + + RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry; + RSC_DATA_ENTRY *RscData; + EFI_STATUS Status; + VOID *NewBuffer = NULL, *Ptr; + EFI_TPL CurrentTpl = TPL_HIGH_LEVEL; + UINT32 i; + + if ((RouterCallbackStr == NULL) || (IsItRecursiveCall (&RouterRecurciveStatus, FALSE, TRUE) == TRUE)) + return EFI_ACCESS_DENIED; + for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++) + { + + if (i == 0) + Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER); + else + Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY); + CallbackEntry = Ptr; + + if (CallbackEntry->RscHandlerCallback == NULL) continue;//Unregistered function + + if (!StatusRuntime) + { + CurrentTpl = pBS->RaiseTPL (TPL_HIGH_LEVEL); + pBS->RestoreTPL (CurrentTpl); + } + + if ((CallbackEntry->Tpl >= CurrentTpl) || StatusRuntime) + { + CallbackEntry->RscHandlerCallback (Type, Value, Instance, CallerId, Data); + continue; + } + + + // If callback is registered with TPL lower than TPL_HIGH_LEVEL, event must be signaled at boot time to possibly wait for + // allowed TPL to report status code. Related data should also be stored in data buffer. + + RscData = (RSC_DATA_ENTRY *) (UINTN) CallbackEntry->EndPointer; + CallbackEntry->EndPointer += sizeof (RSC_DATA_ENTRY); + if (Data != NULL) + CallbackEntry->EndPointer += Data->Size; + + + // If data buffer is about to be used up (7/8 here), try to reallocate a buffer with double size, if not at TPL_HIGH_LEVEL. + + if (CallbackEntry->EndPointer > (CallbackEntry->StatusCodeDataBuffer + (CallbackEntry->BufferSize / 8) * 7)) + { + if ((CurrentTpl < TPL_HIGH_LEVEL) && !InRscHandlerNotification) + { + Status = pBS->AllocatePool (EfiRuntimeServicesData, CallbackEntry->BufferSize * 2, &NewBuffer); + //ASSERT_EFI_ERROR (Status); + if (NewBuffer != NULL && CallbackEntry->StatusCodeDataBuffer != NULL) + { + pBS->SetMem(NewBuffer, CallbackEntry->BufferSize * 2, 0); + MemCpy (NewBuffer, (VOID*)CallbackEntry->StatusCodeDataBuffer, CallbackEntry->BufferSize); + pBS->FreePool ((VOID *) (UINTN) CallbackEntry->StatusCodeDataBuffer); + } + + if (NewBuffer != NULL) + { + CallbackEntry->EndPointer = (EFI_PHYSICAL_ADDRESS) (UINTN) NewBuffer + (CallbackEntry->EndPointer - CallbackEntry->StatusCodeDataBuffer); + CallbackEntry->StatusCodeDataBuffer = (EFI_PHYSICAL_ADDRESS) (UINTN) NewBuffer; + CallbackEntry->BufferSize *= 2; + } + } + } + + + // If data buffer is used up, do not report for this time. + + if (CallbackEntry->EndPointer > (CallbackEntry->StatusCodeDataBuffer + CallbackEntry->BufferSize)) + continue; + + RscData->Type = Type; + RscData->Value = Value; + RscData->Instance = Instance; + if (CallerId != NULL) + MemCpy (&RscData->CallerId, CallerId, sizeof (EFI_GUID)); + + if (Data != NULL) + MemCpy (&RscData->Data, Data, Data->HeaderSize + Data->Size); + + Status = pBS->SignalEvent (CallbackEntry->Event); + + } + // Restore the Recursive status of report + + IsItRecursiveCall (&RouterRecurciveStatus, TRUE, FALSE); + return EFI_SUCCESS; +} +#endif +#endif +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReportStatusCode +// +// Description: +// Top level status code reporting routine exposed by the status code protocol/PPI. +// Calls the various types of status code handlers +// (SimpleStatusReport, StringStatusReport, MiscStatusReport, PerformErrorCodeAction) +// Generates string from the status code data to pass to StringStatusReport function. +// +// Input: +// IN VOID *PeiServices - pointer to the PEI Boot Services table +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance - +// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function +// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReportStatusCode ( + IN VOID *PeiServices, + 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 +) +{ +#if STRING_STATUS_SUPPORT + UINT8 String[EFI_MAX_STRING_LENGTH]; +#endif + SimpleStatusReport(PeiServices,Type,Value); +#if STRING_STATUS_SUPPORT + String[0] = '\0'; + CreateString(Type, Value, Data, String); + + // step through the useable data and display information as needed + // Serial data + if (String[0] != '\0') StringStatusReport(PeiServices,String); + +#endif + MiscStatusReport(PeiServices,Type,Value,Instance,CallerId,Data); + + if (STATUS_CODE_TYPE(Type)==EFI_ERROR_CODE) + PerformErrorCodeAction(PeiServices,Type,Value); +#ifndef PEI_STATUS_CODE +#if PI_SPECIFICATION_VERSION >= 0x00010014 + if ((PeiServices == NULL) && !SmmRouter) + ReportDxeAndRtRouter(Type, Value, Instance, CallerId, Data); +#endif +#endif + return EFI_SUCCESS; +} + +//********************************************************************** +// Status Code Transports +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Port80Checkpoint +// +// Description: Outputs checkpoint value to port 0x80 +// To support different checkpoint displaying hardware do not port this function. +// Use ReportCheckpoint eLink based interface instead. +// +// Input: +// VOID *PeiServices - pointer to the PEI Boot Services table, +// IN UINTN Checkpoint - checkpoint to display +// +// Output: +// EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID Port80Checkpoint(IN VOID *PeiServices, IN UINT8 Checkpoint) +{ + checkpoint(Checkpoint); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: CheckPointStatus +// +// Description: +// Looks up the checkpoint for the given status code Type +// and Value and calls CheckpointStatusReport function to invoke all checkpoint handlers. +// +// Input: +// IN VOID *PeiServices - pointer to the PEI Boot Services table +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// +// Output: +// EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS CheckPointStatus( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +) +{ + UINT8 n; + UINT32 CodeTypeIndex = STATUS_CODE_TYPE(Type) - 1; + + if (CodeTypeIndex >= sizeof(CheckPointStatusCodes)/sizeof(STATUS_CODE_TO_BYTE_MAP*) ) + return EFI_SUCCESS; + + n=FindByteCode(CheckPointStatusCodes[CodeTypeIndex],Value); + + if (n>0) CheckpointStatusReport(PeiServices,n); + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: BeepOn +// +// Description: Initiates generation of the sound corresponding +// to the passed in musical note/octave pair using legacy PC/AT speaker. +// +// Input: +// UINT8 note - a note to play +// UINT8 octave - an octave for the note +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID BeepOn(UINT8 note, UINT8 octave) +{ + // beep tones +#define note(x) ((119318200+(x)/2)/(x)) + UINT16 tones[8]={note(26163),note(29366),note(32963),note(34923),note(39200),note(44000),note(49388),note(26163*2)}; + UINT16 Frequency=tones[(note%8)]; + + if (octave-1>=0) Frequency>>=octave-1; + else Frequency<<=1-octave; + + //set up channel 1 (used for delays) + IoWrite8(0x43,0x54); + IoWrite8(0x41,0x12); + //set up channel 2 (used by speaker) + IoWrite8(0x43,0xb6); + IoWrite8(0x42,(UINT8)Frequency); + IoWrite8(0x42,(UINT8)(Frequency>>8)); + //turn the speaker on + IoWrite8(0x61,IoRead8(0x61)|3); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: BeepOff +// +// Description: Stops generation of the legacy PC/AT speaker sound started by the BeepOn routine. +// +// Input: +// VOID +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID BeepOff() +{ + IoWrite8(0x61,IoRead8(0x61)&0xfc); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Beep +// +// Description: Generates sound of the specified duration corresponding +// to the passed in musical note/octave pair using legacy PC/AT speaker. +// Control flow: +// BeepOn +// Delay +// BeepOff +// +// Input: +// VOID *PeiServices - pointer to the PEI Boot Services table +// UINT8 note - a note to play +// UINT8 octave - an octave for the note +// UINT32 duration - sound duration in microseconds. +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID Beep(VOID *PeiServices, UINT8 note, UINT8 octave, UINT32 duration) +{ + BeepOn(note,octave); + Delay(PeiServices, duration); + BeepOff(); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: BeepStatus +// +// Description: Simple Status Code handler that generates beep codes for a certain types of +// progress and error codes defined by the BEEP_PROGRESS_CODES_MAP and BEEP_ERROR_CODES_MAP mapping tables. +// +// Input: +// EFI_PEI_SERVICES *PeiServices, - pointer to the PEI Boot Services table +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// +// Output: +// EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BeepStatus( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +) +{ + UINT32 CodeTypeIndex = STATUS_CODE_TYPE(Type) - 1; + UINT8 i,n; + + if (CodeTypeIndex >= sizeof(BeepStatusCodes)/sizeof(STATUS_CODE_TO_BYTE_MAP*) ) return EFI_SUCCESS; + + n = FindByteCode(BeepStatusCodes[CodeTypeIndex],Value); + + if (n>0) + { + for (i=0; i<n; i++) + { + Beep(PeiServices,1,2,400000); + Delay(PeiServices,100000); + } + } + + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: BeepService +// +// Description: +// This function plays Value quantity of beeps +// +// Input: +// IN VOID *PeiServices - pointer to the PEI Boot Services table +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance - +// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function +// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS BeepService( + IN VOID *PeiServices, + 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 +) +{ + UINT8 n; + + if ((Value&0xFF00)!=AMI_STATUS_CODE_BEEP_CLASS) return EFI_SUCCESS; + + n = (UINT8)Value; + + if (n) + { + UINT8 i; + + for (i=0; i<n; i++) { Beep(PeiServices,0,4,40000); Delay(PeiServices,100000);} + } + + return EFI_SUCCESS; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/StatusCode/StatusCodeDxe.c b/Core/EM/StatusCode/StatusCodeDxe.c new file mode 100644 index 0000000..2917f32 --- /dev/null +++ b/Core/EM/StatusCode/StatusCodeDxe.c @@ -0,0 +1,883 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeDxe.c 8 11/13/12 6:21p Oleksiyy $ +// +// $Revision: 8 $ +// +// $Date: 11/13/12 6:21p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeDxe.c $ +// +// 8 11/13/12 6:21p Oleksiyy +// [TAG] EIP106198 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Memory leak in DataHubStatusCode function of +// StatusCodeDxe.c +// [RootCause] Memory allocated for the Record was newer released. +// [Solution] FreePool operation added. +// [Files] StatusCodeDxe.c +// +// 7 6/12/12 3:50p Oleksiyy +// [TAG] EIP90338 +// [Category] Improvement +// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to +// AmiLib.h. +// [Files] AmiLib.h, StatusCodeDxe.c and StatusCoderuntime.c +// +// 6 5/22/12 5:31p Oleksiyy +// [TAG] EIP90338 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] ChiefRiver SCT Fail on item Generic Test\EFI Compliant Test +// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined +// variable. +// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used. +// [Files] AmiLib.h, Misc.c, StatusCodeDxe.c and StatusCoderuntime.c +// +// 5 6/23/11 6:09p Oleksiyy +// [TAG] EIP56644 +// [Category] New Feature +// [Description] Implemented PPI and Protocols, described in a PI 1.2 +// Report Status Code Router specification. +// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h, +// StatusCodeCommon.c and StatusCodeRuntime.c +// +// 4 2/25/11 11:12a Oleksiyy +// [TAG] EIP54703 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Disabling "CON_OUT_CHECKPOINTS_IN_QUIET_MODE" token, ends +// with build error +// [RootCause] Wrong dependency from CON_OUT_CHECKPOINTS_IN_QUIET_MODE +// [Solution] Declaration of Foreground and Background variables now +// also depend from CON_OUT_CHECKPOINTS_IN_QUIET_MODE value. +// [Files] StatusCodeDxe.c +// +// 3 11/17/10 6:02p Oleksiyy +// [TAG] EIP39752 +// [Category] Improvement +// [Description] Bug fix. Status code moved to EfiRuntimeServicesData +// memory. +// [Files] StatusCodeDxe.c +// +// 2 7/09/09 5:18p Oleksiyy +// Files clean-up some headers added +// +// 1 3/05/09 1:40p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: StatusCodeDxe.c +// +// Description: +// File contains DXE specific status code routines such as: +// - Entry point of the StatusCode DXE driver +// DXE implementation of some of the functions from the status code library. +// Implementation of the data hub logger (status code subcomponent that logs status codes into the data hub) +// Implementation of the ConOut checkpoints (status code subcomponent that displays checkpoints on all ConOut devices). +// (Status code library is a set of generic routines utilized throughout the component). +// +//<AMI_FHDR_END> +//********************************************************************** +#include <AmiDxeLib.h> +#include <StatusCodes.h> +#include <Token.h> +#include <Protocol/StatusCode.h> +#include <Protocol/DataHub.h> +#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE +#include <Protocol/AmiPostMgr.h> +#endif +#include <Protocol/ConsoleControl.h> +#include <Protocol/SimpleTextOut.h> +#include "StatusCodeInt.h" + +EFI_DATA_HUB_PROTOCOL *DataHub = NULL; +EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; +#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE +AMI_POST_MANAGER_PROTOCOL *PostManager = NULL; +EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground = {0xFF,0xFF,0xFF,0}; +EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background = {0,0,0,0}; +static EFI_GUID gAmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID; +#endif +#if PI_SPECIFICATION_VERSION >= 0x00010014 +//----Router------------------------------------ +#include <Protocol/Variable.h> +#include <Protocol/ReportStatusCodeHandler.h> + +extern ROUTER_STRUCT_HEADER *RouterCallbackStr; +#define SC_ROUTER_ENTRIES 0xF + +//----Router End--------------------------------- +#endif +extern BOOLEAN StatusRuntime; + +#define EFI_STANDARD_CALLER_ID_GUID \ + {0xC9DCF469, 0xA7C4, 0x11D5, 0x87, 0xDA, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9} + +#define EFI_STATUS_CODE_GUID \ + {0xd083e94c, 0x6560, 0x42e4, 0xb6, 0xd4, 0x2d, 0xf7, 0x5a, 0xdf, 0x6a, 0x2a} + +#if PI_SPECIFICATION_VERSION >= 0x00010014 +BOOLEAN InRscHandlerNotification = FALSE; +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RscHandlerNotification +// +// Description: +// Executes delayed calls (when current TPL is higher that one router was +// registered with) to registered status code routers. +// +// Input: +// N EFI_EVENT Event - signaled event. +// IN VOID *Context - pointer to structure with parameters. +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID RscHandlerNotification ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry; + EFI_PHYSICAL_ADDRESS Address; + RSC_DATA_ENTRY *RscData; + + CallbackEntry = (RSC_HANDLER_CALLBACK_ENTRY *) Context; + + + // Traverse the status code data buffer to parse all data to report. + + Address = CallbackEntry->StatusCodeDataBuffer; + InRscHandlerNotification = TRUE; + while (Address < CallbackEntry->EndPointer) + { + RscData = (RSC_DATA_ENTRY *) (UINTN) Address; + CallbackEntry->RscHandlerCallback ( + RscData->Type, + RscData->Value, + RscData->Instance, + &RscData->CallerId, + &RscData->Data + ); + + Address += (sizeof (RSC_DATA_ENTRY) + RscData->Data.Size); + } + + CallbackEntry->EndPointer = CallbackEntry->StatusCodeDataBuffer; + InRscHandlerNotification = FALSE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RouterRegister +// +// Description: Register the callback function for ReportStatusCode() notification +// in DXE and Runtime. +// +// Input: +// IN EFI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type +// EFI_RSC_HANDLER_CALLBACK that is to be registered. +// IN EFI_TPL Tpl - TPL at which callback can be safely invoked. +// +// Output: +// EFI_SUCCESS The function was successfully registered. +// EFI_INVALID_PARAMETER The callback function was NULL. +// EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions can be +// registered. +// EFI_ALREADY_STARTED The function was already registered. It can't be registered again. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RouterRegister ( + IN EFI_RSC_HANDLER_CALLBACK Callback, + IN EFI_TPL Tpl + ) +{ + EFI_STATUS Status; + RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry; + UINT32 i; + VOID *Ptr, *UnregisteredPtr=NULL; + + if (Callback == NULL) + return EFI_INVALID_PARAMETER; + if (RouterCallbackStr == NULL) + return EFI_OUT_OF_RESOURCES; + + Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER); + + for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++) + { + CallbackEntry = Ptr; + + if (CallbackEntry->RscHandlerCallback == NULL) + { + UnregisteredPtr = Ptr; + } + else + { + if (CallbackEntry->RscHandlerCallback == Callback) + // If the function was already registered. It can't be registered again. + return EFI_ALREADY_STARTED; + } + Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY); + } + if (UnregisteredPtr == NULL) //No Unregistered entries + { + if (RouterCallbackStr->RegisteredEntries == RouterCallbackStr->TotalEntries) + return EFI_OUT_OF_RESOURCES; // And all entries are taken already - exit + CallbackEntry = Ptr; + RouterCallbackStr->RegisteredEntries++; + } + else + CallbackEntry = UnregisteredPtr; // Will fill uregistered entry + + CallbackEntry->RscHandlerCallback = Callback; + CallbackEntry->Tpl = Tpl; + + // If TPL of registered callback funtion is not TPL_HIGH_LEVEL, then event should be created + // for it, and related buffer for status code data should be prepared. + // Here the data buffer must be prepared in advance, because Report Status Code Protocol might + // be invoked under TPL_HIGH_LEVEL and no memory allocation is allowed then. + // If TPL is TPL_HIGH_LEVEL, then all status code will be reported immediately, without data + // buffer and event trigger. + if ((Tpl != TPL_HIGH_LEVEL) && !StatusRuntime) + { + VOID *StatusCodeDataBuff; + Status = pBS->AllocatePool (EfiRuntimeServicesData, EFI_PAGE_SIZE, &StatusCodeDataBuff); + CallbackEntry->StatusCodeDataBuffer = (EFI_PHYSICAL_ADDRESS) (UINTN) StatusCodeDataBuff; + CallbackEntry->BufferSize = EFI_PAGE_SIZE; + CallbackEntry->EndPointer = CallbackEntry->StatusCodeDataBuffer; + Status = pBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + Tpl, + RscHandlerNotification, + CallbackEntry, + &CallbackEntry->Event + ); + ASSERT_EFI_ERROR (Status); + } + + return EFI_SUCCESS; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RouterUnregister +// +// Description: Remove a previously registered callback function from the notification list. +// +// Input: +// IN EFI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type +// EFI_RSC_HANDLER_CALLBACK that is to be unregistered. +// +// Output: +// EFI_SUCCESS The function was successfully unregistered. +// EFI_INVALID_PARAMETER The callback function was NULL. +// EFI_NOT_FOUND The callback function was not found to be unregistered. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RouterUnregister (IN EFI_RSC_HANDLER_CALLBACK Callback) +{ + RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry; + UINT32 i; + VOID *Ptr; + + if (Callback == NULL) + return EFI_INVALID_PARAMETER; + if (RouterCallbackStr == NULL) + return EFI_NOT_FOUND; + + Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER); + + for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++) + { + CallbackEntry = Ptr; + + if (CallbackEntry->RscHandlerCallback == Callback) + { + + // If the function is found in list, delete it and return. + + if ((CallbackEntry->Tpl != TPL_HIGH_LEVEL) && (CallbackEntry->StatusCodeDataBuffer != 0)) + { + pBS->FreePool ((VOID *) (UINTN) CallbackEntry->StatusCodeDataBuffer); + pBS->CloseEvent (CallbackEntry->Event); + } + pBS->SetMem(Ptr, sizeof(RSC_HANDLER_CALLBACK_ENTRY), 0);//Clear all data in entry + return EFI_SUCCESS; + } + Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY); + } + + return EFI_NOT_FOUND; +} + +EFI_RSC_HANDLER_PROTOCOL RscHandlerProtocol = { + RouterRegister, + RouterUnregister + }; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PassRouterAdress +// +// Description: Sets variable with the address of RSC Info structure. +// +// Input: +// IN EFI_EVENT Event +// IN VOID *Context +// +// Output: +// VOID +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID PassRouterAdress(IN EFI_EVENT Event, IN VOID *Context) +{ + EFI_PHYSICAL_ADDRESS RSCInfoAddresss = (EFI_PHYSICAL_ADDRESS) (UINTN) RouterCallbackStr; + + + if (RouterCallbackStr == NULL) + return; + pRS->SetVariable( + L"RSCInfoAddresss", + &gAmiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(EFI_PHYSICAL_ADDRESS), + &RSCInfoAddresss + ); + +} +#endif +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Delay +// +// Description: Stalls execution for a passed in number of microseconds +// +// Input: +// VOID *PeiServices - not used +// UINT32 Microseconds - the number of microseconds to stall execution +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID Delay(VOID **PeiServices, UINT32 Microseconds) +{ + pBS->Stall(Microseconds); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DxeReportStatusCode +// +// Description: DXE Status Code Reporting function. +// A wrapper around phase independent ReportStatucCode +// function defined in StatusCodeCommon.c. +// +// Input: +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance Instance - Instance +// *CallerId OPTIONAL - The GUID of the caller function +// *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DxeReportStatusCode ( + 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 +) +{ + //If we are in runtime don't do anything. + //Port this code if runtime status code is required. + if (StatusRuntime) return EFI_SUCCESS; + + return ( ReportStatusCode( NULL, Type, Value, Instance, CallerId, Data)); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: StatusCodeExitBS +// +// Description: Exit Boot Services event handler. +// Terminates boot time status code processing +// +// Input: +// IN EFI_EVENT Event - not used +// IN VOID *Context - not used +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID StatusCodeExitBS (IN EFI_EVENT Event, IN VOID *Context) +{ + StatusRuntime = TRUE; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DxeInitStatusCode +// +// Description: +// Entry point of the StatusCode Driver. +// Calls InitStatusCodeParts function, installs the Status Code Protocol, +// and registers event handlers for the legacy boot and exit boot services events. +// DxeInitStatusCode installs different protocol based on value of the +// EFI_SPECIFICATION_VERSION SDL token (defined in Core.sdl). +// If value of the EFI_SPECIFICATION_VERSION constant is less than 0x20000, +// framework EFI_STATUS_CODE_ARCH_PROTOCOL_GUID protocol is installed; +// otherwise, PI EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID protocol is installed. +// PI Status Code Protocol is initialized with the address of DxeReportStatusCode function. +// +// Input: +// *ImageHandle - The firmware allocate handle for the EFI image +// *SystemTable - pointer to the EFI System Table +// +// Output: EFI_STATUS +// +// Modified: StatusCode Arch Protocol- now published +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DxeInitStatusCode( + IN EFI_HANDLE *ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; + EFI_HANDLE StatusCodeHandle = NULL; + EFI_EVENT Event; +#if PI_SPECIFICATION_VERSION >= 0x00010014 + EFI_EVENT VarEvent = NULL; + VOID *VarReg; +#endif +#if EFI_SPECIFICATION_VERSION >= 0x20000 + static EFI_STATUS_CODE_PROTOCOL *StatusCode; +#endif + InitStatusCodeParts(ImageHandle,SystemTable); + +#if EFI_SPECIFICATION_VERSION >= 0x20000 + Status = pBS->AllocatePool ( + EfiRuntimeServicesData, sizeof(EFI_STATUS_CODE_PROTOCOL), &StatusCode + ); + if (EFI_ERROR(Status)) return Status; + StatusCode->ReportStatusCode = DxeReportStatusCode; +#endif +#if EFI_SPECIFICATION_VERSION < 0x20000 + SystemTable->RuntimeServices->ReportStatusCode = DxeReportStatusCode; +#endif + Status = SystemTable->BootServices->InstallProtocolInterface( + &StatusCodeHandle, +#if EFI_SPECIFICATION_VERSION < 0x20000 + &gEfiStatusCodeArchProtocolGuid, +#else + &gEfiStatusCodeRuntimeProtocolGuid, +#endif + EFI_NATIVE_INTERFACE, +#if EFI_SPECIFICATION_VERSION < 0x20000 + NULL +#else + StatusCode +#endif + ); + //Register Exit Boot Services Callback + pBS->CreateEvent( + EVT_SIGNAL_EXIT_BOOT_SERVICES,TPL_CALLBACK, + &StatusCodeExitBS, NULL, &Event + ); + CreateLegacyBootEvent(TPL_CALLBACK, &StatusCodeExitBS, NULL, &Event); +#if PI_SPECIFICATION_VERSION >= 0x00010014 + //Allocate memory for Status Code Router inforstructure + Status = pBS->AllocatePool (EfiRuntimeServicesData, + sizeof(ROUTER_STRUCT_HEADER) + (sizeof(RSC_HANDLER_CALLBACK_ENTRY) * SC_ROUTER_ENTRIES), + &RouterCallbackStr); + if (EFI_ERROR(Status)) return Status; + pBS->SetMem(RouterCallbackStr, sizeof(ROUTER_STRUCT_HEADER) + + (sizeof(RSC_HANDLER_CALLBACK_ENTRY) * SC_ROUTER_ENTRIES), 0); + RouterCallbackStr->TotalEntries = SC_ROUTER_ENTRIES; + Status = pBS->InstallMultipleProtocolInterfaces ( + &StatusCodeHandle, + &gEfiRscHandlerProtocolGuid, + &RscHandlerProtocol, + NULL + ); + ASSERT_EFI_ERROR (Status); + + Status = RegisterProtocolCallback(&gEfiVariableArchProtocolGuid,PassRouterAdress,NULL,&VarEvent,&VarReg); + + ASSERT_EFI_ERROR(Status); +#endif + return Status; +} + +//<AMI_GHDR_START> +//---------------------------------------------------------------------------- +// Name: Data_Hub_Logging +// +// Description: +// DataHub Logging Functions: +// - DataHubInint +// - DataHubInstalled +// - DataHubStatusCode +//---------------------------------------------------------------------------- +//<AMI_GHDR_END> + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DataHubStatusCode +// +// Description: Logs status code data into the data hub +// +// Input: +// 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 +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DataHubStatusCode ( + IN VOID **Dummy, //dummy parameter for compatibility with PEI callback interface + 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 +) +{ + EFI_STATUS Status; + DATA_HUB_STATUS_CODE_DATA_RECORD *Record; + UINT32 Size; + UINT8 CodeType = STATUS_CODE_TYPE(Type); + + static EFI_GUID gEfiCallerIdGuid = EFI_STANDARD_CALLER_ID_GUID; + static EFI_GUID gEfiStatusCodeGuid = EFI_STATUS_CODE_GUID; + static EFI_GUID gEfiStatusCodeRuntimeProtocolGuid = EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID; + static UINT8 DataHubClasses[] = {EFI_DATA_CLASS_PROGRESS_CODE,EFI_DATA_CLASS_ERROR,EFI_DATA_CLASS_DEBUG}; + + if (DataHub == NULL) return EFI_NOT_AVAILABLE_YET; + + //Do not log debug codes + if (CodeType==EFI_DEBUG_CODE) return EFI_SUCCESS; + + if (CodeType > sizeof(DataHubClasses)) return EFI_INVALID_PARAMETER; + + if (Data!=NULL) + Size = EFI_FIELD_OFFSET(DATA_HUB_STATUS_CODE_DATA_RECORD,Data) + +Data->HeaderSize+Data->Size; + else + Size = sizeof(DATA_HUB_STATUS_CODE_DATA_RECORD); + + pBS->AllocatePool(EfiBootServicesData,Size,&Record); + //---Fill Record structure-------- + Record->CodeType = Type; + Record->Value = Value; + Record->Instance = Instance; + + if (CallerId==NULL) Record->CallerId = gEfiCallerIdGuid; + else Record->CallerId = *CallerId; + + if (Data==NULL) + pBS->SetMem(&Record->Data,sizeof(EFI_STATUS_CODE_DATA),0); + else + pBS->CopyMem(&Record->Data,Data,Data->HeaderSize+Data->Size); + + Status = DataHub->LogData( + DataHub, + &gEfiStatusCodeGuid, + &gEfiStatusCodeRuntimeProtocolGuid, + DataHubClasses[CodeType-1], + Record, + Size + ); + pBS->FreePool(Record); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DataHubInstalled +// +// Description: Callback routine. Activates data hub status code logging once DataHub protocol is installed. +// +// Input: +// IN EFI_EVENT Event - Signalled Event +// IN VOID *Context - calling context +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID DataHubInstalled (IN EFI_EVENT Event, IN VOID *Context) +{ + EFI_STATUS Status; + + if (DataHub!=NULL) return; + + Status = pBS->LocateProtocol(&gEfiDataHubProtocolGuid,NULL,&DataHub); + + if (EFI_ERROR(Status)) DataHub=NULL; + else pBS->CloseEvent(Event); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: DataHubInit +// +// Description: Initializes data hub error logging infrastructure. +// This function is called from InitStatusCodeParts function (in DXE only). +// +// Input: +// IN EFI_HANDLE *ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS DataHubInit( + IN EFI_HANDLE *ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_EVENT Event; + VOID *Registration; + //Register Data Hub Callback + EFI_STATUS Status = RegisterProtocolCallback( + &gEfiDataHubProtocolGuid, DataHubInstalled, NULL, + &Event, &Registration + ); + + if (EFI_ERROR(Status)) return Status; + + pBS->SignalEvent(Event); + return Status; +} + +//<AMI_GHDR_START> +//---------------------------------------------------------------------------- +// Name: Con_Out_Checkpoints +// +// Description: +// ConOut checkpoints functions: +// - ConOutCpInit +// - ConOutInstalled +// - StopConOutCheckpoints +// - ConOutCheckpoint +//---------------------------------------------------------------------------- +//<AMI_GHDR_END> + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConOutCheckpoint +// +// Description: Displays checkpoints at the right bottom corner or the ConOut devices. +// +// Input: +// IN VOID *Dummy - not used. Dummy parameter for compatibility with PEI callback interface. +// IN UINT8 Checkpoint - checkpoint to display +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ConOutCheckpoint ( + IN VOID *Dummy, + IN UINT8 Checkpoint +) +{ + EFI_STATUS Status; + EFI_CONSOLE_CONTROL_SCREEN_MODE Mode; + CHAR16 s[10]; + + if (ConsoleControl==NULL || pST->ConOut==NULL +#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE + || PostManager == NULL +#endif + ) return EFI_NOT_AVAILABLE_YET; + + Status = ConsoleControl->GetMode(ConsoleControl,&Mode,NULL,NULL); + + if (EFI_ERROR(Status)) return Status; + + //TODO: try Sprintf and convert + Swprintf(s, L"%X",Checkpoint); + + if (Mode==EfiConsoleControlScreenText) + { + UINTN X,Y, MaxX, MaxY; + pST->ConOut->QueryMode(pST->ConOut,pST->ConOut->Mode->Mode, &MaxX, &MaxY); + //Get cursor position + X = pST->ConOut->Mode->CursorColumn; + Y = pST->ConOut->Mode->CursorRow; + //Set cursor and print string + pST->ConOut->SetCursorPosition(pST->ConOut, MaxX-3, MaxY-1); + pST->ConOut->OutputString(pST->ConOut, s); + //Restore cursor position + pST->ConOut->SetCursorPosition(pST->ConOut, X, Y); + } + +#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE + else // EfiConsoleControlScreenGraphics + { + PostManager->DisplayQuietBootMessage( + s, 0, 0, CA_AttributeRightBottom, + Foreground, Background + ); + } + +#endif + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: StopConOutCheckpoints +// +// Description: Read To Boot Callback routine. Terminates ConOut checkpoint display. +// +// Input: +// IN EFI_EVENT Event - Signalled Event +// IN VOID *Context - calling context +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID StopConOutCheckpoints (IN EFI_EVENT Event, IN VOID *Context) +{ + ConsoleControl=NULL; + pBS->CloseEvent(Event); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConOutInstalled +// +// Description: Callback routine. Activates ConOut checkpoint display once +// ConOut field in the UEFI ststem table is populated. +// +// Input: +// IN EFI_EVENT Event - Signalled Event +// IN VOID *Context - calling context +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ConOutInstalled (IN EFI_EVENT Event, IN VOID *Context) +{ + EFI_STATUS Status; + + if (ConsoleControl!=NULL) return; + +#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE + Status = pBS->LocateProtocol(&gAmiPostManagerProtocolGuid,NULL,&PostManager); + + if (EFI_ERROR(Status)) PostManager=NULL; + +#endif + Status = pBS->LocateProtocol(&gEfiConsoleControlProtocolGuid,NULL,&ConsoleControl); + + if (EFI_ERROR(Status)) ConsoleControl=NULL; + else pBS->CloseEvent(Event); + + CreateReadyToBootEvent(TPL_CALLBACK, &StopConOutCheckpoints, NULL, &Event); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ConOutCpInit +// +// Description: Initializes ConOut checkpoint display code. +// This function is called from InitStatusCodeParts function (in DXE only). +// +// Input: +// IN EFI_HANDLE *ImageHandle +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ConOutCpInit ( + IN EFI_HANDLE *ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_EVENT Event; + VOID *Registration; + //Register Data Hub Callback + EFI_STATUS Status = RegisterProtocolCallback( + &gEfiConsoleControlProtocolGuid, ConOutInstalled, NULL, + &Event, &Registration + ); + + if (EFI_ERROR(Status)) return Status; + + pBS->SignalEvent(Event); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ResetOrResume +// +// Description: Error Code Action. +// Attempts to perform a system reset. If reset fails, returns. +// +// Input: +// VOID *PeiServices - not used +// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action. +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ResetOrResume( + IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value +) +{ + pRS->ResetSystem(EfiResetCold,0,0,NULL); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/StatusCode/StatusCodeInt.h b/Core/EM/StatusCode/StatusCodeInt.h new file mode 100644 index 0000000..c60e6ec --- /dev/null +++ b/Core/EM/StatusCode/StatusCodeInt.h @@ -0,0 +1,125 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeInt.h 3 6/23/11 6:10p Oleksiyy $ +// +// $Revision: 3 $ +// +// $Date: 6/23/11 6:10p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeInt.h $ +// +// 3 6/23/11 6:10p Oleksiyy +// [TAG] EIP56644 +// [Category] New Feature +// [Description] Implemented PPI and Protocols, described in a PI 1.2 +// Report Status Code Router specification. +// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h, +// StatusCodeCommon.c and StatusCodeRuntime.c +// +// 2 7/09/09 5:18p Oleksiyy +// Files clean-up some headers added +// +// 1 3/05/09 1:40p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: StatusCodeInt.c +// +// Description: Header file containing declarations of functions, macros, and types shared across status code module files. +// +//<AMI_FHDR_END> +//********************************************************************** +#ifndef __STATUS_CODE_INT__H__ +#define __STATUS_CODE_INT__H__ +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct + { + EFI_STATUS_CODE_VALUE Value; + UINT8 Byte; + } STATUS_CODE_TO_BYTE_MAP; + + typedef VOID (ERROR_CODE_ACTION)( + IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value + ); + + typedef struct + { + EFI_STATUS_CODE_VALUE Value; + ERROR_CODE_ACTION *Action; + } ERROR_CODE_ACTION_MAP; + +#define STATUS_CODE_TYPE(Type) ((Type)&EFI_STATUS_CODE_TYPE_MASK) + + UINT8 FindByteCode(STATUS_CODE_TO_BYTE_MAP *Map, EFI_STATUS_CODE_VALUE Value); + VOID Delay(VOID **PeiServices, UINT32 Microseconds); + EFI_STATUS ReportStatusCode ( + IN VOID *PeiServices, + 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 + ); + VOID InitStatusCodeParts(IN VOID *ImageHandler, IN VOID *ServicesTable); + VOID ResetOrResume(IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value); +#if PI_SPECIFICATION_VERSION >= 0x00010014 +#include <Protocol/ReportStatusCodeHandler.h> +typedef struct { + EFI_STATUS_CODE_TYPE Type; + EFI_STATUS_CODE_VALUE Value; + UINT32 Instance; + UINT32 Reserved; + EFI_GUID CallerId; + EFI_STATUS_CODE_DATA Data; +} RSC_DATA_ENTRY; + +typedef struct { + EFI_RSC_HANDLER_CALLBACK RscHandlerCallback; + EFI_TPL Tpl; + EFI_EVENT Event; + EFI_PHYSICAL_ADDRESS StatusCodeDataBuffer; + UINTN BufferSize; + EFI_PHYSICAL_ADDRESS EndPointer; +} RSC_HANDLER_CALLBACK_ENTRY; + +typedef struct { + UINT32 RegisteredEntries; + UINT32 TotalEntries; +} ROUTER_STRUCT_HEADER; +#endif + /****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/StatusCode/StatusCodeMap.c b/Core/EM/StatusCode/StatusCodeMap.c new file mode 100644 index 0000000..b8f416c --- /dev/null +++ b/Core/EM/StatusCode/StatusCodeMap.c @@ -0,0 +1,278 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeMap.c 2 7/09/09 5:18p Oleksiyy $ +// +// $Revision: 2 $ +// +// $Date: 7/09/09 5:18p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeMap.c $ +// +// 2 7/09/09 5:18p Oleksiyy +// Files clean-up some headers added +// +// 1 3/05/09 1:40p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: StatusCodeMap.c +// +// Description: +// This file contains several tables that map generic namespace +// of status code values into domain specific namespaces. +// In the current implementation the following tables are included: +// ProgressCheckpointMap - establishes mapping between progress code values and checkpoint values. +// ErrorCheckpointMap - establishes mapping between error code values and checkpoint values. +// ProgressBeepMap - establishes mapping between progress code values and number of beeps. +// ErrorBeepMap - establishes mapping between error code values and number of beeps. +// The mapping tables can be overriden using SDL tokens. +//<AMI_FHDR_END> +//********************************************************************** +#include <AmiStatusCodes.h> +#include "StatusCodeInt.h" + +//********************************************************************** +// Checkpoints map +//********************************************************************** +//1 - 0xF : SEC execution +//0x10 - 0x2F: PEI CAR execution +//0x30 - 0x4F: PEI execution after memory detection +//0x50 - 0x5F: PEI errors +//0x60 - 0xCF: DXE execution +//0xD0 - 0xDF: DXE errors +//0xE0 - 0xE8: S3 Resume +//0xE9 - 0xEF: S3 Resume errors +//0xF0 - 0xF8: Recovery +//0xF9 - 0xFF: Recovery errors + +STATUS_CODE_TO_BYTE_MAP ProgressCheckpointMap[] = +{ +#ifdef PEI_STATUS_CODE +//Regular boot + { PEI_CORE_STARTED, 0x10 }, + { PEI_CAR_CPU_INIT, 0x11 }, + // reserved for CPU 0x12 - 0x14 + { PEI_CAR_NB_INIT, 0x15 }, + // reserved for NB 0x16 - 0x18 + { PEI_CAR_SB_INIT, 0x19 }, + // reserved for SB 0x1A - 0x1C + // reserved for OEM use: 0x1D - 0x2A + { PEI_MEMORY_SPD_READ, 0x2B }, + { PEI_MEMORY_PRESENCE_DETECT, 0x2C }, + { PEI_MEMORY_TIMING, 0x2D}, + { PEI_MEMORY_CONFIGURING, 0x2E }, + { PEI_MEMORY_INIT, 0x2F }, + // reserved for AML use: 0x30 + { PEI_MEMORY_INSTALLED, 0x31 }, + { PEI_CPU_INIT, 0x32 }, + { PEI_CPU_CACHE_INIT, 0x33 }, + { PEI_CPU_AP_INIT, 0x34 }, + { PEI_CPU_BSP_SELECT, 0x35 }, + { PEI_CPU_SMM_INIT, 0x36 }, + { PEI_MEM_NB_INIT, 0x37 }, + // reserved for NB 0x38 - 0x3A + { PEI_MEM_SB_INIT, 0x3B }, + // reserved for SB 0x3C - 0x3E + // reserved for OEM use: 0x3F - 0x4E + { PEI_DXE_IPL_STARTED, 0x4F }, + { DXE_CORE_STARTED, 0x60 }, +//Recovery + { PEI_RECOVERY_AUTO, 0xF0 }, + { PEI_RECOVERY_USER, 0xF1 }, + { PEI_RECOVERY_STARTED, 0xF2 }, + { PEI_RECOVERY_CAPSULE_FOUND, 0xF3 }, + { PEI_RECOVERY_CAPSULE_LOADED, 0xF4 }, +//S3 + { PEI_S3_STARTED, 0xE0 }, + { PEI_S3_BOOT_SCRIPT, 0xE1 }, + { PEI_S3_VIDEO_REPOST, 0xE2 }, + { PEI_S3_OS_WAKE, 0xE3 }, +#endif +#ifdef DXE_STATUS_CODE + { DXE_CORE_STARTED, 0x60 }, + { DXE_NVRAM_INIT, 0x61 }, + { DXE_SBRUN_INIT, 0x62 }, + { DXE_CPU_INIT, 0x63 }, + //reserved for CPU 0x64 - 0x67 + { DXE_NB_HB_INIT, 0x68 }, + { DXE_NB_INIT, 0x69 }, + { DXE_NB_SMM_INIT, 0x6A }, + //reserved for NB 0x6B - 0x6F + { DXE_SB_INIT, 0x70 }, + { DXE_SB_SMM_INIT, 0x71 }, + { DXE_SB_DEVICES_INIT, 0x72 }, + //reserved for SB 0x73 - 0x77 + { DXE_ACPI_INIT, 0x78 }, + { DXE_CSM_INIT, 0x79 }, + //reserved for AMI use: 0x7A - 0x7F + //reserved for OEM use: 0x80 - 0x8F + { DXE_BDS_STARTED, 0x90 }, + { DXE_BDS_CONNECT_DRIVERS, 0x91 }, + { DXE_PCI_BUS_BEGIN, 0x92 }, + { DXE_PCI_BUS_HPC_INIT, 0x93 }, + { DXE_PCI_BUS_ENUM, 0x94 }, + { DXE_PCI_BUS_REQUEST_RESOURCES, 0x95 }, + { DXE_PCI_BUS_ASSIGN_RESOURCES, 0x96 }, + { DXE_CON_OUT_CONNECT, 0x97 }, + { DXE_CON_IN_CONNECT, 0x98 }, + { DXE_SIO_INIT, 0x99 }, + { DXE_USB_BEGIN, 0x9A }, + { DXE_USB_RESET, 0x9B }, + { DXE_USB_DETECT, 0x9C }, + { DXE_USB_ENABLE, 0x9D }, + //reserved for AMI use: 0x9E - 0x9F + { DXE_IDE_BEGIN, 0xA0 }, + { DXE_IDE_RESET, 0xA1 }, + { DXE_IDE_DETECT, 0xA2 }, + { DXE_IDE_ENABLE, 0xA3 }, + { DXE_SCSI_BEGIN, 0xA4 }, + { DXE_SCSI_RESET, 0xA5 }, + { DXE_SCSI_DETECT, 0xA6 }, + { DXE_SCSI_ENABLE, 0xA7 }, + { DXE_SETUP_VERIFYING_PASSWORD, 0xA8 }, + { DXE_SETUP_START, 0xA9 }, + //reserved for AML use: 0xAA + { DXE_SETUP_INPUT_WAIT, 0xAB }, + //reserved for AML use: 0xAC + { DXE_READY_TO_BOOT, 0xAD }, + { DXE_LEGACY_BOOT, 0xAE }, + { DXE_EXIT_BOOT_SERVICES, 0xAF }, + { RT_SET_VIRTUAL_ADDRESS_MAP_BEGIN, 0xB0 }, + { RT_SET_VIRTUAL_ADDRESS_MAP_END, 0xB1 }, + { DXE_LEGACY_OPROM_INIT, 0xB2 }, + { DXE_RESET_SYSTEM, 0xB3 }, + { DXE_USB_HOTPLUG, 0xB4 }, + { DXE_PCI_BUS_HOTPLUG, 0xB5 }, + { DXE_NVRAM_CLEANUP, 0xB6 }, + { DXE_CONFIGURATION_RESET, 0xB7 }, + //reserved for AMI use: 0xB8 - 0xBF + //reserved for OEM use: 0xC0 - 0xCF +#endif + {0,0} +}; + +STATUS_CODE_TO_BYTE_MAP ErrorCheckpointMap[] = +{ +#ifdef PEI_STATUS_CODE +//Errors +//Regular boot + { PEI_MEMORY_INVALID_TYPE, 0x50 }, + { PEI_MEMORY_INVALID_SPEED, 0x50 }, + { PEI_MEMORY_SPD_FAIL, 0x51 }, + { PEI_MEMORY_INVALID_SIZE, 0x52 }, + { PEI_MEMORY_MISMATCH, 0x52 }, + { PEI_MEMORY_NOT_DETECTED, 0x53 }, + { PEI_MEMORY_NONE_USEFUL, 0x53 }, + { PEI_MEMORY_ERROR, 0x54 }, + { PEI_MEMORY_NOT_INSTALLED, 0x55 }, + { PEI_CPU_INVALID_TYPE, 0x56 }, + { PEI_CPU_INVALID_SPEED, 0x56 }, + { PEI_CPU_MISMATCH, 0x57 }, + { PEI_CPU_SELF_TEST_FAILED, 0x58 }, + { PEI_CPU_CACHE_ERROR, 0x58 }, + { PEI_CPU_MICROCODE_UPDATE_FAILED, 0x59 }, + { PEI_CPU_NO_MICROCODE, 0x59 }, + { PEI_CPU_INTERNAL_ERROR, 0x5A }, + { PEI_CPU_ERROR, 0x5A }, + { PEI_RESET_NOT_AVAILABLE,0x5B }, + //reserved for AMI use: 0x5C - 0x5F +//Recovery + { PEI_RECOVERY_PPI_NOT_FOUND, 0xF8 }, + { PEI_RECOVERY_NO_CAPSULE, 0xF9 }, + { PEI_RECOVERY_INVALID_CAPSULE, 0xFA }, + //reserved for AMI use: 0xFB - 0xFF +//S3 Resume + { PEI_MEMORY_S3_RESUME_FAILED, 0xE8 }, + { PEI_S3_RESUME_PPI_NOT_FOUND, 0xE9 }, + { PEI_S3_BOOT_SCRIPT_ERROR, 0xEA }, + { PEI_S3_OS_WAKE_ERROR, 0xEB }, + //reserved for AMI use: 0xEC - 0xEF +#endif +#ifdef DXE_STATUS_CODE + { DXE_CPU_ERROR, 0xD0 }, + { DXE_NB_ERROR, 0xD1 }, + { DXE_SB_ERROR, 0xD2 }, + { DXE_ARCH_PROTOCOL_NOT_AVAILABLE, 0xD3 }, + { DXE_PCI_BUS_OUT_OF_RESOURCES, 0xD4 }, + { DXE_LEGACY_OPROM_NO_SPACE, 0xD5 }, + { DXE_NO_CON_OUT, 0xD6 }, + { DXE_NO_CON_IN, 0xD7 }, + { DXE_INVALID_PASSWORD, 0xD8 }, + { DXE_BOOT_OPTION_LOAD_ERROR, 0xD9 }, + { DXE_BOOT_OPTION_FAILED, 0xDA }, + { DXE_FLASH_UPDATE_FAILED, 0xDB }, + { DXE_RESET_NOT_AVAILABLE, 0xDC }, + //reserved for AMI use: 0xDE - 0xDF +#endif + {0,0} +}; + +//********************************************************************** +// Beep codes map +//********************************************************************** +STATUS_CODE_TO_BYTE_MAP ProgressBeepMap[] = +{ +#ifdef PEI_STATUS_CODE +//Recovery + { PEI_RECOVERY_STARTED, 2 }, +#endif +#ifdef DXE_STATUS_CODE +#endif + {0,0} +}; + +STATUS_CODE_TO_BYTE_MAP ErrorBeepMap[] = +{ +#ifdef PEI_STATUS_CODE +//Errors +//Regular boot + { PEI_MEMORY_NOT_INSTALLED, 1 }, + { PEI_MEMORY_INSTALLED_TWICE, 1 }, + { PEI_DXEIPL_NOT_FOUND, 3 }, + { PEI_DXE_CORE_NOT_FOUND, 3 }, + { PEI_RESET_NOT_AVAILABLE, 7 }, +//Recovery + { PEI_RECOVERY_FAILED, 4 }, +//S3 Resume + { PEI_S3_RESUME_FAILED, 4 }, +#endif +#ifdef DXE_STATUS_CODE + { DXE_ARCH_PROTOCOL_NOT_AVAILABLE, 4 }, + { DXE_NO_CON_OUT, 5 }, + { DXE_NO_CON_IN, 5 }, + { DXE_INVALID_PASSWORD, 1 }, + { DXE_FLASH_UPDATE_FAILED, 6 }, + { DXE_RESET_NOT_AVAILABLE, 7 }, + { DXE_PCI_BUS_OUT_OF_RESOURCES, 8}, +#endif + {0,0} +}; +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/StatusCode/StatusCodePei.c b/Core/EM/StatusCode/StatusCodePei.c new file mode 100644 index 0000000..1e452d1 --- /dev/null +++ b/Core/EM/StatusCode/StatusCodePei.c @@ -0,0 +1,492 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodePei.c 3 6/23/11 6:09p Oleksiyy $ +// +// $Revision: 3 $ +// +// $Date: 6/23/11 6:09p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodePei.c $ +// +// 3 6/23/11 6:09p Oleksiyy +// [TAG] EIP56644 +// [Category] New Feature +// [Description] Implemented PPI and Protocols, described in a PI 1.2 +// Report Status Code Router specification. +// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h, +// StatusCodeCommon.c and StatusCodeRuntime.c +// +// 2 7/09/09 5:18p Oleksiyy +// Files clean-up some headers added +// +// 1 3/05/09 1:40p Felixp +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: StatusCodePei.c +// +// Description: +// File contains PEI specific status code routines such as +// entry point of the StatusCode PEIM (PeiInitStatusCode) and +// PEI implementation of some of the functions from the status code library. +// (Status code library is a set of generic routines utilized throughout the component). +// +//<AMI_FHDR_END> +//********************************************************************** +#include <AmiPeiLib.h> +#include <PPI/ProgressCode.h> +#include <PPI/Stall.h> +#include "StatusCodeInt.h" +#include <Token.h> + +//--------------------To HEADER----------------------------------------------- +/** @file + GUID used to identify HOB for pointers to callback functios registered on + PEI report status code router. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that 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. + +**/ + +#if PI_SPECIFICATION_VERSION >= 0x00010014 + +#include <PPI/ReportStatusCodeHandler.h> +#define INITIAL_RSC_PEI_ENTRIES 8 +#define STATUS_CODE_CALLBACK_GUID \ + { \ + 0xe701458c, 0x4900, 0x4ca5, {0xb7, 0x72, 0x3d, 0x37, 0x94, 0x9f, 0x79, 0x27} \ + } + +EFI_GUID gStatusCodeCallbackGuid = STATUS_CODE_CALLBACK_GUID; + + +BOOLEAN IsItRecursiveCall ( + IN OUT BOOLEAN *Value, + IN BOOLEAN CompareWith, + IN BOOLEAN SvitchTo + ); + + +EFI_GUID gEfiPeiRscHandlerPpiGuid = EFI_PEI_RSC_HANDLER_PPI_GUID; + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Delay +// +// Description: Worker function to create one memory status code GUID'ed HOB +// +// Input: None +// +// Output: +// UINTN* - Pointer to the NumberOfEntries field in Hob +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + +UINTN* +CreateRscHandlerCallbackPacket ( + ) +{ + UINTN *NumberOfEntries; + EFI_HOB_GUID_TYPE *Hob; + EFI_STATUS Status; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer (); + + // + // Build GUID'ed HOB with PCD defined size. + // + + Status = (*PeiServices)->CreateHob (PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, + (UINT16)(sizeof (EFI_PEI_RSC_HANDLER_CALLBACK) * INITIAL_RSC_PEI_ENTRIES + + sizeof (UINTN)+ sizeof (EFI_HOB_GUID_TYPE)), &Hob); + //ASSERT_PEI_ERROR(PeiServices,Status); + if (EFI_ERROR(Status)) return NULL; + MemCpy (&Hob->Name, &gStatusCodeCallbackGuid, sizeof (EFI_GUID)); + + NumberOfEntries = (UINTN*)(Hob + 1); + + *NumberOfEntries = 0; + + return NumberOfEntries; +} + + +#define GET_GUID_HOB_DATA(HobStart) \ + (VOID*)((UINT8*)(HobStart) + sizeof (EFI_HOB_GUID_TYPE)) + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: GetFirstGuidHob +// +// Description: Returns the first instance of the matched GUID HOB among the +// whole HOB list. +// +// Input: +// IN EFI_GUID *Guid - The GUID to match with in the HOB list. +// +// Output: +// VOID* Pointer po first matched Hob (NULL - if not found) +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID * +GetFirstGuidHob ( + IN EFI_GUID *Guid + ) +{ + + VOID *HobList = NULL; + EFI_STATUS Status; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer (); + + Status = (*PeiServices)->GetHobList (PeiServices, &HobList); + if (EFI_ERROR(Status)) return NULL; + Status = FindNextHobByGuid (Guid, &HobList); + if (EFI_ERROR(Status)) return NULL; + else return HobList; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PpiUnregister +// +// Description: Remove a previously registered callback function from the notification list. +// +// Input: +// IN EFI_PEI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type +// EFI_PEI_RSC_HANDLER_CALLBACK that is to be unregistered. +// +// Output: +// EFI_SUCCESS The function was successfully unregistered. +// EFI_INVALID_PARAMETER The callback function was NULL. +// EFI_NOT_FOUND The callback function was not found to be unregistered. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +PpiUnregister ( + IN EFI_PEI_RSC_HANDLER_CALLBACK Callback + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry; + UINTN *NumberOfEntries; + UINTN Index; + EFI_STATUS Status; + + + if (Callback == NULL) { + return EFI_INVALID_PARAMETER; + } + + Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid); + while (Hob.Raw != NULL) { + NumberOfEntries = GET_GUID_HOB_DATA (Hob.Raw); + 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; + } + } + Status = FindNextHobByGuid (&gStatusCodeCallbackGuid, &Hob.Raw); + if (EFI_ERROR(Status)) Hob.Raw = NULL; + } + + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PpiRegister +// +// Description: Register the callback function for ReportStatusCode() notification. +// +// Input: +// IN EFI_PEI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type +// EFI_PEI_RSC_HANDLER_CALLBACK that is to be registered. +// +// Output: +// EFI_SUCCESS The function was successfully registered. +// EFI_INVALID_PARAMETER The callback function was NULL. +// EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions can be +// registered. +// EFI_ALREADY_STARTED The function was already registered. It can't be registered again. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +PpiRegister ( + IN EFI_PEI_RSC_HANDLER_CALLBACK Callback + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry; + UINTN *NumberOfEntries; + UINTN Index; + UINTN *FreePacket; + EFI_STATUS Status; + + if (Callback == NULL) { + return EFI_INVALID_PARAMETER; + } + + Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid); + FreePacket = NULL; + while (Hob.Raw != NULL) { + NumberOfEntries = GET_GUID_HOB_DATA (Hob.Raw); + CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1); + if (*NumberOfEntries < INITIAL_RSC_PEI_ENTRIES) { + 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; + } + } + + Status = FindNextHobByGuid (&gStatusCodeCallbackGuid, &Hob.Raw); + if (EFI_ERROR(Status)) Hob.Raw = NULL; + } + + if (FreePacket == NULL) { + FreePacket = CreateRscHandlerCallbackPacket(); + } + if (FreePacket == NULL) return EFI_OUT_OF_RESOURCES; + CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (FreePacket + 1); + CallbackEntry[*FreePacket] = Callback; + *FreePacket += 1; + + return EFI_SUCCESS; +} + + +EFI_PEI_RSC_HANDLER_PPI RscHandlerPpi = { + PpiRegister, + PpiUnregister + }; + +EFI_PEI_PPI_DESCRIPTOR RscHandlerPpiDescriptor[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiPeiRscHandlerPpiGuid, + &RscHandlerPpi + } +}; + +#endif +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReportStatusCodePei +// +// Description: +// Top level status code reporting routine exposed by the status code protocol/PPI. +// Calls the various types of status code handlers +// (SimpleStatusReport, StringStatusReport, MiscStatusReport, PerformErrorCodeAction) +// Generates string from the status code data to pass to StringStatusReport function. +// Also pass all parameters to Registered Statuse Code Routers. +// +// Input: +// IN VOID *PeiServices - pointer to the PEI Boot Services table +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance - +// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function +// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReportStatusCodePei ( + IN VOID *PeiServices, + 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 +) +{ + +#if PI_SPECIFICATION_VERSION >= 0x00010014 + EFI_PEI_HOB_POINTERS Hob; + EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry; + UINTN *NumberOfEntries; + UINTN Index; + EFI_STATUS Status; + + //if (IsItRecursiveCall(&PeiRouterRecurciveStatus, FALSE, TRUE) != TRUE) + //{ //return EFI_ACCESS_DENIED; + Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid); + while (Hob.Raw != NULL) + { + NumberOfEntries = GET_GUID_HOB_DATA (Hob.Raw); + CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1); + for (Index = 0; Index < *NumberOfEntries; Index++) + { + CallbackEntry[Index]( + PeiServices, + Type, + Value, + Instance, + CallerId, + Data + ); + } + + Status = FindNextHobByGuid (&gStatusCodeCallbackGuid, &Hob.Raw); + if (EFI_ERROR(Status)) Hob.Raw = NULL; + + } +// } +// IsItRecursiveCall (&PeiRouterRecurciveStatus, TRUE, FALSE); +#endif + + return ReportStatusCode (PeiServices,Type,Value,Instance,CallerId,Data); +} + +// Status Code PPI +EFI_PEI_PROGRESS_CODE_PPI StatusCodePpi = {ReportStatusCodePei}; +// Status Code PPI Descriptor +EFI_PEI_PPI_DESCRIPTOR StatusCodePpiDescriptor[] = +{ + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gPeiStatusCodePpiGuid, &StatusCodePpi +}; + + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: PeiInitStatusCode +// +// Description: Pei "entry point" for this module, called by the Pei Core. +// Conotol flow: +// 1. Creates a RSC Hob and installs RSC PPI. +// 2. Calls InitStatusCodeParts function. +// 3. Installs the Status Code PPI. +// InitStatusCodeParts function calls initialization routines of status code subcomponents +// registered under StatusCodeInitialize eLink. +// Status Code PPI is initialized with the address of ReportStatusCode function. +// +// Input: +// *FfsHeader - pointer to the header of the current firmware file system file +// **PeiServices - pointer to the Pei Services table +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS PeiInitStatusCode( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **PeiServices +) +{ + EFI_STATUS Status; + InitStatusCodeParts(FfsHeader,PeiServices); + +#if PI_SPECIFICATION_VERSION >= 0x00010014 + CreateRscHandlerCallbackPacket (); + // First install Report Status Code Handler PPI + Status = (*PeiServices)->InstallPpi( + PeiServices, &RscHandlerPpiDescriptor[0] + ); + +#endif + // And then install the Status Code PPI + Status = (*PeiServices)->InstallPpi( + PeiServices, &StatusCodePpiDescriptor[0] + ); + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: Delay +// +// Description: Stalls execution for a passed in number of microseconds +// +// Input: +// EFI_PEI_SERVICES **PeiServices +// UINT32 Microseconds - the number of microseconds to stall execution +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID Delay(EFI_PEI_SERVICES **PeiServices, UINT32 Microseconds) +{ + EFI_PEI_STALL_PPI *Stall; + EFI_STATUS Status = (*PeiServices)->LocatePpi(PeiServices,&gPeiStallPpiGuid,0,NULL,&Stall); + + if (EFI_ERROR(Status)) return; + + Stall->Stall(PeiServices, Stall, Microseconds); +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ResetOrResume +// +// Description: Error Code Action. +// Attempts to perform a system reset. If reset fails, returns. +// +// Input: +// EFI_PEI_SERVICES **PeiServices +// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action. +// +// Output: +// VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ResetOrResume( + IN EFI_PEI_SERVICES **PeiServices, IN EFI_STATUS_CODE_VALUE Value +) +{ + (*PeiServices)->ResetSystem(PeiServices); +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file diff --git a/Core/EM/StatusCode/StatusCodeRuntime.c b/Core/EM/StatusCode/StatusCodeRuntime.c new file mode 100644 index 0000000..76d8f23 --- /dev/null +++ b/Core/EM/StatusCode/StatusCodeRuntime.c @@ -0,0 +1,768 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeRuntime.c 9 12/13/12 3:59p Oleksiyy $ +// +// $Revision: 9 $ +// +// $Date: 12/13/12 3:59p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeRuntime.c $ +// +// 9 12/13/12 3:59p Oleksiyy +// [TAG] EIP109426 +// [Category] Improvement +// [Description] Issues found by CppCheck in StatusCode eModule. +// [Files] StatuseCodeRuntime.c +// +// 8 8/09/12 5:27p Oleksiyy +// [TAG] EIP97932 +// [Category] Improvement +// [Description] StatusCode Router RT init fix +// [Files] StatusCodeRuntime.c +// +// 7 6/12/12 3:50p Oleksiyy +// [TAG] EIP90338 +// [Category] Improvement +// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to +// AmiLib.h. +// [Files] AmiLib.h, StatusCodeDxe.c and StatusCoderuntime.c +// +// 6 5/22/12 5:31p Oleksiyy +// [TAG] EIP90338 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] ChiefRiver SCT Fail on item Generic Test\EFI Compliant Test +// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined +// variable. +// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used. +// [Files] AmiLib.h, Misc.c, StatusCodeDxe.c and StatusCoderuntime.c +// +// 5 10/20/11 5:22p Oleksiyy +// [TAG] EIP72806 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] Runtime status code hangs +// [RootCause] Not converting actual status code functions addresses on +// Virtual Address Change event. +// [Solution] Status code functions converted. +// [Files] EfiLib.c, StatusCode.sdl and StatusCodeRuntime.c +// +// 4 6/23/11 6:10p Oleksiyy +// [TAG] EIP56644 +// [Category] New Feature +// [Description] Implemented PPI and Protocols, described in a PI 1.2 +// Report Status Code Router specification. +// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h, +// StatusCodeCommon.c and StatusCodeRuntime.c +// +// 3 11/18/10 4:00p Oleksiyy +// [TAG] EIP46589 +// [Category] Improvement +// [Description] All StatusCode listeners not marked as RUNTIME removed +// from runtime instance. +// [Files] StatusCodeRuntime.c +// +// 2 10/06/10 4:50p Oleksiyy +// Issue Number: 39752 +// +// Category: New Feature +// +// Description: Runtime Staus Code support is added. +// +// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c, +// CsmLib.c, AmiDxeLib.h and StatusCode eModule. +// +// 1 10/04/10 5:49p Oleksiyy +// Issue Number: 39752 and 29307 +// +// Category: New Feature +// +// Description: Support of Status Code in Runtime is added. Trace API +// keeps working after handing off control to OS. New instances of +// StatusCode services in runtime and SMM are now available. +// +// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c, +// CsmLib.c, AmiDxeLib.h and StatusCode eModule. +// +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: StatusCodeRuntime.c +// +// Description: +// File contains Runtime specific status code routines such as: +// - Entry point of the StatusCode Runtime driver +// Runtime implementation of some of the functions from the status code library. +// (Status code library is a set of generic routines utilized throughout the component). +// +//<AMI_FHDR_END> +//********************************************************************** + +#include <AmiDxeLib.h> +#include <StatusCodes.h> +#include <Protocol/StatusCode.h> +#include <Protocol/SmmStatusCode.h> +#include <StatusCodeELinks.h> +#include "StatusCodeInt.h" + +#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \ + {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93} +#if PI_SPECIFICATION_VERSION >= 0x00010014 +#include <Protocol/SmmBase2.h> +#include <Protocol/SmmReportStatusCodeHandler.h> +#include <Protocol/ReportStatusCodeHandler.h> +//----Router----------------------------------- + +#define SMM_CALLBACK_NUMBER 10 + +typedef struct { + UINT32 RegisteredSmmEntries; + EFI_SMM_RSC_HANDLER_CALLBACK RscSmmHandlerCallback[SMM_CALLBACK_NUMBER]; +} SMM_ROUTER_STRUCT; +extern BOOLEAN SmmRouter; +extern ROUTER_STRUCT_HEADER *RouterCallbackStr; +SMM_ROUTER_STRUCT SmmRouterCallbackStr; +//----Router End--------------------------------- +#endif +extern BOOLEAN StatusRuntime; +EFI_STATUS_CODE_PROTOCOL *gStatusCode = NULL; +EFI_REPORT_STATUS_CODE gOldStatusCode = NULL; + + +typedef EFI_STATUS (STRING_FUNCTION)(IN VOID *PeiServices, IN CHAR8 *String); +typedef EFI_STATUS (MY_STRING_FUNCTION)(IN VOID *PeiServices, IN CHAR8 *String); +typedef EFI_STATUS (SIMPLE_FUNCTION)( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +); +typedef EFI_STATUS (MISC_FUNCTION)( + IN VOID *PeiServices, + 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 +); +typedef VOID (CHECKPOINT_FUNCTION)(IN VOID *PeiServices, IN UINT8 Checkpoint); + + +extern EFI_STATUS DummyStringHandler(IN VOID *PeiServices, IN CHAR8 *String); +extern EFI_STATUS DummySimpleHandler( + IN VOID *PeiServices, + IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value +); +extern EFI_STATUS DummyMiscHandler( + IN VOID *PeiServices, + 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 +); + + +extern VOID DummyCheckpointHandler(IN VOID *PeiServices, IN UINT8 Checkpoint); + +extern SIMPLE_FUNCTION* SimpleList[]; +extern STRING_FUNCTION* StringList[]; +extern MISC_FUNCTION* MiscList[]; +extern CHECKPOINT_FUNCTION* CheckpointList[]; + +#define PEI(x) DUMMY_HANDLER +#define DXE(x) DUMMY_HANDLER +#define RUNTIME(x) x + +#define DUMMY_HANDLER DummyStringHandler +extern STRING_FUNCTION STRING_LIST EndOfStringList; +STRING_FUNCTION* MyStringList[] = {STRING_LIST NULL}; +#undef DUMMY_HANDLER + +#define DUMMY_HANDLER DummySimpleHandler +extern SIMPLE_FUNCTION SIMPLE_LIST EndOfSimpleList; +SIMPLE_FUNCTION* MySimpleList[] = {SIMPLE_LIST NULL}; +#undef DUMMY_HANDLER + +#define DUMMY_HANDLER DummyMiscHandler +extern MISC_FUNCTION MISC_LIST EndOfMiscList; +MISC_FUNCTION* MyMiscList[] = {MISC_LIST NULL}; +#undef DUMMY_HANDLER + +#define DUMMY_HANDLER DummyCheckpointHandler +extern CHECKPOINT_FUNCTION CHECKPOINT_LIST EndOfCheckpointList; +CHECKPOINT_FUNCTION* MyCheckpointList[] = {CHECKPOINT_LIST NULL}; +#undef DUMMY_HANDLER + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitElinks +// +// Description: This function inits all Statuse code E-links that dose not have RUNTIME mark +// as dummy. While leaving only RUNTIME marked E-links . +// +// Input: None +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID InitElinks () +{ + UINTN i; + + for (i=0; SimpleList[i]; i++){ + if (MySimpleList[i]== SimpleList[i]) + SimpleList[i]= DummySimpleHandler; + else + SimpleList[i]= MySimpleList[i]; + } + for (i=0; StringList[i]; i++){ + if (MyStringList[i]== StringList[i]) + StringList[i]= DummyStringHandler; + else + StringList[i]= MyStringList[i]; + } + for (i=0; MiscList[i]; i++){ + if (MyMiscList[i]== MiscList[i]) + MiscList[i]= DummyMiscHandler; + else + MiscList[i]= MyMiscList[i]; + } + for (i=0; CheckpointList[i]; i++){ + if (MyCheckpointList[i]== CheckpointList[i]) + CheckpointList[i]= DummyCheckpointHandler; + else + CheckpointList[i]= MyCheckpointList[i]; + } + return; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RuntimeReportStatusCode +// +// Description: Runtime Status Code Reporting function. +// A wrapper around phase independent ReportStatucCode +// function defined in StatusCodeCommon.c. +// +// Input: +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance Instance - Instance +// *CallerId OPTIONAL - The GUID of the caller function +// *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RuntimeReportStatusCode ( + 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 +) +{ + //If we are not in runtime call old function. + + if (!StatusRuntime) return ( gOldStatusCode( Type, Value, Instance, CallerId, Data)); + + return ( ReportStatusCode( NULL, Type, Value, Instance, CallerId, Data)); +} + +#if PI_SPECIFICATION_VERSION >= 0x00010014 +extern BOOLEAN RouterRecurciveStatus; +BOOLEAN IsItRecursiveCall ( + IN OUT BOOLEAN *Value, + IN BOOLEAN CompareWith, + IN BOOLEAN SvitchTo + ); + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ReportStatusCodePei +// +// Description: +// Pass all parameters to Registered Statuse Code Routers. +// +// Input: +// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance - +// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function +// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS ReportSmmRouter ( + 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 + ) +{ + + UINT32 i; + + if ((SmmRouterCallbackStr.RegisteredSmmEntries == 0) || (IsItRecursiveCall (&RouterRecurciveStatus, FALSE, TRUE) == TRUE)) + return EFI_ACCESS_DENIED; + for (i = 0; i != SmmRouterCallbackStr.RegisteredSmmEntries; i++) + { + if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == NULL) + continue;//Unregistered function + else + SmmRouterCallbackStr.RscSmmHandlerCallback[i] (Type, Value, Instance, CallerId, Data); + } + // Restore the Recursive status of report + + IsItRecursiveCall (&RouterRecurciveStatus, TRUE, FALSE); + return EFI_SUCCESS; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmmRegister +// +// Description: Remove a previously registered callback function from the notification list. +// +// Input: +// IN EFI_SMM_RSC_HANDLER_CALLBACK Callback - A pointer to a function that +// that is to be unregistered. +// +// Output: +// EFI_SUCCESS Function was successfully unregistered. +// EFI_INVALID_PARAMETER The callback function was NULL. +// EFI_NOT_FOUND The callback function was not found to be unregistered. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS +SmmUnregister ( + IN EFI_SMM_RSC_HANDLER_CALLBACK Callback + ) +{ + UINT32 i; + + if (Callback == NULL) return EFI_INVALID_PARAMETER; + + for (i = 0; i != SmmRouterCallbackStr.RegisteredSmmEntries; i++) + { + if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == Callback) + { + SmmRouterCallbackStr.RscSmmHandlerCallback[i] = NULL; + return EFI_SUCCESS; //Function Unregistered + } + } + + return EFI_NOT_FOUND; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmmRegister +// +// Description: 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. +// +// Input: +// IN EFI_SMM_RSC_HANDLER_CALLBACK Callback - A pointer to a function that +// is called when a call to ReportStatusCode() occurs. +// +// Output: +// EFI_SUCCESS Function was successfully registered. +// EFI_INVALID_PARAMETER The callback function was NULL. +// EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions +// can be registered. +// EFI_ALREADY_STARTED The function was already registered. It can't be +// registered again. +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS + +SmmRegister ( + IN EFI_SMM_RSC_HANDLER_CALLBACK Callback + ) +{ + UINT32 i=0, FreeEntry = -1; + + if (Callback == NULL) + return EFI_INVALID_PARAMETER; + if (SmmRouterCallbackStr.RegisteredSmmEntries != 0) + { + for (i = 0; i != SmmRouterCallbackStr.RegisteredSmmEntries; i++) + { + if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == Callback) + return EFI_ALREADY_STARTED; //Function already registered + if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == NULL) + FreeEntry = i; + } + if (FreeEntry = -1) //No Unregistered entries + { + if (SmmRouterCallbackStr.RegisteredSmmEntries == SMM_CALLBACK_NUMBER - 1) + return EFI_OUT_OF_RESOURCES; // And all entries are taken already - exit + FreeEntry = i; + SmmRouterCallbackStr.RegisteredSmmEntries++; + } + } + else + { + SmmRouterCallbackStr.RegisteredSmmEntries++; + FreeEntry = 0; + } + SmmRouterCallbackStr.RscSmmHandlerCallback[FreeEntry] = Callback; + + return EFI_SUCCESS; +} + +EFI_SMM_RSC_HANDLER_PROTOCOL mSmmRscHandlerProtocol = { + SmmRegister, + SmmUnregister + }; + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: InitRouterAdress +// +// Description: Reads variable with the address of RSC Info structure and +// initialize global variable with it. +// +// Input: None +// +// Output: +// VOID +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID InitRouterAdress() +{ + EFI_PHYSICAL_ADDRESS RSCInfoAddresss; + UINTN SizeOfRCInfo = sizeof(EFI_PHYSICAL_ADDRESS); + EFI_STATUS Status; + + if (RouterCallbackStr == NULL) + { + Status = pRS->GetVariable( + L"RSCInfoAddresss", + &gAmiGlobalVariableGuid, + NULL, + &SizeOfRCInfo, + &RSCInfoAddresss + ); + if (!EFI_ERROR(Status)) + RouterCallbackStr = (ROUTER_STRUCT_HEADER*) RSCInfoAddresss; + } + +} +//----Router End-------------------------------- + +#endif + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: ScRuntimeVirtualAddressChange +// +// Description: +// Updates pointers to RSC structure and to callback functions inside structure. +// +// Input: +// N EFI_EVENT Event - signaled event. +// IN VOID *Context - Context +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID ScRuntimeVirtualAddressChange (IN EFI_EVENT Event, IN VOID *Context) +{ +#if PI_SPECIFICATION_VERSION >= 0x00010014 + RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry; + VOID *Ptr; +#endif + UINTN i; + + for (i=0; SimpleList[i]; i++){ + pRS->ConvertPointer(0,(VOID**)&(SimpleList[i])); + } + + for (i=0; StringList[i]; i++){ + pRS->ConvertPointer(0,(VOID**)&(StringList[i])); + } + + for (i=0; MiscList[i]; i++){ + pRS->ConvertPointer(0,(VOID**)&(MiscList[i])); + } + + for (i=0; CheckpointList[i]; i++){ + pRS->ConvertPointer(0,(VOID**)&(CheckpointList[i])); + } + pRS->ConvertPointer(0,(VOID**)&(gStatusCode->ReportStatusCode)); +#if PI_SPECIFICATION_VERSION >= 0x00010014 + if (RouterCallbackStr == NULL) + InitRouterAdress(); + if (RouterCallbackStr == NULL) + return; + for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++) + { + + if (i == 0) + Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER); + else + Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY); + CallbackEntry = Ptr; + + if (CallbackEntry->RscHandlerCallback == NULL) continue;//Unregistered function + else pRS->ConvertPointer(0,(VOID**)&(CallbackEntry->RscHandlerCallback)); + + } + + pRS->ConvertPointer(0,(VOID**)&RouterCallbackStr); +#endif +} + + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmmReportStatusCode +// +// Description: SMM Status Code Reporting function. +// A wrapper around phase independent ReportStatucCode +// function defined in StatusCodeCommon.c. +// +// Input: +// IN CONST EFI_SMM_STATUS_CODE_PROTOCOL *This - +// Points to this instance of the EFI_SMM_STATUS_CODE_PROTOCOL. +// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error +// IN UINT32 Instance Instance - Instance +// *CallerId OPTIONAL - The GUID of the caller function +// *Data OPTIONAL - the extended data field that contains additional info +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS SmmReportStatusCode ( + IN CONST EFI_SMM_STATUS_CODE_PROTOCOL *This, 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 +) +{ + EFI_STATUS Status; + +#if PI_SPECIFICATION_VERSION >= 0x00010014 + SmmRouter = TRUE; + ReportSmmRouter (Type, Value, Instance, CallerId, Data); +#endif + Status = ReportStatusCode( NULL, Type, Value, Instance, CallerId, Data); +#if PI_SPECIFICATION_VERSION >= 0x00010014 + SmmRouter = FALSE; +#endif + return Status; +} + + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RuntimeStatusCodeExitBS +// +// Description: Exit Boot Services event handler. +// Terminates boot time status code processing +// +// Input: +// IN EFI_EVENT Event - not used +// IN VOID *Context - not used +// +// Output: VOID +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +VOID RuntimeStatusCodeExitBS (IN EFI_EVENT Event, IN VOID *Context) +{ +#if PI_SPECIFICATION_VERSION >= 0x00010014 + InitRouterAdress(); +#endif + StatusRuntime = TRUE; + +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: RuntimeInitStatusCode +// +// Description: +// Entry point of the StatusCode Runtime Driver. +// Calls InitStatusCodeParts function, installs the Status Code Protocol, +// and registers event handlers for the legacy boot and exit boot services events. +// RuntimeInitStatusCode installs different protocol based on value of the +// EFI_SPECIFICATION_VERSION SDL token (defined in Core.sdl). +// If value of the EFI_SPECIFICATION_VERSION constant is less than 0x20000, +// framework EFI_STATUS_CODE_ARCH_PROTOCOL_GUID protocol is installed; +// otherwise, PI EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID protocol is installed. +// PI Status Code Protocol is initialized with the address of RuntimeReportStatusCode function. +// +// Input: +// *ImageHandle - The firmware allocate handle for the EFI image +// *SystemTable - pointer to the EFI System Table +// +// Output: EFI_STATUS +// +// Modified: StatusCode Arch Protocol- now published +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS RuntimeInitStatusCode( + IN EFI_HANDLE *ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; + EFI_EVENT Event; + + InitAmiRuntimeLib( + ImageHandle, SystemTable, RuntimeStatusCodeExitBS, ScRuntimeVirtualAddressChange + ); + + InitElinks(); + Status = SystemTable->BootServices->LocateProtocol( +#if EFI_SPECIFICATION_VERSION < 0x20000 + &gEfiStatusCodeArchProtocolGuid, +#else + &gEfiStatusCodeRuntimeProtocolGuid, +#endif + NULL, &gStatusCode + ); + gOldStatusCode = gStatusCode->ReportStatusCode; + gStatusCode->ReportStatusCode = RuntimeReportStatusCode; +#if EFI_SPECIFICATION_VERSION < 0x20000 + SystemTable->RuntimeServices->ReportStatusCode = RuntimeReportStatusCode; +#endif + + //Register Exit Boot Services Callback + + CreateLegacyBootEvent(TPL_CALLBACK, &RuntimeStatusCodeExitBS, NULL, &Event); + + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: SmmInitStatusCode +// +// Description: +// Entry point of the StatusCode SMM Driver. +// +// Input: +// IN EFI_HANDLE *ImageHandle - The firmware allocate handle for the EFI image +// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the EFI System Table +// +// Output: EFI_STATUS +// +// Modified: StatusCode Arch Protocol- now published +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> + + +EFI_STATUS SmmInitStatusCode( + IN EFI_HANDLE *ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; + EFI_HANDLE StatusCodeHandle = NULL; + static EFI_SMM_STATUS_CODE_PROTOCOL StatusCode = {SmmReportStatusCode}; + +#if PI_SPECIFICATION_VERSION >= 0x00010014 + EFI_HANDLE SmmRscHandle = NULL; + EFI_GUID gEfiSmmRscHandlerProtocolGuid = EFI_SMM_RSC_HANDLER_PROTOCOL_GUID; + EFI_SMM_SYSTEM_TABLE2 *pSmst2 = NULL; + EFI_SMM_BASE2_PROTOCOL *mInternalSmmBase2 = NULL; + + SmmRouterCallbackStr.RegisteredSmmEntries = 0; + + Status = SystemTable->BootServices->LocateProtocol ( + &gEfiSmmBase2ProtocolGuid, + NULL, + (VOID **)&mInternalSmmBase2 + ); + + Status=mInternalSmmBase2->GetSmstLocation (mInternalSmmBase2, &pSmst2); + ASSERT (pSmst2 != NULL); + Status = pSmst2->SmmInstallProtocolInterface( + &SmmRscHandle, + &gEfiSmmRscHandlerProtocolGuid, + EFI_NATIVE_INTERFACE, + &mSmmRscHandlerProtocol + ); + ASSERT_EFI_ERROR (Status); +#endif + + InitElinks (); + Status = SystemTable->BootServices->InstallProtocolInterface( + &StatusCodeHandle, + &gEfiSmmStatusCodeProtocolGuid, + EFI_NATIVE_INTERFACE, &StatusCode + ); +#if PI_SPECIFICATION_VERSION >= 0x00010014 + Status = pSmst2->SmmInstallProtocolInterface( + &StatusCodeHandle, + &gEfiSmmStatusCodeProtocolGuid, + EFI_NATIVE_INTERFACE, &StatusCode + ); + +#endif + return Status; +} + +//<AMI_PHDR_START> +//---------------------------------------------------------------------------- +// Procedure: StatusCodeSmmEntry +// +// Description: This function is the entry point for this file. This function +// installs services in and outside SMM. +// +// Input: IN EFI_HANDLE ImageHandle - Image handle +// IN EFI_SYSTEM_TABLE *SystemTable - Pointer to the system table +// +// Output: EFI_STATUS - Status based on errors that occurred while waiting for +// time to expire. +// +//---------------------------------------------------------------------------- +//<AMI_PHDR_END> +EFI_STATUS StatusCodeSmmEntry( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable +) +{ + InitAmiLib(ImageHandle,SystemTable); + return InitSmmHandlerEx( + ImageHandle, SystemTable, SmmInitStatusCode, RuntimeInitStatusCode + ); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//**********************************************************************
\ No newline at end of file |