OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcVariableLib.c
Go to the documentation of this file.
1
8#include <Uefi.h>
9
10#include <Guid/OcVariable.h>
11
12#include <Library/BaseMemoryLib.h>
13#include <Library/DebugLib.h>
14#include <Library/MemoryAllocationLib.h>
16#include <Library/UefiRuntimeServicesTableLib.h>
17
18STATIC BOOLEAN mForceOcWriteFlash = FALSE;
19
20STATIC BOOLEAN mDebugInitialized = FALSE;
21
22VOID
24 IN BOOLEAN ForceOcWriteFlash
25 )
26{
27 mForceOcWriteFlash = ForceOcWriteFlash;
28
29 DEBUG_CODE_BEGIN ();
30 mDebugInitialized = TRUE;
31 DEBUG_CODE_END ();
32}
33
34EFI_STATUS
36 IN CHAR16 *VariableName,
37 IN UINT32 Attributes,
38 IN UINTN DataSize,
39 IN VOID *Data,
40 IN EFI_GUID *VendorGuid OPTIONAL
41 )
42{
43 EFI_STATUS Status;
44 INTN CmpResult;
45
46 UINTN OldDataSize;
47 VOID *OldData;
48
49 UINT8 StackBuffer[256];
50
51 if (VendorGuid == NULL) {
52 VendorGuid = &gOcVendorVariableGuid;
53 }
54
55 DEBUG_CODE_BEGIN ();
57 DEBUG_CODE_END ();
58 //
59 // All OC system variables are volatile as of now. Below logic must be adapted
60 // in case non-volatile requests are to be supported.
61 //
62 ASSERT ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0);
63 //
64 // If the data to be written is non-volatile, check first that the existing
65 // data is different. Handle errors tolerantly as this is only a shortcut.
66 //
68 //
69 // Try to read the old data to the stack first to save allocations.
70 //
71 OldDataSize = sizeof (StackBuffer);
72 OldData = StackBuffer;
73
74 Status = gRT->GetVariable (
75 VariableName,
76 VendorGuid,
77 NULL,
78 &OldDataSize,
79 OldData
80 );
81 if (Status == EFI_BUFFER_TOO_SMALL) {
82 //
83 // If the stack buffer is too small, allocate dynamically and retry.
84 //
85 OldData = AllocatePool (OldDataSize);
86 if (OldData != NULL) {
87 Status = gRT->GetVariable (
88 VariableName,
89 VendorGuid,
90 NULL,
91 &OldDataSize,
92 OldData
93 );
94 if (EFI_ERROR (Status)) {
95 FreePool (OldData);
96 }
97 }
98 }
99
100 if (!EFI_ERROR (Status)) {
101 //
102 // Status may only be a success value if the allocation did not fail.
103 //
104 ASSERT (OldData != NULL);
105 //
106 // Compare the current variable data to the new data to be written.
107 //
108 CmpResult = 1;
109 if (OldDataSize == DataSize) {
110 CmpResult = CompareMem (OldData, Data, DataSize);
111 }
112
113 if (OldData != StackBuffer) {
114 FreePool (OldData);
115 }
116
117 //
118 // If the old data is equal to the new data, skip the write.
119 //
120 if (CmpResult == 0) {
121 return EFI_SUCCESS;
122 }
123 }
124
125 //
126 // Force-write the OC system variable.
127 //
128 Attributes |= EFI_VARIABLE_NON_VOLATILE;
129 }
130
131 return gRT->SetVariable (
132 VariableName,
133 VendorGuid,
134 Attributes,
135 DataSize,
136 Data
137 );
138}
EFI_GUID gOcVendorVariableGuid
STATIC BOOLEAN mForceOcWriteFlash
EFI_STATUS OcSetSystemVariable(IN CHAR16 *VariableName, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data, IN EFI_GUID *VendorGuid OPTIONAL)
STATIC BOOLEAN mDebugInitialized
VOID OcVariableInit(IN BOOLEAN ForceOcWriteFlash)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
#define ASSERT(x)
Definition coder.h:55