1 /** @file
2   Memory profile data structure.
3 
4   Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #ifndef _MEMORY_PROFILE_H_
10 #define _MEMORY_PROFILE_H_
11 
12 #include <Pi/PiFirmwareFile.h>
13 
14 //
15 // For BIOS MemoryType (0 ~ EfiMaxMemoryType - 1), it is recorded in UsageByType[MemoryType]. (Each valid entry has one entry)
16 // For OS MemoryType (0x80000000 ~ 0xFFFFFFFF), it is recorded in UsageByType[EfiMaxMemoryType]. (All types are combined into one entry)
17 // For OEM MemoryType (0x70000000 ~ 0x7FFFFFFF), it is recorded in UsageByType[EfiMaxMemoryType + 1]. (All types are combined into one entry)
18 //
19 
20 typedef struct {
21   UINT32                       Signature;
22   UINT16                       Length;
23   UINT16                       Revision;
24 } MEMORY_PROFILE_COMMON_HEADER;
25 
26 #define MEMORY_PROFILE_CONTEXT_SIGNATURE SIGNATURE_32 ('M','P','C','T')
27 #define MEMORY_PROFILE_CONTEXT_REVISION 0x0002
28 
29 typedef struct {
30   MEMORY_PROFILE_COMMON_HEADER  Header;
31   UINT64                        CurrentTotalUsage;
32   UINT64                        PeakTotalUsage;
33   UINT64                        CurrentTotalUsageByType[EfiMaxMemoryType + 2];
34   UINT64                        PeakTotalUsageByType[EfiMaxMemoryType + 2];
35   UINT64                        TotalImageSize;
36   UINT32                        ImageCount;
37   UINT32                        SequenceCount;
38 } MEMORY_PROFILE_CONTEXT;
39 
40 #define MEMORY_PROFILE_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('M','P','D','I')
41 #define MEMORY_PROFILE_DRIVER_INFO_REVISION 0x0003
42 
43 typedef struct {
44   MEMORY_PROFILE_COMMON_HEADER  Header;
45   EFI_GUID                      FileName;
46   PHYSICAL_ADDRESS              ImageBase;
47   UINT64                        ImageSize;
48   PHYSICAL_ADDRESS              EntryPoint;
49   UINT16                        ImageSubsystem;
50   EFI_FV_FILETYPE               FileType;
51   UINT8                         Reserved[1];
52   UINT32                        AllocRecordCount;
53   UINT64                        CurrentUsage;
54   UINT64                        PeakUsage;
55   UINT64                        CurrentUsageByType[EfiMaxMemoryType + 2];
56   UINT64                        PeakUsageByType[EfiMaxMemoryType + 2];
57   UINT16                        PdbStringOffset;
58   UINT8                         Reserved2[6];
59 //CHAR8                         PdbString[];
60 } MEMORY_PROFILE_DRIVER_INFO;
61 
62 typedef enum {
63   MemoryProfileActionAllocatePages = 1,
64   MemoryProfileActionFreePages = 2,
65   MemoryProfileActionAllocatePool = 3,
66   MemoryProfileActionFreePool = 4,
67 } MEMORY_PROFILE_ACTION;
68 
69 //
70 // Below is the detailed MEMORY_PROFILE_ACTION definition.
71 //
72 //  31       15      9  8  8 7  7 6   6 5-4  3 - 0
73 // +----------------------------------------------+
74 // |User |  |Lib|   |Re|Copy|Zero|Align|Type|Basic|
75 // +----------------------------------------------+
76 //
77 
78 //
79 // Basic Action
80 //      1 : AllocatePages
81 //      2 : FreePages
82 //      3 : AllocatePool
83 //      4 : FreePool
84 //
85 #define MEMORY_PROFILE_ACTION_BASIC_MASK 0xF
86 
87 //
88 // Extension
89 //
90 #define MEMORY_PROFILE_ACTION_EXTENSION_MASK               0xFFF0
91 #define MEMORY_PROFILE_ACTION_EXTENSION_LIB_MASK           0x8000
92 #define MEMORY_PROFILE_ACTION_EXTENSION_REALLOC_MASK       0x0200
93 #define MEMORY_PROFILE_ACTION_EXTENSION_COPY_MASK          0x0100
94 #define MEMORY_PROFILE_ACTION_EXTENSION_ZERO_MASK          0x0080
95 #define MEMORY_PROFILE_ACTION_EXTENSION_ALIGN_MASK         0x0040
96 #define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_MASK      0x0030
97 #define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_BASIC     0x0000
98 #define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_RUNTIME   0x0010
99 #define MEMORY_PROFILE_ACTION_EXTENSION_MEM_TYPE_RESERVED  0x0020
100 
101 //
102 // Extension (used by memory allocation lib)
103 //
104 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES                    0x8001
105 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES            0x8011
106 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES           0x8021
107 #define MEMORY_PROFILE_ACTION_LIB_FREE_PAGES                        0x8002
108 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES            0x8041
109 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES    0x8051
110 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES   0x8061
111 #define MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES                0x8042
112 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL                     0x8003
113 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL             0x8013
114 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL            0x8023
115 #define MEMORY_PROFILE_ACTION_LIB_FREE_POOL                         0x8004
116 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL                0x8083
117 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL        0x8093
118 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL       0x80a3
119 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL                0x8103
120 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL        0x8113
121 #define MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL       0x8123
122 #define MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL                   0x8203
123 #define MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL           0x8213
124 #define MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL          0x8223
125 
126 //
127 // User defined: 0x80000000~0xFFFFFFFF
128 //
129 // NOTE: User defined action MUST OR the basic action,
130 //       so that core can know the action is allocate or free,
131 //       and the type is pages (can be freed partially)
132 //       or pool (cannot be freed partially).
133 //
134 #define MEMORY_PROFILE_ACTION_USER_DEFINED_MASK           0x80000000
135 
136 #define MEMORY_PROFILE_ALLOC_INFO_SIGNATURE SIGNATURE_32 ('M','P','A','I')
137 #define MEMORY_PROFILE_ALLOC_INFO_REVISION 0x0002
138 
139 typedef struct {
140   MEMORY_PROFILE_COMMON_HEADER  Header;
141   PHYSICAL_ADDRESS              CallerAddress;
142   UINT32                        SequenceId;
143   UINT8                         Reserved[2];
144   UINT16                        ActionStringOffset;
145   MEMORY_PROFILE_ACTION         Action;
146   EFI_MEMORY_TYPE               MemoryType;
147   PHYSICAL_ADDRESS              Buffer;
148   UINT64                        Size;
149 //CHAR8                         ActionString[];
150 } MEMORY_PROFILE_ALLOC_INFO;
151 
152 #define MEMORY_PROFILE_DESCRIPTOR_SIGNATURE SIGNATURE_32 ('M','P','D','R')
153 #define MEMORY_PROFILE_DESCRIPTOR_REVISION 0x0001
154 
155 typedef struct {
156   MEMORY_PROFILE_COMMON_HEADER  Header;
157   PHYSICAL_ADDRESS              Address;
158   UINT64                        Size;
159 } MEMORY_PROFILE_DESCRIPTOR;
160 
161 #define MEMORY_PROFILE_FREE_MEMORY_SIGNATURE SIGNATURE_32 ('M','P','R','M')
162 #define MEMORY_PROFILE_FREE_MEMORY_REVISION 0x0001
163 
164 typedef struct {
165   MEMORY_PROFILE_COMMON_HEADER  Header;
166   UINT64                        TotalFreeMemoryPages;
167   UINT32                        FreeMemoryEntryCount;
168   UINT8                         Reserved[4];
169   //MEMORY_PROFILE_DESCRIPTOR     MemoryDescriptor[FreeMemoryEntryCount];
170 } MEMORY_PROFILE_FREE_MEMORY;
171 
172 #define MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE SIGNATURE_32 ('M','P','M','R')
173 #define MEMORY_PROFILE_MEMORY_RANGE_REVISION 0x0001
174 
175 typedef struct {
176   MEMORY_PROFILE_COMMON_HEADER  Header;
177   UINT32                        MemoryRangeCount;
178   UINT8                         Reserved[4];
179   //MEMORY_PROFILE_DESCRIPTOR     MemoryDescriptor[MemoryRangeCount];
180 } MEMORY_PROFILE_MEMORY_RANGE;
181 
182 //
183 // UEFI memory profile layout:
184 // +--------------------------------+
185 // | CONTEXT                        |
186 // +--------------------------------+
187 // | DRIVER_INFO(1)                 |
188 // +--------------------------------+
189 // | ALLOC_INFO(1, 1)               |
190 // +--------------------------------+
191 // | ALLOC_INFO(1, m1)              |
192 // +--------------------------------+
193 // | DRIVER_INFO(n)                 |
194 // +--------------------------------+
195 // | ALLOC_INFO(n, 1)               |
196 // +--------------------------------+
197 // | ALLOC_INFO(n, mn)              |
198 // +--------------------------------+
199 //
200 
201 typedef struct _EDKII_MEMORY_PROFILE_PROTOCOL EDKII_MEMORY_PROFILE_PROTOCOL;
202 
203 /**
204   Get memory profile data.
205 
206   @param[in]      This              The EDKII_MEMORY_PROFILE_PROTOCOL instance.
207   @param[in, out] ProfileSize       On entry, points to the size in bytes of the ProfileBuffer.
208                                     On return, points to the size of the data returned in ProfileBuffer.
209   @param[out]     ProfileBuffer     Profile buffer.
210 
211   @return EFI_SUCCESS               Get the memory profile data successfully.
212   @return EFI_UNSUPPORTED           Memory profile is unsupported.
213   @return EFI_BUFFER_TO_SMALL       The ProfileSize is too small for the resulting data.
214                                     ProfileSize is updated with the size required.
215 
216 **/
217 typedef
218 EFI_STATUS
219 (EFIAPI *EDKII_MEMORY_PROFILE_GET_DATA)(
220   IN     EDKII_MEMORY_PROFILE_PROTOCOL  *This,
221   IN OUT UINT64                         *ProfileSize,
222      OUT VOID                           *ProfileBuffer
223   );
224 
225 /**
226   Register image to memory profile.
227 
228   @param[in] This               The EDKII_MEMORY_PROFILE_PROTOCOL instance.
229   @param[in] FilePath           File path of the image.
230   @param[in] ImageBase          Image base address.
231   @param[in] ImageSize          Image size.
232   @param[in] FileType           File type of the image.
233 
234   @return EFI_SUCCESS           Register successfully.
235   @return EFI_UNSUPPORTED       Memory profile is unsupported,
236                                 or memory profile for the image is not required.
237   @return EFI_OUT_OF_RESOURCES  No enough resource for this register.
238 
239 **/
240 typedef
241 EFI_STATUS
242 (EFIAPI *EDKII_MEMORY_PROFILE_REGISTER_IMAGE)(
243   IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
244   IN EFI_DEVICE_PATH_PROTOCOL           *FilePath,
245   IN PHYSICAL_ADDRESS                   ImageBase,
246   IN UINT64                             ImageSize,
247   IN EFI_FV_FILETYPE                    FileType
248   );
249 
250 /**
251   Unregister image from memory profile.
252 
253   @param[in] This               The EDKII_MEMORY_PROFILE_PROTOCOL instance.
254   @param[in] FilePath           File path of the image.
255   @param[in] ImageBase          Image base address.
256   @param[in] ImageSize          Image size.
257 
258   @return EFI_SUCCESS           Unregister successfully.
259   @return EFI_UNSUPPORTED       Memory profile is unsupported,
260                                 or memory profile for the image is not required.
261   @return EFI_NOT_FOUND         The image is not found.
262 
263 **/
264 typedef
265 EFI_STATUS
266 (EFIAPI *EDKII_MEMORY_PROFILE_UNREGISTER_IMAGE)(
267   IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
268   IN EFI_DEVICE_PATH_PROTOCOL           *FilePath,
269   IN PHYSICAL_ADDRESS                   ImageBase,
270   IN UINT64                             ImageSize
271   );
272 
273 #define MEMORY_PROFILE_RECORDING_ENABLE     TRUE
274 #define MEMORY_PROFILE_RECORDING_DISABLE    FALSE
275 
276 /**
277   Get memory profile recording state.
278 
279   @param[in]  This              The EDKII_MEMORY_PROFILE_PROTOCOL instance.
280   @param[out] RecordingState    Recording state.
281 
282   @return EFI_SUCCESS           Memory profile recording state is returned.
283   @return EFI_UNSUPPORTED       Memory profile is unsupported.
284   @return EFI_INVALID_PARAMETER RecordingState is NULL.
285 
286 **/
287 typedef
288 EFI_STATUS
289 (EFIAPI *EDKII_MEMORY_PROFILE_GET_RECORDING_STATE) (
290   IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
291   OUT BOOLEAN                           *RecordingState
292   );
293 
294 /**
295   Set memory profile recording state.
296 
297   @param[in] This               The EDKII_MEMORY_PROFILE_PROTOCOL instance.
298   @param[in] RecordingState     Recording state.
299 
300   @return EFI_SUCCESS           Set memory profile recording state successfully.
301   @return EFI_UNSUPPORTED       Memory profile is unsupported.
302 
303 **/
304 typedef
305 EFI_STATUS
306 (EFIAPI *EDKII_MEMORY_PROFILE_SET_RECORDING_STATE) (
307   IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
308   IN BOOLEAN                            RecordingState
309   );
310 
311 /**
312   Record memory profile of multilevel caller.
313 
314   @param[in] This               The EDKII_MEMORY_PROFILE_PROTOCOL instance.
315   @param[in] CallerAddress      Address of caller.
316   @param[in] Action             Memory profile action.
317   @param[in] MemoryType         Memory type.
318                                 EfiMaxMemoryType means the MemoryType is unknown.
319   @param[in] Buffer             Buffer address.
320   @param[in] Size               Buffer size.
321   @param[in] ActionString       String for memory profile action.
322                                 Only needed for user defined allocate action.
323 
324   @return EFI_SUCCESS           Memory profile is updated.
325   @return EFI_UNSUPPORTED       Memory profile is unsupported,
326                                 or memory profile for the image is not required,
327                                 or memory profile for the memory type is not required.
328   @return EFI_ACCESS_DENIED     It is during memory profile data getting.
329   @return EFI_ABORTED           Memory profile recording is not enabled.
330   @return EFI_OUT_OF_RESOURCES  No enough resource to update memory profile for allocate action.
331   @return EFI_NOT_FOUND         No matched allocate info found for free action.
332 
333 **/
334 typedef
335 EFI_STATUS
336 (EFIAPI *EDKII_MEMORY_PROFILE_RECORD) (
337   IN EDKII_MEMORY_PROFILE_PROTOCOL      *This,
338   IN PHYSICAL_ADDRESS                   CallerAddress,
339   IN MEMORY_PROFILE_ACTION              Action,
340   IN EFI_MEMORY_TYPE                    MemoryType,
341   IN VOID                               *Buffer,
342   IN UINTN                              Size,
343   IN CHAR8                              *ActionString OPTIONAL
344   );
345 
346 struct _EDKII_MEMORY_PROFILE_PROTOCOL {
347   EDKII_MEMORY_PROFILE_GET_DATA             GetData;
348   EDKII_MEMORY_PROFILE_REGISTER_IMAGE       RegisterImage;
349   EDKII_MEMORY_PROFILE_UNREGISTER_IMAGE     UnregisterImage;
350   EDKII_MEMORY_PROFILE_GET_RECORDING_STATE  GetRecordingState;
351   EDKII_MEMORY_PROFILE_SET_RECORDING_STATE  SetRecordingState;
352   EDKII_MEMORY_PROFILE_RECORD               Record;
353 };
354 
355 //
356 // SMRAM profile layout:
357 // +--------------------------------+
358 // | CONTEXT                        |
359 // +--------------------------------+
360 // | DRIVER_INFO(1)                 |
361 // +--------------------------------+
362 // | ALLOC_INFO(1, 1)               |
363 // +--------------------------------+
364 // | ALLOC_INFO(1, m1)              |
365 // +--------------------------------+
366 // | DRIVER_INFO(n)                 |
367 // +--------------------------------+
368 // | ALLOC_INFO(n, 1)               |
369 // +--------------------------------+
370 // | ALLOC_INFO(n, mn)              |
371 // +--------------------------------+
372 // | FREE_MEMORY                    |
373 // +--------------------------------+
374 // | FREE MEMORY DESCRIPTOR(1)      |
375 // +--------------------------------+
376 // | FREE MEMORY DESCRIPTOR(p)      |
377 // +--------------------------------+
378 // | MEMORY_RANGE                   |
379 // +--------------------------------+
380 // | MEMORY RANGE DESCRIPTOR(1)     |
381 // +--------------------------------+
382 // | MEMORY RANGE DESCRIPTOR(q)     |
383 // +--------------------------------+
384 //
385 
386 //
387 // SMRAM profile command
388 //
389 #define SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO           0x1
390 #define SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA           0x2
391 //
392 // Below 2 commands are now used by ECP only and only valid before SmmReadyToLock
393 //
394 #define SMRAM_PROFILE_COMMAND_REGISTER_IMAGE             0x3
395 #define SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE           0x4
396 
397 #define SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET 0x5
398 #define SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE        0x6
399 #define SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE        0x7
400 
401 typedef struct {
402   UINT32                            Command;
403   UINT32                            DataLength;
404   UINT64                            ReturnStatus;
405 } SMRAM_PROFILE_PARAMETER_HEADER;
406 
407 typedef struct {
408   SMRAM_PROFILE_PARAMETER_HEADER    Header;
409   UINT64                            ProfileSize;
410 } SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO;
411 
412 typedef struct {
413   SMRAM_PROFILE_PARAMETER_HEADER    Header;
414   UINT64                            ProfileSize;
415   PHYSICAL_ADDRESS                  ProfileBuffer;
416 } SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA;
417 
418 typedef struct {
419   SMRAM_PROFILE_PARAMETER_HEADER    Header;
420   //
421   // On input, profile buffer size.
422   // On output, actual profile data size copied.
423   //
424   UINT64                            ProfileSize;
425   PHYSICAL_ADDRESS                  ProfileBuffer;
426   //
427   // On input, profile buffer offset to copy.
428   // On output, next time profile buffer offset to copy.
429   //
430   UINT64                            ProfileOffset;
431 } SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET;
432 
433 typedef struct {
434   SMRAM_PROFILE_PARAMETER_HEADER    Header;
435   BOOLEAN                           RecordingState;
436 } SMRAM_PROFILE_PARAMETER_RECORDING_STATE;
437 
438 typedef struct {
439   SMRAM_PROFILE_PARAMETER_HEADER    Header;
440   EFI_GUID                          FileName;
441   PHYSICAL_ADDRESS                  ImageBuffer;
442   UINT64                            NumberOfPage;
443 } SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE;
444 
445 typedef struct {
446   SMRAM_PROFILE_PARAMETER_HEADER    Header;
447   EFI_GUID                          FileName;
448   PHYSICAL_ADDRESS                  ImageBuffer;
449   UINT64                            NumberOfPage;
450 } SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE;
451 
452 
453 #define EDKII_MEMORY_PROFILE_GUID { \
454   0x821c9a09, 0x541a, 0x40f6, { 0x9f, 0x43, 0xa, 0xd1, 0x93, 0xa1, 0x2c, 0xfe } \
455 }
456 
457 extern EFI_GUID gEdkiiMemoryProfileGuid;
458 
459 typedef EDKII_MEMORY_PROFILE_PROTOCOL EDKII_SMM_MEMORY_PROFILE_PROTOCOL;
460 
461 #define EDKII_SMM_MEMORY_PROFILE_GUID { \
462   0xe22bbcca, 0x516a, 0x46a8, { 0x80, 0xe2, 0x67, 0x45, 0xe8, 0x36, 0x93, 0xbd } \
463 }
464 
465 extern EFI_GUID gEdkiiSmmMemoryProfileGuid;
466 
467 #endif
468 
469