OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
LegacyNvramWrapper.c
Go to the documentation of this file.
1
8#include <Uefi.h>
13#include <Library/UefiBootServicesTableLib.h>
14
15STATIC
16EFI_STATUS
18 OC_VARIABLE_RUNTIME_PROTOCOL **OcVariableRuntimeProtocol
19 )
20{
21 EFI_STATUS Status;
22
23 ASSERT (OcVariableRuntimeProtocol != NULL);
24
25 Status = gBS->LocateProtocol (
27 NULL,
28 (VOID **)OcVariableRuntimeProtocol
29 );
30
31 if (EFI_ERROR (Status)) {
32 DEBUG ((DEBUG_INFO, "OCVAR: Locate emulated NVRAM protocol - %r\n", Status));
33 return Status;
34 }
35
36 if ((*OcVariableRuntimeProtocol)->Revision != OC_VARIABLE_RUNTIME_PROTOCOL_REVISION) {
37 DEBUG ((
38 DEBUG_WARN,
39 "OCVAR: Emulated NVRAM protocol incompatible revision %d != %d\n",
40 (*OcVariableRuntimeProtocol)->Revision,
42 ));
43 return EFI_UNSUPPORTED;
44 }
45
46 return Status;
47}
48
49//
50// TODO: We should normally strictly avoid passing OpenCore config structures outside of OcMainLib, but the
51// emulated NVRAM protocol is so tightly tied to the legacy NVRAM map that we (currently?) do so.
52//
53VOID
55 IN OC_STORAGE_CONTEXT *Storage,
56 IN OC_NVRAM_LEGACY_MAP *LegacyMap,
57 IN BOOLEAN LegacyOverwrite,
58 IN BOOLEAN RequestBootVarRouting
59 )
60{
61 EFI_STATUS Status;
62 OC_VARIABLE_RUNTIME_PROTOCOL *OcVariableRuntimeProtocol;
64 OC_FWRT_CONFIG FwrtConfig;
65
66 Status = InternalLocateVariableRuntimeProtocol (&OcVariableRuntimeProtocol);
67 if (EFI_ERROR (Status)) {
68 return;
69 }
70
71 //
72 // It is not really required to support boot var routing with emulated NVRAM (since there are
73 // no firmware NVRAM boot vars used outside of OpenCore to avoid trashing), but having working
74 // support is more convenient when switching back and forth between emulated and non-emulated
75 // NVRAM, i.e. one less thing to have to remember to switch, since with this code everything
76 // works as expected with or without RequestBootVarRouting. (Without it, boot entries do not
77 // restore to the right place when RequestBootVarRouting is enabled.)
78 // OpenRuntime.efi must be loaded early, but after OpenVariableRuntimeDxe.efi, for this to work.
79 //
80 if (RequestBootVarRouting) {
81 Status = gBS->LocateProtocol (
83 NULL,
84 (VOID **)&FwRuntime
85 );
86
87 if (!EFI_ERROR (Status) && (FwRuntime->Revision == OC_FIRMWARE_RUNTIME_REVISION)) {
88 FwRuntime->GetCurrent (&FwrtConfig);
89 if (FwrtConfig.BootVariableRedirect) {
90 DEBUG ((DEBUG_INFO, "OCVAR: Found FW NVRAM, redirect already present %d\n", FwrtConfig.BootVariableRedirect));
91 FwRuntime = NULL;
92 } else {
93 FwrtConfig.BootVariableRedirect = TRUE;
94 FwRuntime->SetOverride (&FwrtConfig);
95 DEBUG ((DEBUG_INFO, "OCVAR: Found FW NVRAM, forcing redirect %d\n", FwrtConfig.BootVariableRedirect));
96 }
97 } else {
98 FwRuntime = NULL;
99 DEBUG ((DEBUG_INFO, "OCVAR: Missing FW NVRAM, going on...\n"));
100 }
101 } else {
102 FwRuntime = NULL;
103 }
104
105 DEBUG ((DEBUG_INFO, "OCVAR: Loading NVRAM from storage...\n"));
106
107 Status = OcVariableRuntimeProtocol->LoadNvram (Storage, LegacyMap, LegacyOverwrite);
108
109 if (EFI_ERROR (Status)) {
110 //
111 // Make this INFO rather then WARN, since it is expected on first boot with emulated NVRAM.
112 //
113 DEBUG ((DEBUG_INFO, "OCVAR: Emulated NVRAM load failed - %r\n", Status));
114 }
115
116 if (FwRuntime != NULL) {
117 DEBUG ((DEBUG_INFO, "OCVAR: Restoring FW NVRAM...\n"));
118 FwRuntime->SetOverride (NULL);
119 }
120}
121
122VOID
123EFIAPI
125 VOID
126 )
127{
128 EFI_STATUS Status;
129 OC_VARIABLE_RUNTIME_PROTOCOL *OcVariableRuntimeProtocol;
130
131 Status = InternalLocateVariableRuntimeProtocol (&OcVariableRuntimeProtocol);
132 if (EFI_ERROR (Status)) {
133 return;
134 }
135
136 DEBUG ((DEBUG_INFO, "OCVAR: Saving NVRAM to storage...\n"));
137
138 Status = OcVariableRuntimeProtocol->SaveNvram ();
139
140 if (EFI_ERROR (Status)) {
141 DEBUG ((DEBUG_WARN, "OCVAR: Emulated NVRAM save failed - %r\n", Status));
142 }
143}
144
145VOID
146EFIAPI
148 VOID
149 )
150{
151 EFI_STATUS Status;
152 OC_VARIABLE_RUNTIME_PROTOCOL *OcVariableRuntimeProtocol;
153
154 Status = InternalLocateVariableRuntimeProtocol (&OcVariableRuntimeProtocol);
155 if (EFI_ERROR (Status)) {
156 return;
157 }
158
159 DEBUG ((DEBUG_INFO, "OCVAR: Resetting NVRAM storage...\n"));
160
161 Status = OcVariableRuntimeProtocol->ResetNvram ();
162
163 if (EFI_ERROR (Status)) {
164 DEBUG ((DEBUG_WARN, "OCVAR: Emulated NVRAM reset failed - %r\n", Status));
165 }
166
168}
169
170VOID
171EFIAPI
173 VOID
174 )
175{
176 EFI_STATUS Status;
177 OC_VARIABLE_RUNTIME_PROTOCOL *OcVariableRuntimeProtocol;
178
179 Status = InternalLocateVariableRuntimeProtocol (&OcVariableRuntimeProtocol);
180 if (EFI_ERROR (Status)) {
181 return;
182 }
183
184 DEBUG ((DEBUG_INFO, "OCVAR: Switching to fallback NVRAM storage...\n"));
185
186 Status = OcVariableRuntimeProtocol->SwitchToFallback ();
187
188 if (EFI_ERROR (Status)) {
189 DEBUG ((
190 Status == EFI_ALREADY_STARTED ? DEBUG_INFO : DEBUG_WARN,
191 "OCVAR: Emulated NVRAM switch to fallback failed - %r\n",
192 Status
193 ));
194 }
195}
STATIC EFI_STATUS InternalLocateVariableRuntimeProtocol(OC_VARIABLE_RUNTIME_PROTOCOL **OcVariableRuntimeProtocol)
VOID EFIAPI OcSaveLegacyNvram(VOID)
VOID EFIAPI OcSwitchToFallbackLegacyNvram(VOID)
VOID EFIAPI OcResetLegacyNvram(VOID)
VOID OcLoadLegacyNvram(IN OC_STORAGE_CONTEXT *Storage, IN OC_NVRAM_LEGACY_MAP *LegacyMap, IN BOOLEAN LegacyOverwrite, IN BOOLEAN RequestBootVarRouting)
EFI_BOOT_SERVICES * gBS
VOID DirectResetCold(VOID)
Definition DirectReset.c:16
#define OC_FIRMWARE_RUNTIME_REVISION
EFI_GUID gOcFirmwareRuntimeProtocolGuid
EFI_GUID gOcVariableRuntimeProtocolGuid
#define OC_VARIABLE_RUNTIME_PROTOCOL_REVISION
#define ASSERT(x)
Definition coder.h:55
OC_FWRT_SET_OVERRIDE_CONFIG SetOverride
OC_VARIABLE_RUNTIME_PROTOCOL_LOAD_NVRAM LoadNvram
OC_VARIABLE_RUNTIME_PROTOCOL_SAVE_NVRAM SaveNvram
OC_VARIABLE_RUNTIME_PROTOCOL_RESET_NVRAM ResetNvram
OC_VARIABLE_RUNTIME_PROTOCOL_SWITCH_TO_FALLBACK SwitchToFallback