xref: /netbsd-src/sys/external/bsd/gnu-efi/dist/lib/misc.c (revision 35ff39e48f27cc4d27af726cb651cda505a965b4)
1*35ff39e4Sjmcneill /*	$NetBSD: misc.c,v 1.3 2021/09/30 19:02:48 jmcneill Exp $	*/
2b2c829d7Sjakllsch 
3b2c829d7Sjakllsch /*++
4b2c829d7Sjakllsch 
5b2c829d7Sjakllsch Copyright (c) 1998  Intel Corporation
6b2c829d7Sjakllsch 
7b2c829d7Sjakllsch Module Name:
8b2c829d7Sjakllsch 
9b2c829d7Sjakllsch     misc.c
10b2c829d7Sjakllsch 
11b2c829d7Sjakllsch Abstract:
12b2c829d7Sjakllsch 
13b2c829d7Sjakllsch 
14b2c829d7Sjakllsch 
15b2c829d7Sjakllsch 
16b2c829d7Sjakllsch Revision History
17b2c829d7Sjakllsch 
18b2c829d7Sjakllsch --*/
19b2c829d7Sjakllsch 
20b2c829d7Sjakllsch #include "lib.h"
21b2c829d7Sjakllsch 
22b2c829d7Sjakllsch 
23b2c829d7Sjakllsch //
24b2c829d7Sjakllsch //
25b2c829d7Sjakllsch //
26b2c829d7Sjakllsch 
27b2c829d7Sjakllsch VOID *
AllocatePool(IN UINTN Size)28b2c829d7Sjakllsch AllocatePool (
29b2c829d7Sjakllsch     IN UINTN                Size
30b2c829d7Sjakllsch     )
31b2c829d7Sjakllsch {
32b2c829d7Sjakllsch     EFI_STATUS              Status;
33b2c829d7Sjakllsch     VOID                    *p;
34b2c829d7Sjakllsch 
35b2c829d7Sjakllsch     Status = uefi_call_wrapper(BS->AllocatePool, 3, PoolAllocationType, Size, &p);
36b2c829d7Sjakllsch     if (EFI_ERROR(Status)) {
37b2c829d7Sjakllsch         DEBUG((D_ERROR, "AllocatePool: out of pool  %x\n", Status));
38b2c829d7Sjakllsch         p = NULL;
39b2c829d7Sjakllsch     }
40b2c829d7Sjakllsch     return p;
41b2c829d7Sjakllsch }
42b2c829d7Sjakllsch 
43b2c829d7Sjakllsch VOID *
AllocateZeroPool(IN UINTN Size)44b2c829d7Sjakllsch AllocateZeroPool (
45b2c829d7Sjakllsch     IN UINTN                Size
46b2c829d7Sjakllsch     )
47b2c829d7Sjakllsch {
48b2c829d7Sjakllsch     VOID                    *p;
49b2c829d7Sjakllsch 
50b2c829d7Sjakllsch     p = AllocatePool (Size);
51b2c829d7Sjakllsch     if (p) {
52b2c829d7Sjakllsch         ZeroMem (p, Size);
53b2c829d7Sjakllsch     }
54b2c829d7Sjakllsch 
55b2c829d7Sjakllsch     return p;
56b2c829d7Sjakllsch }
57b2c829d7Sjakllsch 
58b2c829d7Sjakllsch VOID *
ReallocatePool(IN VOID * OldPool,IN UINTN OldSize,IN UINTN NewSize)59b2c829d7Sjakllsch ReallocatePool (
60b2c829d7Sjakllsch     IN VOID                 *OldPool,
61b2c829d7Sjakllsch     IN UINTN                OldSize,
62b2c829d7Sjakllsch     IN UINTN                NewSize
63b2c829d7Sjakllsch     )
64b2c829d7Sjakllsch {
65b2c829d7Sjakllsch     VOID                    *NewPool;
66b2c829d7Sjakllsch 
67b2c829d7Sjakllsch     NewPool = NULL;
68b2c829d7Sjakllsch     if (NewSize) {
69b2c829d7Sjakllsch         NewPool = AllocatePool (NewSize);
70b2c829d7Sjakllsch     }
71b2c829d7Sjakllsch 
72b2c829d7Sjakllsch     if (OldPool) {
73b2c829d7Sjakllsch         if (NewPool) {
74b2c829d7Sjakllsch             CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
75b2c829d7Sjakllsch         }
76b2c829d7Sjakllsch 
77b2c829d7Sjakllsch         FreePool (OldPool);
78b2c829d7Sjakllsch     }
79b2c829d7Sjakllsch 
80b2c829d7Sjakllsch     return NewPool;
81b2c829d7Sjakllsch }
82b2c829d7Sjakllsch 
83b2c829d7Sjakllsch 
84b2c829d7Sjakllsch VOID
FreePool(IN VOID * Buffer)85b2c829d7Sjakllsch FreePool (
86b2c829d7Sjakllsch     IN VOID                 *Buffer
87b2c829d7Sjakllsch     )
88b2c829d7Sjakllsch {
89b2c829d7Sjakllsch     uefi_call_wrapper(BS->FreePool, 1, Buffer);
90b2c829d7Sjakllsch }
91b2c829d7Sjakllsch 
92b2c829d7Sjakllsch 
93b2c829d7Sjakllsch 
94b2c829d7Sjakllsch VOID
ZeroMem(IN VOID * Buffer,IN UINTN Size)95b2c829d7Sjakllsch ZeroMem (
96b2c829d7Sjakllsch     IN VOID     *Buffer,
97b2c829d7Sjakllsch     IN UINTN    Size
98b2c829d7Sjakllsch     )
99b2c829d7Sjakllsch {
100b2c829d7Sjakllsch     RtZeroMem (Buffer, Size);
101b2c829d7Sjakllsch }
102b2c829d7Sjakllsch 
103b2c829d7Sjakllsch VOID
SetMem(IN VOID * Buffer,IN UINTN Size,IN UINT8 Value)104b2c829d7Sjakllsch SetMem (
105b2c829d7Sjakllsch     IN VOID     *Buffer,
106b2c829d7Sjakllsch     IN UINTN    Size,
107b2c829d7Sjakllsch     IN UINT8    Value
108b2c829d7Sjakllsch     )
109b2c829d7Sjakllsch {
110b2c829d7Sjakllsch     RtSetMem (Buffer, Size, Value);
111b2c829d7Sjakllsch }
112b2c829d7Sjakllsch 
113b2c829d7Sjakllsch VOID
CopyMem(IN VOID * Dest,IN CONST VOID * Src,IN UINTN len)114b2c829d7Sjakllsch CopyMem (
115b2c829d7Sjakllsch     IN VOID     *Dest,
116d1b935f8Sjmcneill     IN CONST VOID     *Src,
117b2c829d7Sjakllsch     IN UINTN    len
118b2c829d7Sjakllsch     )
119b2c829d7Sjakllsch {
120b2c829d7Sjakllsch     RtCopyMem (Dest, Src, len);
121b2c829d7Sjakllsch }
122b2c829d7Sjakllsch 
123b2c829d7Sjakllsch INTN
CompareMem(IN CONST VOID * Dest,IN CONST VOID * Src,IN UINTN len)124b2c829d7Sjakllsch CompareMem (
125d1b935f8Sjmcneill     IN CONST VOID     *Dest,
126d1b935f8Sjmcneill     IN CONST VOID     *Src,
127b2c829d7Sjakllsch     IN UINTN    len
128b2c829d7Sjakllsch     )
129b2c829d7Sjakllsch {
130b2c829d7Sjakllsch     return RtCompareMem (Dest, Src, len);
131b2c829d7Sjakllsch }
132b2c829d7Sjakllsch 
133b2c829d7Sjakllsch BOOLEAN
GrowBuffer(IN OUT EFI_STATUS * Status,IN OUT VOID ** Buffer,IN UINTN BufferSize)134b2c829d7Sjakllsch GrowBuffer(
135b2c829d7Sjakllsch     IN OUT EFI_STATUS   *Status,
136b2c829d7Sjakllsch     IN OUT VOID         **Buffer,
137b2c829d7Sjakllsch     IN UINTN            BufferSize
138b2c829d7Sjakllsch     )
139b2c829d7Sjakllsch /*++
140b2c829d7Sjakllsch 
141b2c829d7Sjakllsch Routine Description:
142b2c829d7Sjakllsch 
143b2c829d7Sjakllsch     Helper function called as part of the code needed
144b2c829d7Sjakllsch     to allocate the proper sized buffer for various
145b2c829d7Sjakllsch     EFI interfaces.
146b2c829d7Sjakllsch 
147b2c829d7Sjakllsch Arguments:
148b2c829d7Sjakllsch 
149b2c829d7Sjakllsch     Status      - Current status
150b2c829d7Sjakllsch 
151b2c829d7Sjakllsch     Buffer      - Current allocated buffer, or NULL
152b2c829d7Sjakllsch 
153b2c829d7Sjakllsch     BufferSize  - Current buffer size needed
154b2c829d7Sjakllsch 
155b2c829d7Sjakllsch Returns:
156b2c829d7Sjakllsch 
157b2c829d7Sjakllsch     TRUE - if the buffer was reallocated and the caller
158b2c829d7Sjakllsch     should try the API again.
159b2c829d7Sjakllsch 
160b2c829d7Sjakllsch --*/
161b2c829d7Sjakllsch {
162b2c829d7Sjakllsch     BOOLEAN         TryAgain;
163b2c829d7Sjakllsch 
164b2c829d7Sjakllsch     //
165b2c829d7Sjakllsch     // If this is an initial request, buffer will be null with a new buffer size
166b2c829d7Sjakllsch     //
167b2c829d7Sjakllsch 
168b2c829d7Sjakllsch     if (!*Buffer && BufferSize) {
169b2c829d7Sjakllsch         *Status = EFI_BUFFER_TOO_SMALL;
170b2c829d7Sjakllsch     }
171b2c829d7Sjakllsch 
172b2c829d7Sjakllsch     //
173b2c829d7Sjakllsch     // If the status code is "buffer too small", resize the buffer
174b2c829d7Sjakllsch     //
175b2c829d7Sjakllsch 
176b2c829d7Sjakllsch     TryAgain = FALSE;
177b2c829d7Sjakllsch     if (*Status == EFI_BUFFER_TOO_SMALL) {
178b2c829d7Sjakllsch 
179b2c829d7Sjakllsch         if (*Buffer) {
180b2c829d7Sjakllsch             FreePool (*Buffer);
181b2c829d7Sjakllsch         }
182b2c829d7Sjakllsch 
183b2c829d7Sjakllsch         *Buffer = AllocatePool (BufferSize);
184b2c829d7Sjakllsch 
185b2c829d7Sjakllsch         if (*Buffer) {
186b2c829d7Sjakllsch             TryAgain = TRUE;
187b2c829d7Sjakllsch         } else {
188b2c829d7Sjakllsch             *Status = EFI_OUT_OF_RESOURCES;
189b2c829d7Sjakllsch         }
190b2c829d7Sjakllsch     }
191b2c829d7Sjakllsch 
192b2c829d7Sjakllsch     //
193b2c829d7Sjakllsch     // If there's an error, free the buffer
194b2c829d7Sjakllsch     //
195b2c829d7Sjakllsch 
196b2c829d7Sjakllsch     if (!TryAgain && EFI_ERROR(*Status) && *Buffer) {
197b2c829d7Sjakllsch         FreePool (*Buffer);
198b2c829d7Sjakllsch         *Buffer = NULL;
199b2c829d7Sjakllsch     }
200b2c829d7Sjakllsch 
201b2c829d7Sjakllsch     return TryAgain;
202b2c829d7Sjakllsch }
203b2c829d7Sjakllsch 
204b2c829d7Sjakllsch 
205b2c829d7Sjakllsch EFI_MEMORY_DESCRIPTOR *
LibMemoryMap(OUT UINTN * NoEntries,OUT UINTN * MapKey,OUT UINTN * DescriptorSize,OUT UINT32 * DescriptorVersion)206b2c829d7Sjakllsch LibMemoryMap (
207b2c829d7Sjakllsch     OUT UINTN               *NoEntries,
208b2c829d7Sjakllsch     OUT UINTN               *MapKey,
209b2c829d7Sjakllsch     OUT UINTN               *DescriptorSize,
210b2c829d7Sjakllsch     OUT UINT32              *DescriptorVersion
211b2c829d7Sjakllsch     )
212b2c829d7Sjakllsch {
213b2c829d7Sjakllsch     EFI_STATUS              Status;
214b2c829d7Sjakllsch     EFI_MEMORY_DESCRIPTOR   *Buffer;
215b2c829d7Sjakllsch     UINTN                   BufferSize;
216b2c829d7Sjakllsch 
217b2c829d7Sjakllsch     //
218b2c829d7Sjakllsch     // Initialize for GrowBuffer loop
219b2c829d7Sjakllsch     //
220b2c829d7Sjakllsch 
221d1b935f8Sjmcneill     Status = EFI_SUCCESS;
222b2c829d7Sjakllsch     Buffer = NULL;
223b2c829d7Sjakllsch     BufferSize = sizeof(EFI_MEMORY_DESCRIPTOR);
224b2c829d7Sjakllsch 
225b2c829d7Sjakllsch     //
226b2c829d7Sjakllsch     // Call the real function
227b2c829d7Sjakllsch     //
228b2c829d7Sjakllsch 
229b2c829d7Sjakllsch     while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
230b2c829d7Sjakllsch         Status = uefi_call_wrapper(BS->GetMemoryMap, 5, &BufferSize, Buffer, MapKey, DescriptorSize, DescriptorVersion);
231b2c829d7Sjakllsch     }
232b2c829d7Sjakllsch 
233b2c829d7Sjakllsch     //
234b2c829d7Sjakllsch     // Convert buffer size to NoEntries
235b2c829d7Sjakllsch     //
236b2c829d7Sjakllsch 
237b2c829d7Sjakllsch     if (!EFI_ERROR(Status)) {
238b2c829d7Sjakllsch         *NoEntries = BufferSize / *DescriptorSize;
239b2c829d7Sjakllsch     }
240b2c829d7Sjakllsch 
241b2c829d7Sjakllsch     return Buffer;
242b2c829d7Sjakllsch }
243b2c829d7Sjakllsch 
244b2c829d7Sjakllsch VOID *
LibGetVariableAndSize(IN CHAR16 * Name,IN EFI_GUID * VendorGuid,OUT UINTN * VarSize)245b2c829d7Sjakllsch LibGetVariableAndSize (
246b2c829d7Sjakllsch     IN CHAR16               *Name,
247b2c829d7Sjakllsch     IN EFI_GUID             *VendorGuid,
248b2c829d7Sjakllsch     OUT UINTN               *VarSize
249b2c829d7Sjakllsch     )
250b2c829d7Sjakllsch {
251*35ff39e4Sjmcneill     EFI_STATUS              Status = EFI_SUCCESS;
252b2c829d7Sjakllsch     VOID                    *Buffer;
253b2c829d7Sjakllsch     UINTN                   BufferSize;
254b2c829d7Sjakllsch 
255b2c829d7Sjakllsch     //
256b2c829d7Sjakllsch     // Initialize for GrowBuffer loop
257b2c829d7Sjakllsch     //
258b2c829d7Sjakllsch 
259dca76491Smrg     Status = EFI_SUCCESS;
260b2c829d7Sjakllsch     Buffer = NULL;
261b2c829d7Sjakllsch     BufferSize = 100;
262b2c829d7Sjakllsch 
263b2c829d7Sjakllsch     //
264b2c829d7Sjakllsch     // Call the real function
265b2c829d7Sjakllsch     //
266b2c829d7Sjakllsch 
267b2c829d7Sjakllsch     while (GrowBuffer (&Status, &Buffer, BufferSize)) {
268b2c829d7Sjakllsch         Status = uefi_call_wrapper(
269b2c829d7Sjakllsch 		    RT->GetVariable,
270b2c829d7Sjakllsch 			5,
271b2c829d7Sjakllsch                     Name,
272b2c829d7Sjakllsch                     VendorGuid,
273b2c829d7Sjakllsch                     NULL,
274b2c829d7Sjakllsch                     &BufferSize,
275b2c829d7Sjakllsch                     Buffer
276b2c829d7Sjakllsch                     );
277b2c829d7Sjakllsch     }
278b2c829d7Sjakllsch     if (Buffer) {
279b2c829d7Sjakllsch         *VarSize = BufferSize;
280b2c829d7Sjakllsch     } else {
281b2c829d7Sjakllsch         *VarSize = 0;
282b2c829d7Sjakllsch     }
283b2c829d7Sjakllsch     return Buffer;
284b2c829d7Sjakllsch }
285b2c829d7Sjakllsch 
286b2c829d7Sjakllsch VOID *
LibGetVariable(IN CHAR16 * Name,IN EFI_GUID * VendorGuid)287b2c829d7Sjakllsch LibGetVariable (
288b2c829d7Sjakllsch     IN CHAR16               *Name,
289b2c829d7Sjakllsch     IN EFI_GUID             *VendorGuid
290b2c829d7Sjakllsch     )
291b2c829d7Sjakllsch {
292b2c829d7Sjakllsch     UINTN   VarSize;
293b2c829d7Sjakllsch 
294b2c829d7Sjakllsch     return LibGetVariableAndSize (Name, VendorGuid, &VarSize);
295b2c829d7Sjakllsch }
296b2c829d7Sjakllsch 
297b2c829d7Sjakllsch EFI_STATUS
LibDeleteVariable(IN CHAR16 * VarName,IN EFI_GUID * VarGuid)298b2c829d7Sjakllsch LibDeleteVariable (
299b2c829d7Sjakllsch     IN CHAR16   *VarName,
300b2c829d7Sjakllsch     IN EFI_GUID *VarGuid
301b2c829d7Sjakllsch     )
302b2c829d7Sjakllsch {
303b2c829d7Sjakllsch     VOID        *VarBuf;
304b2c829d7Sjakllsch     EFI_STATUS  Status;
305b2c829d7Sjakllsch 
306b2c829d7Sjakllsch     VarBuf = LibGetVariable(VarName,VarGuid);
307b2c829d7Sjakllsch 
308b2c829d7Sjakllsch     Status = EFI_NOT_FOUND;
309b2c829d7Sjakllsch 
310b2c829d7Sjakllsch     if (VarBuf) {
311b2c829d7Sjakllsch         //
312b2c829d7Sjakllsch         // Delete variable from Storage
313b2c829d7Sjakllsch         //
314b2c829d7Sjakllsch         Status = uefi_call_wrapper(
315b2c829d7Sjakllsch 		    RT->SetVariable,
316b2c829d7Sjakllsch 			5,
317b2c829d7Sjakllsch                     VarName, VarGuid,
318b2c829d7Sjakllsch                     EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
319b2c829d7Sjakllsch                     0, NULL
320b2c829d7Sjakllsch                  );
321b2c829d7Sjakllsch         ASSERT (!EFI_ERROR(Status));
322b2c829d7Sjakllsch         FreePool(VarBuf);
323b2c829d7Sjakllsch     }
324b2c829d7Sjakllsch 
325b2c829d7Sjakllsch     return (Status);
326b2c829d7Sjakllsch }
327b2c829d7Sjakllsch 
328b2c829d7Sjakllsch EFI_STATUS
LibSetNVVariable(IN CHAR16 * VarName,IN EFI_GUID * VarGuid,IN UINTN DataSize,IN VOID * Data)329d1b935f8Sjmcneill LibSetNVVariable (
330d1b935f8Sjmcneill     IN CHAR16   *VarName,
331d1b935f8Sjmcneill     IN EFI_GUID *VarGuid,
332d1b935f8Sjmcneill     IN UINTN	 DataSize,
333d1b935f8Sjmcneill     IN VOID     *Data
334d1b935f8Sjmcneill     )
335d1b935f8Sjmcneill {
336d1b935f8Sjmcneill     EFI_STATUS  Status;
337d1b935f8Sjmcneill 
338d1b935f8Sjmcneill     Status = uefi_call_wrapper(
339d1b935f8Sjmcneill 	    RT->SetVariable,
340d1b935f8Sjmcneill 	    5,
341d1b935f8Sjmcneill 	    VarName, VarGuid,
342d1b935f8Sjmcneill 	    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
343d1b935f8Sjmcneill 	    DataSize, Data
344d1b935f8Sjmcneill 	    );
345d1b935f8Sjmcneill     ASSERT (!EFI_ERROR(Status));
346d1b935f8Sjmcneill     return (Status);
347d1b935f8Sjmcneill }
348d1b935f8Sjmcneill 
349d1b935f8Sjmcneill EFI_STATUS
LibSetVariable(IN CHAR16 * VarName,IN EFI_GUID * VarGuid,IN UINTN DataSize,IN VOID * Data)350d1b935f8Sjmcneill LibSetVariable (
351d1b935f8Sjmcneill     IN CHAR16   *VarName,
352d1b935f8Sjmcneill     IN EFI_GUID *VarGuid,
353d1b935f8Sjmcneill     IN UINTN	 DataSize,
354d1b935f8Sjmcneill     IN VOID     *Data
355d1b935f8Sjmcneill     )
356d1b935f8Sjmcneill {
357d1b935f8Sjmcneill     EFI_STATUS  Status;
358d1b935f8Sjmcneill 
359d1b935f8Sjmcneill     Status = uefi_call_wrapper(
360d1b935f8Sjmcneill 	    RT->SetVariable,
361d1b935f8Sjmcneill 	    5,
362d1b935f8Sjmcneill 	    VarName, VarGuid,
363d1b935f8Sjmcneill 	    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
364d1b935f8Sjmcneill 	    DataSize, Data
365d1b935f8Sjmcneill 	    );
366d1b935f8Sjmcneill     ASSERT (!EFI_ERROR(Status));
367d1b935f8Sjmcneill     return (Status);
368d1b935f8Sjmcneill }
369d1b935f8Sjmcneill 
370d1b935f8Sjmcneill EFI_STATUS
LibInsertToTailOfBootOrder(IN UINT16 BootOption,IN BOOLEAN OnlyInsertIfEmpty)371b2c829d7Sjakllsch LibInsertToTailOfBootOrder (
372b2c829d7Sjakllsch     IN  UINT16  BootOption,
373b2c829d7Sjakllsch     IN  BOOLEAN OnlyInsertIfEmpty
374b2c829d7Sjakllsch     )
375b2c829d7Sjakllsch {
376b2c829d7Sjakllsch     UINT16      *BootOptionArray;
377b2c829d7Sjakllsch     UINT16      *NewBootOptionArray;
378b2c829d7Sjakllsch     UINTN       VarSize;
379b2c829d7Sjakllsch     UINTN       Index;
380b2c829d7Sjakllsch     EFI_STATUS  Status;
381b2c829d7Sjakllsch 
382b2c829d7Sjakllsch     BootOptionArray = LibGetVariableAndSize (VarBootOrder, &EfiGlobalVariable, &VarSize);
383b2c829d7Sjakllsch     if (VarSize != 0 && OnlyInsertIfEmpty) {
384b2c829d7Sjakllsch         if (BootOptionArray) {
385b2c829d7Sjakllsch             FreePool (BootOptionArray);
386b2c829d7Sjakllsch         }
387b2c829d7Sjakllsch         return EFI_UNSUPPORTED;
388b2c829d7Sjakllsch     }
389b2c829d7Sjakllsch 
390b2c829d7Sjakllsch     VarSize += sizeof(UINT16);
391b2c829d7Sjakllsch     NewBootOptionArray = AllocatePool (VarSize);
392*35ff39e4Sjmcneill     if (!NewBootOptionArray)
393*35ff39e4Sjmcneill         return EFI_OUT_OF_RESOURCES;
394b2c829d7Sjakllsch 
395b2c829d7Sjakllsch     for (Index = 0; Index < ((VarSize/sizeof(UINT16)) - 1); Index++) {
396b2c829d7Sjakllsch         NewBootOptionArray[Index] = BootOptionArray[Index];
397b2c829d7Sjakllsch     }
398b2c829d7Sjakllsch     //
399b2c829d7Sjakllsch     // Insert in the tail of the array
400b2c829d7Sjakllsch     //
401b2c829d7Sjakllsch     NewBootOptionArray[Index] = BootOption;
402b2c829d7Sjakllsch 
403b2c829d7Sjakllsch     Status = uefi_call_wrapper(
404b2c829d7Sjakllsch 		RT->SetVariable,
405b2c829d7Sjakllsch 		5,
406b2c829d7Sjakllsch                 VarBootOrder, &EfiGlobalVariable,
407b2c829d7Sjakllsch                 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
408b2c829d7Sjakllsch                 VarSize, (VOID*) NewBootOptionArray
409b2c829d7Sjakllsch                 );
410b2c829d7Sjakllsch 
411b2c829d7Sjakllsch     FreePool (NewBootOptionArray);
412b2c829d7Sjakllsch     if (BootOptionArray) {
413b2c829d7Sjakllsch         FreePool (BootOptionArray);
414b2c829d7Sjakllsch     }
415b2c829d7Sjakllsch     return Status;
416b2c829d7Sjakllsch }
417b2c829d7Sjakllsch 
418b2c829d7Sjakllsch 
419b2c829d7Sjakllsch BOOLEAN
ValidMBR(IN MASTER_BOOT_RECORD * Mbr,IN EFI_BLOCK_IO * BlkIo)420b2c829d7Sjakllsch ValidMBR(
421b2c829d7Sjakllsch     IN  MASTER_BOOT_RECORD  *Mbr,
422b2c829d7Sjakllsch     IN  EFI_BLOCK_IO        *BlkIo
423b2c829d7Sjakllsch     )
424b2c829d7Sjakllsch {
425b2c829d7Sjakllsch     UINT32      StartingLBA, EndingLBA;
426b2c829d7Sjakllsch     UINT32      NewEndingLBA;
427b2c829d7Sjakllsch     INTN        i, j;
428b2c829d7Sjakllsch     BOOLEAN     ValidMbr;
429b2c829d7Sjakllsch 
430b2c829d7Sjakllsch     if (Mbr->Signature != MBR_SIGNATURE) {
431b2c829d7Sjakllsch         //
432b2c829d7Sjakllsch         // The BPB also has this signature, so it can not be used alone.
433b2c829d7Sjakllsch         //
434b2c829d7Sjakllsch         return FALSE;
435b2c829d7Sjakllsch     }
436b2c829d7Sjakllsch 
437b2c829d7Sjakllsch     ValidMbr = FALSE;
438b2c829d7Sjakllsch     for (i=0; i<MAX_MBR_PARTITIONS; i++) {
439b2c829d7Sjakllsch         if ( Mbr->Partition[i].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) == 0 ) {
440b2c829d7Sjakllsch             continue;
441b2c829d7Sjakllsch         }
442b2c829d7Sjakllsch         ValidMbr = TRUE;
443b2c829d7Sjakllsch         StartingLBA = EXTRACT_UINT32(Mbr->Partition[i].StartingLBA);
444b2c829d7Sjakllsch         EndingLBA = StartingLBA + EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) - 1;
445b2c829d7Sjakllsch         if (EndingLBA > BlkIo->Media->LastBlock) {
446b2c829d7Sjakllsch             //
447b2c829d7Sjakllsch             // Compatability Errata:
448b2c829d7Sjakllsch             //  Some systems try to hide drive space with thier INT 13h driver
449b2c829d7Sjakllsch             //  This does not hide space from the OS driver. This means the MBR
450b2c829d7Sjakllsch             //  that gets created from DOS is smaller than the MBR created from
451b2c829d7Sjakllsch             //  a real OS (NT & Win98). This leads to BlkIo->LastBlock being
452b2c829d7Sjakllsch             //  wrong on some systems FDISKed by the OS.
453b2c829d7Sjakllsch             //
454b2c829d7Sjakllsch             //
455b2c829d7Sjakllsch             if (BlkIo->Media->LastBlock < MIN_MBR_DEVICE_SIZE) {
456b2c829d7Sjakllsch                 //
457b2c829d7Sjakllsch                 // If this is a very small device then trust the BlkIo->LastBlock
458b2c829d7Sjakllsch                 //
459b2c829d7Sjakllsch                 return FALSE;
460b2c829d7Sjakllsch             }
461b2c829d7Sjakllsch 
462b2c829d7Sjakllsch             if (EndingLBA > (BlkIo->Media->LastBlock + MBR_ERRATA_PAD)) {
463b2c829d7Sjakllsch                 return FALSE;
464b2c829d7Sjakllsch             }
465b2c829d7Sjakllsch 
466b2c829d7Sjakllsch         }
467b2c829d7Sjakllsch         for (j=i+1; j<MAX_MBR_PARTITIONS; j++) {
468b2c829d7Sjakllsch             if (Mbr->Partition[j].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) == 0) {
469b2c829d7Sjakllsch                 continue;
470b2c829d7Sjakllsch             }
471b2c829d7Sjakllsch             if (   EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) >= StartingLBA &&
472b2c829d7Sjakllsch                    EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) <= EndingLBA       ) {
473b2c829d7Sjakllsch                 //
474b2c829d7Sjakllsch                 // The Start of this region overlaps with the i'th region
475b2c829d7Sjakllsch                 //
476b2c829d7Sjakllsch                 return FALSE;
477b2c829d7Sjakllsch             }
478b2c829d7Sjakllsch             NewEndingLBA = EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) + EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) - 1;
479b2c829d7Sjakllsch             if ( NewEndingLBA >= StartingLBA && NewEndingLBA <= EndingLBA ) {
480b2c829d7Sjakllsch                 //
481b2c829d7Sjakllsch                 // The End of this region overlaps with the i'th region
482b2c829d7Sjakllsch                 //
483b2c829d7Sjakllsch                 return FALSE;
484b2c829d7Sjakllsch             }
485b2c829d7Sjakllsch         }
486b2c829d7Sjakllsch     }
487b2c829d7Sjakllsch     //
488b2c829d7Sjakllsch     // Non of the regions overlapped so MBR is O.K.
489b2c829d7Sjakllsch     //
490b2c829d7Sjakllsch     return ValidMbr;
491b2c829d7Sjakllsch }
492b2c829d7Sjakllsch 
493b2c829d7Sjakllsch 
494b2c829d7Sjakllsch UINT8
DecimaltoBCD(IN UINT8 DecValue)495b2c829d7Sjakllsch DecimaltoBCD(
496b2c829d7Sjakllsch     IN  UINT8 DecValue
497b2c829d7Sjakllsch     )
498b2c829d7Sjakllsch {
499b2c829d7Sjakllsch     return RtDecimaltoBCD (DecValue);
500b2c829d7Sjakllsch }
501b2c829d7Sjakllsch 
502b2c829d7Sjakllsch 
503b2c829d7Sjakllsch UINT8
BCDtoDecimal(IN UINT8 BcdValue)504b2c829d7Sjakllsch BCDtoDecimal(
505b2c829d7Sjakllsch     IN  UINT8 BcdValue
506b2c829d7Sjakllsch     )
507b2c829d7Sjakllsch {
508b2c829d7Sjakllsch     return RtBCDtoDecimal (BcdValue);
509b2c829d7Sjakllsch }
510b2c829d7Sjakllsch 
511b2c829d7Sjakllsch EFI_STATUS
LibGetSystemConfigurationTable(IN EFI_GUID * TableGuid,IN OUT VOID ** Table)512b2c829d7Sjakllsch LibGetSystemConfigurationTable(
513b2c829d7Sjakllsch     IN EFI_GUID *TableGuid,
514b2c829d7Sjakllsch     IN OUT VOID **Table
515b2c829d7Sjakllsch     )
516b2c829d7Sjakllsch 
517b2c829d7Sjakllsch {
518b2c829d7Sjakllsch     UINTN Index;
519b2c829d7Sjakllsch 
520b2c829d7Sjakllsch     for(Index=0;Index<ST->NumberOfTableEntries;Index++) {
521b2c829d7Sjakllsch         if (CompareGuid(TableGuid,&(ST->ConfigurationTable[Index].VendorGuid))==0) {
522b2c829d7Sjakllsch             *Table = ST->ConfigurationTable[Index].VendorTable;
523b2c829d7Sjakllsch             return EFI_SUCCESS;
524b2c829d7Sjakllsch         }
525b2c829d7Sjakllsch     }
526b2c829d7Sjakllsch     return EFI_NOT_FOUND;
527b2c829d7Sjakllsch }
528b2c829d7Sjakllsch 
529b2c829d7Sjakllsch 
530b2c829d7Sjakllsch CHAR16 *
LibGetUiString(IN EFI_HANDLE Handle,IN UI_STRING_TYPE StringType,IN ISO_639_2 * LangCode,IN BOOLEAN ReturnDevicePathStrOnMismatch)531b2c829d7Sjakllsch LibGetUiString (
532b2c829d7Sjakllsch     IN  EFI_HANDLE      Handle,
533b2c829d7Sjakllsch     IN  UI_STRING_TYPE  StringType,
534b2c829d7Sjakllsch     IN  ISO_639_2       *LangCode,
535b2c829d7Sjakllsch     IN  BOOLEAN         ReturnDevicePathStrOnMismatch
536b2c829d7Sjakllsch     )
537b2c829d7Sjakllsch {
538b2c829d7Sjakllsch     UI_INTERFACE    *Ui;
539b2c829d7Sjakllsch     UI_STRING_TYPE  Index;
540b2c829d7Sjakllsch     UI_STRING_ENTRY *Array;
541b2c829d7Sjakllsch     EFI_STATUS      Status;
542b2c829d7Sjakllsch 
543b2c829d7Sjakllsch     Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &UiProtocol, (VOID *)&Ui);
544b2c829d7Sjakllsch     if (EFI_ERROR(Status)) {
545b2c829d7Sjakllsch         return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
546b2c829d7Sjakllsch     }
547b2c829d7Sjakllsch 
548b2c829d7Sjakllsch     //
549b2c829d7Sjakllsch     // Skip the first strings
550b2c829d7Sjakllsch     //
551b2c829d7Sjakllsch     for (Index = UiDeviceString, Array = Ui->Entry; Index < StringType; Index++, Array++) {
552b2c829d7Sjakllsch         while (Array->LangCode) {
553b2c829d7Sjakllsch             Array++;
554b2c829d7Sjakllsch         }
555b2c829d7Sjakllsch     }
556b2c829d7Sjakllsch 
557b2c829d7Sjakllsch     //
558b2c829d7Sjakllsch     // Search for the match
559b2c829d7Sjakllsch     //
560b2c829d7Sjakllsch     while (Array->LangCode) {
561b2c829d7Sjakllsch         if (strcmpa (Array->LangCode, LangCode) == 0) {
562b2c829d7Sjakllsch             return Array->UiString;
563b2c829d7Sjakllsch         }
564b2c829d7Sjakllsch     }
565b2c829d7Sjakllsch     return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
566b2c829d7Sjakllsch }
567