]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/MemTypeInfo.c
8100a2db7d44d6b62f0ed319bdb66c554c4f069a
[mirror_edk2.git] / OvmfPkg / PlatformPei / MemTypeInfo.c
1 /** @file
2 Produce a default memory type information HOB unless we can determine, from
3 the existence of the "MemoryTypeInformation" variable, that the DXE IPL PEIM
4 will produce the HOB.
5
6 Copyright (C) 2017-2020, Red Hat, Inc.
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9 **/
10
11 #include <Guid/MemoryTypeInformation.h>
12 #include <Library/BaseLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/HobLib.h>
15 #include <Library/PcdLib.h>
16 #include <Library/PeiServicesLib.h>
17 #include <Ppi/ReadOnlyVariable2.h>
18 #include <Uefi/UefiMultiPhase.h>
19
20 #include "Platform.h"
21
22 //
23 // The NumberOfPages values below are ad-hoc. They are updated sporadically at
24 // best (please refer to git-blame for past updates). The values capture a set
25 // of BIN hints that made sense at a particular time, for some (now likely
26 // unknown) workloads / boot paths.
27 //
28 STATIC EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
29 { EfiACPIMemoryNVS, 0x004 },
30 { EfiACPIReclaimMemory, 0x008 },
31 { EfiReservedMemoryType, 0x004 },
32 { EfiRuntimeServicesData, 0x024 },
33 { EfiRuntimeServicesCode, 0x030 },
34 { EfiMaxMemoryType, 0x000 }
35 };
36
37 STATIC
38 VOID
39 BuildMemTypeInfoHob (
40 VOID
41 )
42 {
43 BuildGuidDataHob (
44 &gEfiMemoryTypeInformationGuid,
45 mDefaultMemoryTypeInformation,
46 sizeof mDefaultMemoryTypeInformation
47 );
48 DEBUG ((DEBUG_INFO, "%a: default memory type information HOB built\n",
49 __FUNCTION__));
50 }
51
52 /**
53 Notification function called when EFI_PEI_READ_ONLY_VARIABLE2_PPI becomes
54 available.
55
56 @param[in] PeiServices Indirect reference to the PEI Services Table.
57 @param[in] NotifyDescriptor Address of the notification descriptor data
58 structure.
59 @param[in] Ppi Address of the PPI that was installed.
60
61 @return Status of the notification. The status code returned from this
62 function is ignored.
63 **/
64 STATIC
65 EFI_STATUS
66 EFIAPI
67 OnReadOnlyVariable2Available (
68 IN EFI_PEI_SERVICES **PeiServices,
69 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
70 IN VOID *Ppi
71 )
72 {
73 EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
74 UINTN DataSize;
75 EFI_STATUS Status;
76
77 DEBUG ((DEBUG_VERBOSE, "%a\n", __FUNCTION__));
78
79 //
80 // Check if the "MemoryTypeInformation" variable exists, in the
81 // gEfiMemoryTypeInformationGuid namespace.
82 //
83 ReadOnlyVariable2 = Ppi;
84 DataSize = 0;
85 Status = ReadOnlyVariable2->GetVariable (
86 ReadOnlyVariable2,
87 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
88 &gEfiMemoryTypeInformationGuid,
89 NULL,
90 &DataSize,
91 NULL
92 );
93 switch (Status) {
94 case EFI_BUFFER_TOO_SMALL:
95 //
96 // The variable exists; the DXE IPL PEIM will build the HOB from it.
97 //
98 break;
99 case EFI_NOT_FOUND:
100 //
101 // The variable does not exist; install the default memory type information
102 // HOB.
103 //
104 BuildMemTypeInfoHob ();
105 break;
106 default:
107 DEBUG ((DEBUG_ERROR, "%a: unexpected: GetVariable(): %r\n", __FUNCTION__,
108 Status));
109 ASSERT (FALSE);
110 CpuDeadLoop ();
111 break;
112 }
113
114 return EFI_SUCCESS;
115 }
116
117 //
118 // Notification object for registering the callback, for when
119 // EFI_PEI_READ_ONLY_VARIABLE2_PPI becomes available.
120 //
121 STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mReadOnlyVariable2Notify = {
122 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH |
123 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), // Flags
124 &gEfiPeiReadOnlyVariable2PpiGuid, // Guid
125 OnReadOnlyVariable2Available // Notify
126 };
127
128 VOID
129 MemTypeInfoInitialization (
130 VOID
131 )
132 {
133 EFI_STATUS Status;
134
135 if (!FeaturePcdGet (PcdSmmSmramRequire)) {
136 //
137 // EFI_PEI_READ_ONLY_VARIABLE2_PPI will never be available; install
138 // the default memory type information HOB right away.
139 //
140 BuildMemTypeInfoHob ();
141 return;
142 }
143
144 Status = PeiServicesNotifyPpi (&mReadOnlyVariable2Notify);
145 if (EFI_ERROR (Status)) {
146 DEBUG ((DEBUG_ERROR, "%a: failed to set up R/O Variable 2 callback: %r\n",
147 __FUNCTION__, Status));
148 ASSERT (FALSE);
149 CpuDeadLoop ();
150 }
151 }