123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- /** @file
- Report Status Code Router PEIM which produces Report Stataus Code Handler PPI and Status Code PPI.
- @copyright
- Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "ExReportStatusCodeRouterPei.h"
- EFI_PEI_RSC_HANDLER_PPI mRscHandlerPpi = {
- Register,
- Unregister
- };
- EFI_PEI_PROGRESS_CODE_PPI mStatusCodePpi = {
- ReportDispatcher
- };
- EFI_PEI_PPI_DESCRIPTOR mRscHandlerPpiList[] = {
- {
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
- &gEfiPeiRscHandlerPpiGuid,
- &mRscHandlerPpi
- }
- };
- EFI_PEI_PPI_DESCRIPTOR mStatusCodePpiList[] = {
- {
- EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
- &gEfiPeiStatusCodePpiGuid,
- &mStatusCodePpi
- }
- };
- /**
- Worker function to create one memory status code GUID'ed HOB,
- using PacketIndex to identify the packet.
- @param PacketIndex Index of records packet.
- @return Pointer to the memory status code packet.
- **/
- UINTN *
- CreateRscHandlerCallbackPacket (
- VOID
- )
- {
- UINTN *NumberOfEntries;
- EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry;
- UINT16 Index;
- //
- // Build GUID'ed HOB with PCD defined size.
- //
- NumberOfEntries = BuildGuidHob (
- &gStatusCodeCallbackGuid,
- sizeof (EFI_PEI_RSC_HANDLER_CALLBACK) * 64 + sizeof (UINTN)
- );
- ASSERT (NumberOfEntries != NULL);
- if (NumberOfEntries == NULL) {
- return NumberOfEntries;
- }
- *NumberOfEntries = 0;
- CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
- for (Index = 0; Index < 64; Index++) {
- CallbackEntry[Index] = NULL;
- }
- return NumberOfEntries;
- }
- /**
- Register the callback function for ReportStatusCode() notification.
- When this function is called the function pointer is added to an internal list and any future calls to
- ReportStatusCode() will be forwarded to the Callback function.
- @param[in] Callback A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is called
- when a call to ReportStatusCode() occurs.
- @retval EFI_SUCCESS Function was successfully registered.
- @retval EFI_INVALID_PARAMETER The callback function was NULL.
- @retval EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions can be
- registered.
- @retval EFI_ALREADY_STARTED The function was already registered. It can't be registered again.
- **/
- EFI_STATUS
- EFIAPI
- Register (
- IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
- )
- {
- EFI_PEI_HOB_POINTERS Hob;
- EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry;
- UINTN *NumberOfEntries;
- UINTN Index;
- if (Callback == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
- if (Hob.Raw != NULL) {
- NumberOfEntries = GET_GUID_HOB_DATA (Hob);
- CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
- if (*NumberOfEntries >= 64) {
- //
- // If current total number of handlers does exceed 64, bail
- //
- return EFI_OUT_OF_RESOURCES;
- }
- 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;
- }
- if (CallbackEntry[Index] == NULL) {
- //
- // If the total number of handlers in current packet is max value 64,
- // search an entry with NULL pointer and fill new handler into this entry.
- //
- *NumberOfEntries += 1;
- CallbackEntry[Index] = Callback;
- return EFI_SUCCESS;
- }
- }
- }
- return EFI_NOT_FOUND;
- }
- /**
- Remove a previously registered callback function from the notification list.
- ReportStatusCode() messages will no longer be forwarded to the Callback function.
- @param[in] Callback A pointer to a function of type EFI_PEI_RSC_HANDLER_CALLBACK that is to be
- unregistered.
- @retval EFI_SUCCESS The function was successfully unregistered.
- @retval EFI_INVALID_PARAMETER The callback function was NULL.
- @retval EFI_NOT_FOUND The callback function was not found to be unregistered.
- **/
- EFI_STATUS
- EFIAPI
- Unregister (
- IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
- )
- {
- EFI_PEI_HOB_POINTERS Hob;
- EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry;
- UINTN *NumberOfEntries;
- UINTN Index;
- if (Callback == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
- if (Hob.Raw != NULL) {
- NumberOfEntries = GET_GUID_HOB_DATA (Hob);
- CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
- for (Index = 0; Index < *NumberOfEntries; Index++) {
- if (CallbackEntry[Index] == Callback) {
- //
- // Set removed entry as NULL.
- //
- CallbackEntry[Index] = NULL;
- return EFI_SUCCESS;
- }
- }
- }
- return EFI_NOT_FOUND;
- }
- /**
- Publishes an interface that allows PEIMs to report status codes.
- This function implements EFI_PEI_PROGRESS_CODE_PPI.ReportStatusCode().
- It publishes an interface that allows PEIMs to report status codes.
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param CodeType Indicates the type of status code being reported.
- @param Value Describes the current status of a hardware or
- software entity. This includes information about the class and
- subclass that is used to classify the entity as well as an operation.
- For progress codes, the operation is the current activity.
- For error codes, it is the exception.For debug codes,it is not defined at this time.
- @param Instance The enumeration of a hardware or software entity within
- the system. A system may contain multiple entities that match a class/subclass
- pairing. The instance differentiates between them. An instance of 0 indicates
- that instance information is unavailable, not meaningful, or not relevant.
- Valid instance numbers start with 1.
- @param CallerId This optional parameter may be used to identify the caller.
- This parameter allows the status code driver to apply different rules to
- different callers.
- @param Data This optional parameter may be used to pass additional data.
- @retval EFI_SUCCESS The function completed successfully.
- **/
- EFI_STATUS
- EFIAPI
- ReportDispatcher (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_STATUS_CODE_TYPE CodeType,
- IN EFI_STATUS_CODE_VALUE Value,
- IN UINT32 Instance,
- IN CONST EFI_GUID *CallerId OPTIONAL,
- IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
- )
- {
- EFI_PEI_HOB_POINTERS Hob;
- EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry;
- UINTN *NumberOfEntries;
- UINTN Index;
- Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
- if (Hob.Raw != NULL) {
- NumberOfEntries = GET_GUID_HOB_DATA (Hob);
- CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
- for (Index = 0; Index < *NumberOfEntries; Index++) {
- if (CallbackEntry[Index] != NULL) {
- CallbackEntry[Index](
- PeiServices,
- CodeType,
- Value,
- Instance,
- CallerId,
- Data
- );
- }
- }
- }
- return EFI_SUCCESS;
- }
- /**
- Entry point of Status Code PEIM.
- This function is the entry point of this Status Code Router PEIM.
- It produces Report Stataus Code Handler PPI and Status Code PPI.
- @param FileHandle Handle of the file being invoked.
- @param PeiServices Describes the list of possible PEI Services.
- @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.
- **/
- EFI_STATUS
- EFIAPI
- GenericStatusCodePeiEntry (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
- {
- EFI_STATUS Status;
- EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
- EFI_PEI_PROGRESS_CODE_PPI *OldStatusCodePpi;
- CreateRscHandlerCallbackPacket ();
- //
- // Install Report Status Code Handler PPI
- //
- Status = PeiServicesInstallPpi (mRscHandlerPpiList);
- ASSERT_EFI_ERROR (Status);
- //
- // Install Status Code PPI. PI spec specifies that there can be only one instance
- // of this PPI in system. So first check if other instance already exists.
- // If no other instance exists, then just install the PPI.
- // If other instance already exists, then reinstall it.
- //
- Status = PeiServicesLocatePpi (
- &gEfiPeiStatusCodePpiGuid,
- 0,
- &OldDescriptor,
- (VOID **) &OldStatusCodePpi
- );
- if (!EFI_ERROR (Status)) {
- Status = PeiServicesReInstallPpi (OldDescriptor, mStatusCodePpiList);
- } else {
- Status = PeiServicesInstallPpi (mStatusCodePpiList);
- }
- ASSERT_EFI_ERROR (Status);
- return EFI_SUCCESS;
- }
|