1 /** @file
2   UEFI Dxe DebugLib constructor that prevent some debug service after ExitBootServices event,
3   because some pointer is nulled at that phase.
4 
5   Copyright (c) 2018, Microsoft Corporation
6   Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
7 
8   SPDX-License-Identifier: BSD-2-Clause-Patent
9 **/
10 
11 #include <Uefi.h>
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 
15 //
16 // BOOLEAN value to indicate if it is at the post ExitBootServices pahse
17 //
18 BOOLEAN     mPostEBS = FALSE;
19 
20 static EFI_EVENT   mExitBootServicesEvent;
21 
22 //
23 // Pointer to SystemTable
24 // This library instance may have a cycle consume with UefiBootServicesTableLib
25 // because of the constructors.
26 //
27 EFI_BOOT_SERVICES     *mDebugBS;
28 
29 /**
30   This routine sets the mPostEBS for exit boot servies true
31   to prevent DebugPort protocol dereferences when the pointer is nulled.
32 
33   @param  Event        Event whose notification function is being invoked.
34   @param  Context      Pointer to the notification function's context.
35 
36 **/
37 VOID
38 EFIAPI
ExitBootServicesCallback(EFI_EVENT Event,VOID * Context)39 ExitBootServicesCallback (
40   EFI_EVENT   Event,
41   VOID*       Context
42   )
43 {
44   mPostEBS = TRUE;
45   return;
46 }
47 
48 /**
49   The constructor gets the pointers to boot services table.
50   And create a event to indicate it is after ExitBootServices.
51 
52   @param  ImageHandle     The firmware allocated handle for the EFI image.
53   @param  SystemTable     A pointer to the EFI System Table.
54 
55   @retval EFI_SUCCESS     The constructor always returns EFI_SUCCESS.
56 
57 **/
58 EFI_STATUS
59 EFIAPI
DxeDebugLibConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)60 DxeDebugLibConstructor(
61   IN EFI_HANDLE                 ImageHandle,
62   IN EFI_SYSTEM_TABLE           *SystemTable
63   )
64 {
65   mDebugBS = SystemTable->BootServices;
66 
67   mDebugBS->CreateEvent (
68               EVT_SIGNAL_EXIT_BOOT_SERVICES,
69               TPL_NOTIFY,
70               ExitBootServicesCallback,
71               NULL,
72               &mExitBootServicesEvent
73               );
74 
75   return EFI_SUCCESS;
76 }
77 
78 /**
79   The destructor closes Exit Boot Services Event.
80 
81   @param  ImageHandle   The firmware allocated handle for the EFI image.
82   @param  SystemTable   A pointer to the EFI System Table.
83 
84   @retval EFI_SUCCESS   The destructor always returns EFI_SUCCESS.
85 
86 **/
87 EFI_STATUS
88 EFIAPI
DxeDebugLibDestructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)89 DxeDebugLibDestructor(
90   IN EFI_HANDLE                 ImageHandle,
91   IN EFI_SYSTEM_TABLE           *SystemTable
92   )
93 {
94   if (mExitBootServicesEvent != NULL) {
95     SystemTable->BootServices->CloseEvent (mExitBootServicesEvent);
96   }
97 
98   return EFI_SUCCESS;
99 }
100