EFI_STATUS
BBTestWaitForEvent_Conf_Sub3 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib
  )
{
  EFI_STATUS          Status;
  EFI_TEST_ASSERTION  AssertionType;
  EFI_EVENT           Event;
  UINTN               EventIndex;

  //
  // Create an event
  //
  Status = gtBS->CreateEvent (
                   EFI_EVENT_NOTIFY_WAIT,
                   EFI_TPL_NOTIFY,
                   NotifyFunction,
                   NULL,
                   &Event
                   );
  if (EFI_ERROR (Status)) {
    EFI_TEST_GENERIC_FAILURE (L"BS.WaitForEvent - Create event", Status);
    return Status;
  }

  //
  // Wait for event with invalid event number
  //
  Status = gtBS->WaitForEvent (0, &Event, &EventIndex);

  if (Status == EFI_INVALID_PARAMETER) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gEventTimerTaskPriorityServicesBBTestWaitForEventAssertionGuid006,
                 L"BS.WaitForEvent - Invoke WaitForEvent with invalid event number.",
                 L"%a:%d:Status - %r",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status
                 );

  //
  // Close the event
  //
  gtBS->CloseEvent (Event);

  //
  // Done
  //
  return EFI_SUCCESS;
}
EFI_STATUS
BBTestCheckEvent_Func_Sub4 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib
  )
{
  EFI_STATUS          Status;
  EFI_TEST_ASSERTION  AssertionType;
  EFI_EVENT           Event;

  //
  // Create an event with notify function, which signals itself
  //
  Status = gtBS->CreateEvent (
                   EFI_EVENT_NOTIFY_WAIT,
                   EFI_TPL_NOTIFY,
                   NotifyFunctionSignal,
                   NULL,
                   &Event
                   );
  if (EFI_ERROR (Status)) {
    EFI_TEST_GENERIC_FAILURE (L"BS.CheckEvent - Create event", Status);
    return Status;
  }

  //
  // Check this event
  //
  Status = gtBS->CheckEvent (Event);

  if (Status == EFI_SUCCESS) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gEventTimerTaskPriorityServicesBBTestCheckEventAssertionGuid002,
                 L"BS.CheckEvent - Check event with notify function (signal).",
                 L"%a:%d:Status - %r",
                 __FILE__,
                 __LINE__,
                 Status
                 );

  //
  // Close the event
  //
  gtBS->CloseEvent (Event);

  //
  // Done
  //
  return EFI_SUCCESS;
}
EFI_STATUS
BBTestCheckEvent_Conf_Sub1 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib
  )
{
  EFI_STATUS          Status;
  EFI_TEST_ASSERTION  AssertionType;
  EFI_EVENT           Event;

  //
  // Create an event with type being EVT_NOTIFY_SIGNAL
  //
  Status = gtBS->CreateEvent (
                   EFI_EVENT_NOTIFY_SIGNAL,
                   EFI_TPL_NOTIFY,
                   NotifyFunction,
                   NULL,
                   &Event
                   );
  if (EFI_ERROR (Status)) {
    EFI_TEST_GENERIC_FAILURE (L"BS.CheckEvent - Create event", Status);
    return Status;
  }

  //
  // Check this event
  //
  Status = gtBS->CheckEvent (Event);

  if (Status == EFI_INVALID_PARAMETER) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gEventTimerTaskPriorityServicesBBTestCheckEventAssertionGuid003,
                 L"BS.CheckEvent - Check event with invalid event type.",
                 L"%a:%d:Status - %r",
                 __FILE__,
                 __LINE__,
                 Status
                 );

  //
  // Close the event
  //
  gtBS->CloseEvent (Event);

  //
  // Done
  //
  return EFI_SUCCESS;
}
EFI_STATUS
BBTestSignalEvent_Func_Sub1 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib
  )
{
  EFI_STATUS          Status;
  EFI_STATUS          Status1;
  EFI_STATUS          Status2;
  UINTN               Index;
  UINTN               SubIndex;
  EFI_TPL             OldTpl;
  UINT32              EventTypes[] = {
                        EFI_EVENT_NOTIFY_SIGNAL,
                        0
                      };
  EFI_TPL             NotifyTpls[] = {
                        EFI_TPL_CALLBACK,
                        EFI_TPL_NOTIFY,
                        0
                      };
  EFI_TEST_ASSERTION  AssertionType;
  EFI_EVENT           Event;
  UINTN               Buffer[2];

  //
  // Walk through common event types and notify TPLs
  //
  for (Index = 0; EventTypes[Index] != 0; Index++) {
    for (SubIndex = 0; NotifyTpls[SubIndex] != 0; SubIndex++) {
      //
      // Create event with valid parameters
      //
      Buffer[0] = 0;
      Buffer[1] = 0;
      Status = gtBS->CreateEvent (
                       EventTypes[Index],
                       NotifyTpls[SubIndex],
                       NotifyFunction,
                       Buffer,
                       &Event
                       );
      if (EFI_ERROR (Status)) {
        EFI_TEST_GENERIC_FAILURE (L"BS.SignalEvent - Create event", Status);
        return Status;
      }

      //
      // Signal event in the EFI_TPL_CALLBACK
      //
      OldTpl  = gtBS->RaiseTPL (EFI_TPL_CALLBACK);
      Status1 = gtBS->SignalEvent (Event);
      Status2 = gtBS->SignalEvent (Event);
      gtBS->RestoreTPL (OldTpl);

      if ((Status1   == EFI_SUCCESS) &&
          (Status2   == EFI_SUCCESS) &&
          ((NotifyTpls[SubIndex] >  EFI_TPL_CALLBACK) && (Buffer[1] == 2) ||
           (NotifyTpls[SubIndex] <= EFI_TPL_CALLBACK) && (Buffer[1] == 1)
          )) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gEventTimerTaskPriorityServicesBBTestSignalEventAssertionGuid001,
                     L"BS.SignalEvent - Signal event with valid parameters.",
                     L"%a:%d:Status1 - %r, Status2 - %r, EventType - 0x%08x, NotifyTpl - %d, Count - %d",
                     __FILE__,
                     __LINE__,
                     Status1,
                     Status2,
                     EventTypes[Index],
                     NotifyTpls[SubIndex],
                     Buffer[1]
                     );

      //
      // Close the event
      //
      gtBS->CloseEvent (Event);
    }
  }

  //
  // Done
  //
  return EFI_SUCCESS;
}
EFI_STATUS
BBTestCloseEvent_Func_Sub1 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib
  )
{
  EFI_STATUS          Status;
  UINTN               Index;
  UINTN               SubIndex;
  UINT32              EventTypes[] = {
                        EFI_EVENT_TIMER,
                        EFI_EVENT_NOTIFY_WAIT,
                        EFI_EVENT_NOTIFY_SIGNAL,
                        0
                      };
  EFI_TPL             NotifyTpls[] = {
                        EFI_TPL_CALLBACK,
                        EFI_TPL_NOTIFY,
                        0
                      };
  EFI_TEST_ASSERTION  AssertionType;
  EFI_EVENT           Event;

  //
  // Walk through the common event types and notify TPLs
  //
  for (Index = 0; EventTypes[Index] != 0; Index++) {
    for (SubIndex = 0; NotifyTpls[SubIndex] != 0; SubIndex++) {
      //
      // Create an event
      //
      Status = gtBS->CreateEvent (
                       EventTypes[Index],
                       NotifyTpls[SubIndex],
                       NotifyFunction,
                       NULL,
                       &Event
                       );
      if (EFI_ERROR (Status)) {
        EFI_TEST_GENERIC_FAILURE (L"BS.CloseEvent - Create event", Status);
        return Status;
      }

      //
      // Close the event
      //
      Status = gtBS->CloseEvent (Event);

      if (Status == EFI_SUCCESS) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
      } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
      }

      StandardLib->RecordAssertion (
                     StandardLib,
                     AssertionType,
                     gEventTimerTaskPriorityServicesBBTestCloseEventAssertionGuid001,
                     L"BS.CloseEvent - Close event with valid parameters.",
                     L"%a:%d:Status - %r, EventType - 0x%08x, NotifyTpl - %d",
                     __FILE__,
                     (UINTN)__LINE__,
                     Status,
                     EventTypes[Index],
                     NotifyTpls[SubIndex]
                     );
    }
  }

  //
  // Done
  //
  return EFI_SUCCESS;
}
EFI_STATUS
BBTestWaitForEvent_Func_Sub2 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib
  )
{
  EFI_STATUS          Status;
  EFI_TEST_ASSERTION  AssertionType;
  EFI_EVENT           Event[2];
  UINTN               EventIndex;

  //
  // Create an event
  //
  Status = gtBS->CreateEvent (
                   EFI_EVENT_NOTIFY_WAIT,
                   EFI_TPL_NOTIFY,
                   NotifyFunction,
                   NULL,
                   &Event[0]
                   );
  if (EFI_ERROR (Status)) {
    EFI_TEST_GENERIC_FAILURE (L"BS.WaitForEvent - Create event", Status);
    return Status;
  }

  //
  // Create a timer event and set it
  //
  Status = gtBS->CreateEvent (
                   EFI_EVENT_TIMER,
                   EFI_TPL_NOTIFY,
                   NotifyFunction,
                   NULL,
                   &Event[1]
                   );
  if (EFI_ERROR (Status)) {
    EFI_TEST_GENERIC_FAILURE (L"BS.WaitForEvent - Create timer event", Status);
    gtBS->CloseEvent (Event[0]);
    return Status;
  }

  Status = gtBS->SetTimer (
                   Event[1],
                   TimerRelative,
                   10000000           // 1 second
                   );
  if (EFI_ERROR (Status)) {
    EFI_TEST_GENERIC_FAILURE (L"BS.WaitForEvent - Set timer", Status);
    gtBS->CloseEvent (Event[0]);
    gtBS->CloseEvent (Event[1]);
    return Status;
  }

  //
  // Wait for event with signaled event
  //
  Status = gtBS->WaitForEvent (2, Event, &EventIndex);

  if ((Status     == EFI_SUCCESS) &&
      (EventIndex == 1          )) {
    AssertionType = EFI_TEST_ASSERTION_PASSED;
  } else {
    AssertionType = EFI_TEST_ASSERTION_FAILED;
  }

  StandardLib->RecordAssertion (
                 StandardLib,
                 AssertionType,
                 gEventTimerTaskPriorityServicesBBTestWaitForEventAssertionGuid002,
                 L"BS.WaitForEvent - Invoke WaitForEvent with timer event.",
                 L"%a:%d:Status - %r, EventIndex - %d",
                 __FILE__,
                 (UINTN)__LINE__,
                 Status,
                 EventIndex
                 );

  //
  // Close the event
  //
  gtBS->CloseEvent (Event[0]);
  gtBS->CloseEvent (Event[1]);

  //
  // Done
  //
  return EFI_SUCCESS;
}
EFI_STATUS
BBTestWaitForEvent_Conf_Sub1 (
  IN EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib
  )
{
  EFI_STATUS          Status;
  UINTN               Index;
  EFI_TPL             OldTpl;
  EFI_TPL             CheckTpls[] = {
                        EFI_TPL_CALLBACK,
                        EFI_TPL_NOTIFY,
                        EFI_TPL_HIGH_LEVEL,
                        0
                      };
  EFI_TEST_ASSERTION  AssertionType;
  EFI_EVENT           Event;
  UINTN               EventIndex;

  //
  // Create an event
  //
  Status = gtBS->CreateEvent (
                   EFI_EVENT_NOTIFY_WAIT,
                   EFI_TPL_NOTIFY,
                   NotifyFunction,
                   NULL,
                   &Event
                   );
  if (EFI_ERROR (Status)) {
    EFI_TEST_GENERIC_FAILURE (L"BS.WaitForEvent - Create event", Status);
    return Status;
  }

  //
  // Wait for event at invalid TPLs
  //
  for (Index = 0; CheckTpls[Index] != 0; Index++) {
    OldTpl = gtBS->RaiseTPL (CheckTpls[Index]);
    Status = gtBS->WaitForEvent (1, &Event, &EventIndex);
    gtBS->RestoreTPL (OldTpl);

    if (Status == EFI_UNSUPPORTED) {
      AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
      AssertionType = EFI_TEST_ASSERTION_FAILED;
    }

    StandardLib->RecordAssertion (
                   StandardLib,
                   AssertionType,
                   gEventTimerTaskPriorityServicesBBTestWaitForEventAssertionGuid004,
                   L"BS.WaitForEvent - Invoke WaitForEvent from invalid TPL.",
                   L"%a:%d:Status - %r, TPL - %d",
                   __FILE__,
                   (UINTN)__LINE__,
                   Status,
                   CheckTpls[Index]
                   );
  }

  //
  // Close the event
  //
  gtBS->CloseEvent (Event);

  //
  // Done
  //
  return EFI_SUCCESS;
}