]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/MemTypeInfo.c
863c6f382680d30a3e43b59aff5158710460c0a2
[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 { EfiBootServicesCode, 0x180 },
35 { EfiBootServicesData, 0xF00 },
36 { EfiMaxMemoryType, 0x000 }
37 };
38
39 STATIC
40 VOID
41 BuildMemTypeInfoHob (
42 VOID
43 )
44 {
45 BuildGuidDataHob (
46 &gEfiMemoryTypeInformationGuid,
47 mDefaultMemoryTypeInformation,
48 sizeof mDefaultMemoryTypeInformation
49 );
50 DEBUG ((DEBUG_INFO, "%a: default memory type information HOB built\n",
51 __FUNCTION__));
52 }
53
54 /**
55 Notification function called when EFI_PEI_READ_ONLY_VARIABLE2_PPI becomes
56 available.
57
58 @param[in] PeiServices Indirect reference to the PEI Services Table.
59 @param[in] NotifyDescriptor Address of the notification descriptor data
60 structure.
61 @param[in] Ppi Address of the PPI that was installed.
62
63 @return Status of the notification. The status code returned from this
64 function is ignored.
65 **/
66 STATIC
67 EFI_STATUS
68 EFIAPI
69 OnReadOnlyVariable2Available (
70 IN EFI_PEI_SERVICES **PeiServices,
71 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
72 IN VOID *Ppi
73 )
74 {
75 EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
76 UINTN DataSize;
77 EFI_STATUS Status;
78
79 DEBUG ((DEBUG_VERBOSE, "%a\n", __FUNCTION__));
80
81 //
82 // Check if the "MemoryTypeInformation" variable exists, in the
83 // gEfiMemoryTypeInformationGuid namespace.
84 //
85 ReadOnlyVariable2 = Ppi;
86 DataSize = 0;
87 Status = ReadOnlyVariable2->GetVariable (
88 ReadOnlyVariable2,
89 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
90 &gEfiMemoryTypeInformationGuid,
91 NULL,
92 &DataSize,
93 NULL
94 );
95 switch (Status) {
96 case EFI_BUFFER_TOO_SMALL:
97 //
98 // The variable exists; the DXE IPL PEIM will build the HOB from it.
99 //
100 break;
101 case EFI_NOT_FOUND:
102 //
103 // The variable does not exist; install the default memory type information
104 // HOB.
105 //
106 BuildMemTypeInfoHob ();
107 break;
108 default:
109 DEBUG ((DEBUG_ERROR, "%a: unexpected: GetVariable(): %r\n", __FUNCTION__,
110 Status));
111 ASSERT (FALSE);
112 CpuDeadLoop ();
113 break;
114 }
115
116 return EFI_SUCCESS;
117 }
118
119 //
120 // Notification object for registering the callback, for when
121 // EFI_PEI_READ_ONLY_VARIABLE2_PPI becomes available.
122 //
123 STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mReadOnlyVariable2Notify = {
124 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH |
125 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), // Flags
126 &gEfiPeiReadOnlyVariable2PpiGuid, // Guid
127 OnReadOnlyVariable2Available // Notify
128 };
129
130 VOID
131 MemTypeInfoInitialization (
132 VOID
133 )
134 {
135 EFI_STATUS Status;
136
137 if (!FeaturePcdGet (PcdSmmSmramRequire)) {
138 //
139 // EFI_PEI_READ_ONLY_VARIABLE2_PPI will never be available; install
140 // the default memory type information HOB right away.
141 //
142 BuildMemTypeInfoHob ();
143 return;
144 }
145
146 Status = PeiServicesNotifyPpi (&mReadOnlyVariable2Notify);
147 if (EFI_ERROR (Status)) {
148 DEBUG ((DEBUG_ERROR, "%a: failed to set up R/O Variable 2 callback: %r\n",
149 __FUNCTION__, Status));
150 ASSERT (FALSE);
151 CpuDeadLoop ();
152 }
153 }