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