1 /** @file
2   Support routines for memory profile for Smm phase drivers.
3 
4   Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include <PiSmm.h>
10 
11 #include <Library/UefiBootServicesTableLib.h>
12 #include <Library/SmmServicesTableLib.h>
13 #include <Library/DebugLib.h>
14 
15 #include <Guid/MemoryProfile.h>
16 
17 EDKII_MEMORY_PROFILE_PROTOCOL     *mLibProfileProtocol;
18 EDKII_SMM_MEMORY_PROFILE_PROTOCOL *mLibSmmProfileProtocol;
19 
20 /**
21   Check whether the start address of buffer is within any of the SMRAM ranges.
22 
23   @param[in]  Buffer   The pointer to the buffer to be checked.
24 
25   @retval     TRUE     The buffer is in SMRAM ranges.
26   @retval     FALSE    The buffer is out of SMRAM ranges.
27 **/
28 BOOLEAN
29 EFIAPI
30 BufferInSmram (
31   IN VOID *Buffer
32   );
33 
34 /**
35   The constructor function initializes memory profile for SMM phase.
36 
37   @param ImageHandle    The firmware allocated handle for the EFI image.
38   @param SystemTable    A pointer to the EFI System Table.
39 
40   @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
41 
42 **/
43 EFI_STATUS
44 EFIAPI
SmmMemoryProfileLibConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)45 SmmMemoryProfileLibConstructor (
46   IN EFI_HANDLE        ImageHandle,
47   IN EFI_SYSTEM_TABLE  *SystemTable
48   )
49 {
50   EFI_STATUS                Status;
51 
52   //
53   // Locate Profile Protocol
54   //
55   Status = gBS->LocateProtocol (
56                   &gEdkiiMemoryProfileGuid,
57                   NULL,
58                   (VOID **)&mLibProfileProtocol
59                   );
60   if (EFI_ERROR (Status)) {
61     mLibProfileProtocol = NULL;
62   }
63 
64   Status = gSmst->SmmLocateProtocol (
65                     &gEdkiiSmmMemoryProfileGuid,
66                     NULL,
67                     (VOID **)&mLibSmmProfileProtocol
68                     );
69   if (EFI_ERROR (Status)) {
70     mLibSmmProfileProtocol = NULL;
71   }
72 
73   return EFI_SUCCESS;
74 }
75 
76 /**
77   Record memory profile of multilevel caller.
78 
79   @param[in] CallerAddress      Address of caller.
80   @param[in] Action             Memory profile action.
81   @param[in] MemoryType         Memory type.
82                                 EfiMaxMemoryType means the MemoryType is unknown.
83   @param[in] Buffer             Buffer address.
84   @param[in] Size               Buffer size.
85   @param[in] ActionString       String for memory profile action.
86                                 Only needed for user defined allocate action.
87 
88   @return EFI_SUCCESS           Memory profile is updated.
89   @return EFI_UNSUPPORTED       Memory profile is unsupported,
90                                 or memory profile for the image is not required,
91                                 or memory profile for the memory type is not required.
92   @return EFI_ACCESS_DENIED     It is during memory profile data getting.
93   @return EFI_ABORTED           Memory profile recording is not enabled.
94   @return EFI_OUT_OF_RESOURCES  No enough resource to update memory profile for allocate action.
95   @return EFI_NOT_FOUND         No matched allocate info found for free action.
96 
97 **/
98 EFI_STATUS
99 EFIAPI
MemoryProfileLibRecord(IN PHYSICAL_ADDRESS CallerAddress,IN MEMORY_PROFILE_ACTION Action,IN EFI_MEMORY_TYPE MemoryType,IN VOID * Buffer,IN UINTN Size,IN CHAR8 * ActionString OPTIONAL)100 MemoryProfileLibRecord (
101   IN PHYSICAL_ADDRESS           CallerAddress,
102   IN MEMORY_PROFILE_ACTION      Action,
103   IN EFI_MEMORY_TYPE            MemoryType,
104   IN VOID                       *Buffer,
105   IN UINTN                      Size,
106   IN CHAR8                      *ActionString OPTIONAL
107   )
108 {
109   if (BufferInSmram (Buffer)) {
110     if (mLibSmmProfileProtocol == NULL) {
111       return EFI_UNSUPPORTED;
112     }
113     return mLibSmmProfileProtocol->Record (
114                                      mLibSmmProfileProtocol,
115                                      CallerAddress,
116                                      Action,
117                                      MemoryType,
118                                      Buffer,
119                                      Size,
120                                      ActionString
121                                      );
122   } else {
123     if (mLibProfileProtocol == NULL) {
124       return EFI_UNSUPPORTED;
125     }
126     return mLibProfileProtocol->Record (
127                                   mLibProfileProtocol,
128                                   CallerAddress,
129                                   Action,
130                                   MemoryType,
131                                   Buffer,
132                                   Size,
133                                   ActionString
134                                   );
135   }
136 }
137 
138