/** @file
  Support functions for UEFI protocol notification infrastructure.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PiSmmCore.h"

/**
  Signal event for every protocol in protocol entry.

  @param  Prot                   Protocol interface

**/
VOID
SmmNotifyProtocol (
  IN PROTOCOL_INTERFACE  *Prot
  )
{
  PROTOCOL_ENTRY   *ProtEntry;
  PROTOCOL_NOTIFY  *ProtNotify;
  LIST_ENTRY       *Link;

  ProtEntry = Prot->Protocol;
  for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
    ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
    ProtNotify->Function (&ProtEntry->ProtocolID, Prot->Interface, Prot->Handle);
  }
}

/**
  Removes Protocol from the protocol list (but not the handle list).

  @param  Handle                 The handle to remove protocol on.
  @param  Protocol               GUID of the protocol to be moved
  @param  Interface              The interface of the protocol

  @return Protocol Entry

**/
PROTOCOL_INTERFACE *
SmmRemoveInterfaceFromProtocol (
  IN IHANDLE   *Handle,
  IN EFI_GUID  *Protocol,
  IN VOID      *Interface
  )
{
  PROTOCOL_INTERFACE  *Prot;
  PROTOCOL_NOTIFY     *ProtNotify;
  PROTOCOL_ENTRY      *ProtEntry;
  LIST_ENTRY          *Link;

  Prot = SmmFindProtocolInterface (Handle, Protocol, Interface);
  if (Prot != NULL) {

    ProtEntry = Prot->Protocol;

    //
    // If there's a protocol notify location pointing to this entry, back it up one
    //
    for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
      ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);

      if (ProtNotify->Position == &Prot->ByProtocol) {
        ProtNotify->Position = Prot->ByProtocol.BackLink;
      }
    }

    //
    // Remove the protocol interface entry
    //
    RemoveEntryList (&Prot->ByProtocol);
  }

  return Prot;
}

/**
  Add a new protocol notification record for the request protocol.

  @param  Protocol               The requested protocol to add the notify
                                 registration
  @param  Function               Points to the notification function
  @param  Registration           Returns the registration record

  @retval EFI_SUCCESS            Successfully returned the registration record
                                 that has been added or unhooked
  @retval EFI_INVALID_PARAMETER  Protocol is NULL or Registration is NULL
  @retval EFI_OUT_OF_RESOURCES   Not enough memory resource to finish the request
  @retval EFI_NOT_FOUND          If the registration is not found when Function == NULL

**/
EFI_STATUS
EFIAPI
SmmRegisterProtocolNotify (
  IN  CONST EFI_GUID     *Protocol,
  IN  EFI_SMM_NOTIFY_FN  Function,
  OUT VOID               **Registration
  )
{
  PROTOCOL_ENTRY   *ProtEntry;
  PROTOCOL_NOTIFY  *ProtNotify;
  LIST_ENTRY       *Link;
  EFI_STATUS       Status;

  if (Protocol == NULL || Registration == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Function == NULL) {
    //
    // Get the protocol entry per Protocol
    //
    ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, FALSE);
    if (ProtEntry != NULL) {
      ProtNotify = (PROTOCOL_NOTIFY * )*Registration;
      for (Link = ProtEntry->Notify.ForwardLink;
           Link != &ProtEntry->Notify;
           Link = Link->ForwardLink) {
        //
        // Compare the notification record
        //
        if (ProtNotify == (CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE))){
          //
          // If Registration is an existing registration, then unhook it
          //
          ProtNotify->Signature = 0;
          RemoveEntryList (&ProtNotify->Link);
          FreePool (ProtNotify);
          return EFI_SUCCESS;
        }
      }
    }
    //
    // If the registration is not found
    //
    return EFI_NOT_FOUND;
  }

  ProtNotify = NULL;

  //
  // Get the protocol entry to add the notification too
  //
  ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE);
  if (ProtEntry != NULL) {
    //
    // Find whether notification already exist
    //
    for (Link = ProtEntry->Notify.ForwardLink;
         Link != &ProtEntry->Notify;
         Link = Link->ForwardLink) {

      ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
      if (CompareGuid (&ProtNotify->Protocol->ProtocolID, Protocol) &&
          (ProtNotify->Function == Function)) {

        //
        // Notification already exist
        //
        *Registration = ProtNotify;

        return EFI_SUCCESS;
      }
    }

    //
    // Allocate a new notification record
    //
    ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY));
    if (ProtNotify != NULL) {
      ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;
      ProtNotify->Protocol = ProtEntry;
      ProtNotify->Function = Function;
      //
      // Start at the ending
      //
      ProtNotify->Position = ProtEntry->Protocols.BackLink;

      InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);
    }
  }

  //
  // Done.  If we have a protocol notify entry, then return it.
  // Otherwise, we must have run out of resources trying to add one
  //
  Status = EFI_OUT_OF_RESOURCES;
  if (ProtNotify != NULL) {
    *Registration = ProtNotify;
    Status = EFI_SUCCESS;
  }
  return Status;
}
