xref: /DragonStub/lib/misc.c (revision dfdcd7eff371071d4f5089fa8bf1c50bef6828f5)
1530d68baSNigel Croxon /*++
2530d68baSNigel Croxon 
3530d68baSNigel Croxon Copyright (c) 1998  Intel Corporation
4530d68baSNigel Croxon 
5530d68baSNigel Croxon Module Name:
6530d68baSNigel Croxon 
7530d68baSNigel Croxon     misc.c
8530d68baSNigel Croxon 
9530d68baSNigel Croxon Abstract:
10530d68baSNigel Croxon 
11530d68baSNigel Croxon 
12530d68baSNigel Croxon 
13530d68baSNigel Croxon 
14530d68baSNigel Croxon Revision History
15530d68baSNigel Croxon 
16530d68baSNigel Croxon --*/
17530d68baSNigel Croxon 
18530d68baSNigel Croxon #include "lib.h"
19530d68baSNigel Croxon 
20530d68baSNigel Croxon 
21530d68baSNigel Croxon //
22530d68baSNigel Croxon //
23530d68baSNigel Croxon //
24530d68baSNigel Croxon 
25530d68baSNigel Croxon VOID *
26530d68baSNigel Croxon AllocatePool (
27530d68baSNigel Croxon     IN UINTN                Size
28530d68baSNigel Croxon     )
29530d68baSNigel Croxon {
30530d68baSNigel Croxon     EFI_STATUS              Status;
31530d68baSNigel Croxon     VOID                    *p;
32530d68baSNigel Croxon 
33530d68baSNigel Croxon     Status = uefi_call_wrapper(BS->AllocatePool, 3, PoolAllocationType, Size, &p);
34530d68baSNigel Croxon     if (EFI_ERROR(Status)) {
35530d68baSNigel Croxon         DEBUG((D_ERROR, "AllocatePool: out of pool  %x\n", Status));
36530d68baSNigel Croxon         p = NULL;
37530d68baSNigel Croxon     }
38530d68baSNigel Croxon     return p;
39530d68baSNigel Croxon }
40530d68baSNigel Croxon 
41530d68baSNigel Croxon VOID *
42530d68baSNigel Croxon AllocateZeroPool (
43530d68baSNigel Croxon     IN UINTN                Size
44530d68baSNigel Croxon     )
45530d68baSNigel Croxon {
46530d68baSNigel Croxon     VOID                    *p;
47530d68baSNigel Croxon 
48530d68baSNigel Croxon     p = AllocatePool (Size);
49530d68baSNigel Croxon     if (p) {
50530d68baSNigel Croxon         ZeroMem (p, Size);
51530d68baSNigel Croxon     }
52530d68baSNigel Croxon 
53530d68baSNigel Croxon     return p;
54530d68baSNigel Croxon }
55530d68baSNigel Croxon 
56530d68baSNigel Croxon VOID *
57530d68baSNigel Croxon ReallocatePool (
58530d68baSNigel Croxon     IN VOID                 *OldPool,
59530d68baSNigel Croxon     IN UINTN                OldSize,
60530d68baSNigel Croxon     IN UINTN                NewSize
61530d68baSNigel Croxon     )
62530d68baSNigel Croxon {
63530d68baSNigel Croxon     VOID                    *NewPool;
64530d68baSNigel Croxon 
65530d68baSNigel Croxon     NewPool = NULL;
66530d68baSNigel Croxon     if (NewSize) {
67530d68baSNigel Croxon         NewPool = AllocatePool (NewSize);
68530d68baSNigel Croxon     }
69530d68baSNigel Croxon 
70530d68baSNigel Croxon     if (OldPool) {
71530d68baSNigel Croxon         if (NewPool) {
72530d68baSNigel Croxon             CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
73530d68baSNigel Croxon         }
74530d68baSNigel Croxon 
75530d68baSNigel Croxon         FreePool (OldPool);
76530d68baSNigel Croxon     }
77530d68baSNigel Croxon 
78530d68baSNigel Croxon     return NewPool;
79530d68baSNigel Croxon }
80530d68baSNigel Croxon 
81530d68baSNigel Croxon 
82530d68baSNigel Croxon VOID
83530d68baSNigel Croxon FreePool (
84530d68baSNigel Croxon     IN VOID                 *Buffer
85530d68baSNigel Croxon     )
86530d68baSNigel Croxon {
87530d68baSNigel Croxon     uefi_call_wrapper(BS->FreePool, 1, Buffer);
88530d68baSNigel Croxon }
89530d68baSNigel Croxon 
90530d68baSNigel Croxon 
91530d68baSNigel Croxon 
92530d68baSNigel Croxon VOID
93530d68baSNigel Croxon ZeroMem (
94530d68baSNigel Croxon     IN VOID     *Buffer,
95530d68baSNigel Croxon     IN UINTN    Size
96530d68baSNigel Croxon     )
97530d68baSNigel Croxon {
98530d68baSNigel Croxon     RtZeroMem (Buffer, Size);
99530d68baSNigel Croxon }
100530d68baSNigel Croxon 
101530d68baSNigel Croxon VOID
102530d68baSNigel Croxon SetMem (
103530d68baSNigel Croxon     IN VOID     *Buffer,
104530d68baSNigel Croxon     IN UINTN    Size,
105530d68baSNigel Croxon     IN UINT8    Value
106530d68baSNigel Croxon     )
107530d68baSNigel Croxon {
108530d68baSNigel Croxon     RtSetMem (Buffer, Size, Value);
109530d68baSNigel Croxon }
110530d68baSNigel Croxon 
111530d68baSNigel Croxon VOID
112530d68baSNigel Croxon CopyMem (
113530d68baSNigel Croxon     IN VOID     *Dest,
114530d68baSNigel Croxon     IN CONST VOID     *Src,
115530d68baSNigel Croxon     IN UINTN    len
116530d68baSNigel Croxon     )
117530d68baSNigel Croxon {
118530d68baSNigel Croxon     RtCopyMem (Dest, Src, len);
119530d68baSNigel Croxon }
120530d68baSNigel Croxon 
121530d68baSNigel Croxon INTN
122530d68baSNigel Croxon CompareMem (
123530d68baSNigel Croxon     IN CONST VOID     *Dest,
124530d68baSNigel Croxon     IN CONST VOID     *Src,
125530d68baSNigel Croxon     IN UINTN    len
126530d68baSNigel Croxon     )
127530d68baSNigel Croxon {
128530d68baSNigel Croxon     return RtCompareMem (Dest, Src, len);
129530d68baSNigel Croxon }
130530d68baSNigel Croxon 
131530d68baSNigel Croxon BOOLEAN
132530d68baSNigel Croxon GrowBuffer(
133530d68baSNigel Croxon     IN OUT EFI_STATUS   *Status,
134530d68baSNigel Croxon     IN OUT VOID         **Buffer,
135530d68baSNigel Croxon     IN UINTN            BufferSize
136530d68baSNigel Croxon     )
137530d68baSNigel Croxon /*++
138530d68baSNigel Croxon 
139530d68baSNigel Croxon Routine Description:
140530d68baSNigel Croxon 
141530d68baSNigel Croxon     Helper function called as part of the code needed
142530d68baSNigel Croxon     to allocate the proper sized buffer for various
143530d68baSNigel Croxon     EFI interfaces.
144530d68baSNigel Croxon 
145530d68baSNigel Croxon Arguments:
146530d68baSNigel Croxon 
147530d68baSNigel Croxon     Status      - Current status
148530d68baSNigel Croxon 
149530d68baSNigel Croxon     Buffer      - Current allocated buffer, or NULL
150530d68baSNigel Croxon 
151530d68baSNigel Croxon     BufferSize  - Current buffer size needed
152530d68baSNigel Croxon 
153530d68baSNigel Croxon Returns:
154530d68baSNigel Croxon 
155530d68baSNigel Croxon     TRUE - if the buffer was reallocated and the caller
156530d68baSNigel Croxon     should try the API again.
157530d68baSNigel Croxon 
158530d68baSNigel Croxon --*/
159530d68baSNigel Croxon {
160530d68baSNigel Croxon     BOOLEAN         TryAgain;
161530d68baSNigel Croxon 
162530d68baSNigel Croxon     //
163530d68baSNigel Croxon     // If this is an initial request, buffer will be null with a new buffer size
164530d68baSNigel Croxon     //
165530d68baSNigel Croxon 
166530d68baSNigel Croxon     if (!*Buffer && BufferSize) {
167530d68baSNigel Croxon         *Status = EFI_BUFFER_TOO_SMALL;
168530d68baSNigel Croxon     }
169530d68baSNigel Croxon 
170530d68baSNigel Croxon     //
171530d68baSNigel Croxon     // If the status code is "buffer too small", resize the buffer
172530d68baSNigel Croxon     //
173530d68baSNigel Croxon 
174530d68baSNigel Croxon     TryAgain = FALSE;
175530d68baSNigel Croxon     if (*Status == EFI_BUFFER_TOO_SMALL) {
176530d68baSNigel Croxon 
177530d68baSNigel Croxon         if (*Buffer) {
178530d68baSNigel Croxon             FreePool (*Buffer);
179530d68baSNigel Croxon         }
180530d68baSNigel Croxon 
181530d68baSNigel Croxon         *Buffer = AllocatePool (BufferSize);
182530d68baSNigel Croxon 
183530d68baSNigel Croxon         if (*Buffer) {
184530d68baSNigel Croxon             TryAgain = TRUE;
185530d68baSNigel Croxon         } else {
186530d68baSNigel Croxon             *Status = EFI_OUT_OF_RESOURCES;
187530d68baSNigel Croxon         }
188530d68baSNigel Croxon     }
189530d68baSNigel Croxon 
190530d68baSNigel Croxon     //
191530d68baSNigel Croxon     // If there's an error, free the buffer
192530d68baSNigel Croxon     //
193530d68baSNigel Croxon 
194530d68baSNigel Croxon     if (!TryAgain && EFI_ERROR(*Status) && *Buffer) {
195530d68baSNigel Croxon         FreePool (*Buffer);
196530d68baSNigel Croxon         *Buffer = NULL;
197530d68baSNigel Croxon     }
198530d68baSNigel Croxon 
199530d68baSNigel Croxon     return TryAgain;
200530d68baSNigel Croxon }
201530d68baSNigel Croxon 
202530d68baSNigel Croxon 
203530d68baSNigel Croxon EFI_MEMORY_DESCRIPTOR *
204530d68baSNigel Croxon LibMemoryMap (
205530d68baSNigel Croxon     OUT UINTN               *NoEntries,
206530d68baSNigel Croxon     OUT UINTN               *MapKey,
207530d68baSNigel Croxon     OUT UINTN               *DescriptorSize,
208530d68baSNigel Croxon     OUT UINT32              *DescriptorVersion
209530d68baSNigel Croxon     )
210530d68baSNigel Croxon {
211530d68baSNigel Croxon     EFI_STATUS              Status;
212530d68baSNigel Croxon     EFI_MEMORY_DESCRIPTOR   *Buffer;
213530d68baSNigel Croxon     UINTN                   BufferSize;
214530d68baSNigel Croxon 
215530d68baSNigel Croxon     //
216530d68baSNigel Croxon     // Initialize for GrowBuffer loop
217530d68baSNigel Croxon     //
218530d68baSNigel Croxon 
219530d68baSNigel Croxon     Status = EFI_SUCCESS;
220530d68baSNigel Croxon     Buffer = NULL;
221530d68baSNigel Croxon     BufferSize = sizeof(EFI_MEMORY_DESCRIPTOR);
222530d68baSNigel Croxon 
223530d68baSNigel Croxon     //
224530d68baSNigel Croxon     // Call the real function
225530d68baSNigel Croxon     //
226530d68baSNigel Croxon 
227530d68baSNigel Croxon     while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
228530d68baSNigel Croxon         Status = uefi_call_wrapper(BS->GetMemoryMap, 5, &BufferSize, Buffer, MapKey, DescriptorSize, DescriptorVersion);
229530d68baSNigel Croxon     }
230530d68baSNigel Croxon 
231530d68baSNigel Croxon     //
232530d68baSNigel Croxon     // Convert buffer size to NoEntries
233530d68baSNigel Croxon     //
234530d68baSNigel Croxon 
235530d68baSNigel Croxon     if (!EFI_ERROR(Status)) {
236530d68baSNigel Croxon         *NoEntries = BufferSize / *DescriptorSize;
237530d68baSNigel Croxon     }
238530d68baSNigel Croxon 
239530d68baSNigel Croxon     return Buffer;
240530d68baSNigel Croxon }
241530d68baSNigel Croxon 
242530d68baSNigel Croxon VOID *
243530d68baSNigel Croxon LibGetVariableAndSize (
244530d68baSNigel Croxon     IN CHAR16               *Name,
245530d68baSNigel Croxon     IN EFI_GUID             *VendorGuid,
246530d68baSNigel Croxon     OUT UINTN               *VarSize
247530d68baSNigel Croxon     )
248530d68baSNigel Croxon {
249*dfdcd7efSHeinrich Schuchardt     EFI_STATUS              Status = EFI_SUCCESS;
250530d68baSNigel Croxon     VOID                    *Buffer;
251530d68baSNigel Croxon     UINTN                   BufferSize;
252530d68baSNigel Croxon 
253530d68baSNigel Croxon     //
254530d68baSNigel Croxon     // Initialize for GrowBuffer loop
255530d68baSNigel Croxon     //
256530d68baSNigel Croxon 
257530d68baSNigel Croxon     Buffer = NULL;
258530d68baSNigel Croxon     BufferSize = 100;
259530d68baSNigel Croxon 
260530d68baSNigel Croxon     //
261530d68baSNigel Croxon     // Call the real function
262530d68baSNigel Croxon     //
263530d68baSNigel Croxon 
264530d68baSNigel Croxon     while (GrowBuffer (&Status, &Buffer, BufferSize)) {
265530d68baSNigel Croxon         Status = uefi_call_wrapper(
266530d68baSNigel Croxon 		    RT->GetVariable,
267530d68baSNigel Croxon 			5,
268530d68baSNigel Croxon                     Name,
269530d68baSNigel Croxon                     VendorGuid,
270530d68baSNigel Croxon                     NULL,
271530d68baSNigel Croxon                     &BufferSize,
272530d68baSNigel Croxon                     Buffer
273530d68baSNigel Croxon                     );
274530d68baSNigel Croxon     }
275530d68baSNigel Croxon     if (Buffer) {
276530d68baSNigel Croxon         *VarSize = BufferSize;
277530d68baSNigel Croxon     } else {
278530d68baSNigel Croxon         *VarSize = 0;
279530d68baSNigel Croxon     }
280530d68baSNigel Croxon     return Buffer;
281530d68baSNigel Croxon }
282530d68baSNigel Croxon 
283530d68baSNigel Croxon VOID *
284530d68baSNigel Croxon LibGetVariable (
285530d68baSNigel Croxon     IN CHAR16               *Name,
286530d68baSNigel Croxon     IN EFI_GUID             *VendorGuid
287530d68baSNigel Croxon     )
288530d68baSNigel Croxon {
289530d68baSNigel Croxon     UINTN   VarSize;
290530d68baSNigel Croxon 
291530d68baSNigel Croxon     return LibGetVariableAndSize (Name, VendorGuid, &VarSize);
292530d68baSNigel Croxon }
293530d68baSNigel Croxon 
294530d68baSNigel Croxon EFI_STATUS
295530d68baSNigel Croxon LibDeleteVariable (
296530d68baSNigel Croxon     IN CHAR16   *VarName,
297530d68baSNigel Croxon     IN EFI_GUID *VarGuid
298530d68baSNigel Croxon     )
299530d68baSNigel Croxon {
300530d68baSNigel Croxon     VOID        *VarBuf;
301530d68baSNigel Croxon     EFI_STATUS  Status;
302530d68baSNigel Croxon 
303530d68baSNigel Croxon     VarBuf = LibGetVariable(VarName,VarGuid);
304530d68baSNigel Croxon 
305530d68baSNigel Croxon     Status = EFI_NOT_FOUND;
306530d68baSNigel Croxon 
307530d68baSNigel Croxon     if (VarBuf) {
308530d68baSNigel Croxon         //
309530d68baSNigel Croxon         // Delete variable from Storage
310530d68baSNigel Croxon         //
311530d68baSNigel Croxon         Status = uefi_call_wrapper(
312530d68baSNigel Croxon 		    RT->SetVariable,
313530d68baSNigel Croxon 			5,
314530d68baSNigel Croxon                     VarName, VarGuid,
315530d68baSNigel Croxon                     EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
316530d68baSNigel Croxon                     0, NULL
317530d68baSNigel Croxon                  );
318530d68baSNigel Croxon         ASSERT (!EFI_ERROR(Status));
319530d68baSNigel Croxon         FreePool(VarBuf);
320530d68baSNigel Croxon     }
321530d68baSNigel Croxon 
322530d68baSNigel Croxon     return (Status);
323530d68baSNigel Croxon }
324530d68baSNigel Croxon 
325530d68baSNigel Croxon EFI_STATUS
326530d68baSNigel Croxon LibSetNVVariable (
327530d68baSNigel Croxon     IN CHAR16   *VarName,
328530d68baSNigel Croxon     IN EFI_GUID *VarGuid,
329530d68baSNigel Croxon     IN UINTN	 DataSize,
330530d68baSNigel Croxon     IN VOID     *Data
331530d68baSNigel Croxon     )
332530d68baSNigel Croxon {
333530d68baSNigel Croxon     EFI_STATUS  Status;
334530d68baSNigel Croxon 
335530d68baSNigel Croxon     Status = uefi_call_wrapper(
336530d68baSNigel Croxon 	    RT->SetVariable,
337530d68baSNigel Croxon 	    5,
338530d68baSNigel Croxon 	    VarName, VarGuid,
339530d68baSNigel Croxon 	    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
340530d68baSNigel Croxon 	    DataSize, Data
341530d68baSNigel Croxon 	    );
342530d68baSNigel Croxon     ASSERT (!EFI_ERROR(Status));
343530d68baSNigel Croxon     return (Status);
344530d68baSNigel Croxon }
345530d68baSNigel Croxon 
346530d68baSNigel Croxon EFI_STATUS
347530d68baSNigel Croxon LibSetVariable (
348530d68baSNigel Croxon     IN CHAR16   *VarName,
349530d68baSNigel Croxon     IN EFI_GUID *VarGuid,
350530d68baSNigel Croxon     IN UINTN	 DataSize,
351530d68baSNigel Croxon     IN VOID     *Data
352530d68baSNigel Croxon     )
353530d68baSNigel Croxon {
354530d68baSNigel Croxon     EFI_STATUS  Status;
355530d68baSNigel Croxon 
356530d68baSNigel Croxon     Status = uefi_call_wrapper(
357530d68baSNigel Croxon 	    RT->SetVariable,
358530d68baSNigel Croxon 	    5,
359530d68baSNigel Croxon 	    VarName, VarGuid,
360530d68baSNigel Croxon 	    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
361530d68baSNigel Croxon 	    DataSize, Data
362530d68baSNigel Croxon 	    );
363530d68baSNigel Croxon     ASSERT (!EFI_ERROR(Status));
364530d68baSNigel Croxon     return (Status);
365530d68baSNigel Croxon }
366530d68baSNigel Croxon 
367530d68baSNigel Croxon EFI_STATUS
368530d68baSNigel Croxon LibInsertToTailOfBootOrder (
369530d68baSNigel Croxon     IN  UINT16  BootOption,
370530d68baSNigel Croxon     IN  BOOLEAN OnlyInsertIfEmpty
371530d68baSNigel Croxon     )
372530d68baSNigel Croxon {
373530d68baSNigel Croxon     UINT16      *BootOptionArray;
374530d68baSNigel Croxon     UINT16      *NewBootOptionArray;
375530d68baSNigel Croxon     UINTN       VarSize;
376530d68baSNigel Croxon     UINTN       Index;
377530d68baSNigel Croxon     EFI_STATUS  Status;
378530d68baSNigel Croxon 
379530d68baSNigel Croxon     BootOptionArray = LibGetVariableAndSize (VarBootOrder, &EfiGlobalVariable, &VarSize);
380530d68baSNigel Croxon     if (VarSize != 0 && OnlyInsertIfEmpty) {
381530d68baSNigel Croxon         if (BootOptionArray) {
382530d68baSNigel Croxon             FreePool (BootOptionArray);
383530d68baSNigel Croxon         }
384530d68baSNigel Croxon         return EFI_UNSUPPORTED;
385530d68baSNigel Croxon     }
386530d68baSNigel Croxon 
387530d68baSNigel Croxon     VarSize += sizeof(UINT16);
388530d68baSNigel Croxon     NewBootOptionArray = AllocatePool (VarSize);
389530d68baSNigel Croxon 
390530d68baSNigel Croxon     for (Index = 0; Index < ((VarSize/sizeof(UINT16)) - 1); Index++) {
391530d68baSNigel Croxon         NewBootOptionArray[Index] = BootOptionArray[Index];
392530d68baSNigel Croxon     }
393530d68baSNigel Croxon     //
394530d68baSNigel Croxon     // Insert in the tail of the array
395530d68baSNigel Croxon     //
396530d68baSNigel Croxon     NewBootOptionArray[Index] = BootOption;
397530d68baSNigel Croxon 
398530d68baSNigel Croxon     Status = uefi_call_wrapper(
399530d68baSNigel Croxon 		RT->SetVariable,
400530d68baSNigel Croxon 		5,
401530d68baSNigel Croxon                 VarBootOrder, &EfiGlobalVariable,
402530d68baSNigel Croxon                 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
403530d68baSNigel Croxon                 VarSize, (VOID*) NewBootOptionArray
404530d68baSNigel Croxon                 );
405530d68baSNigel Croxon 
406530d68baSNigel Croxon     if (NewBootOptionArray) {
407530d68baSNigel Croxon         FreePool (NewBootOptionArray);
408530d68baSNigel Croxon     }
409530d68baSNigel Croxon     if (BootOptionArray) {
410530d68baSNigel Croxon         FreePool (BootOptionArray);
411530d68baSNigel Croxon     }
412530d68baSNigel Croxon     return Status;
413530d68baSNigel Croxon }
414530d68baSNigel Croxon 
415530d68baSNigel Croxon 
416530d68baSNigel Croxon BOOLEAN
417530d68baSNigel Croxon ValidMBR(
418530d68baSNigel Croxon     IN  MASTER_BOOT_RECORD  *Mbr,
419530d68baSNigel Croxon     IN  EFI_BLOCK_IO        *BlkIo
420530d68baSNigel Croxon     )
421530d68baSNigel Croxon {
422530d68baSNigel Croxon     UINT32      StartingLBA, EndingLBA;
423530d68baSNigel Croxon     UINT32      NewEndingLBA;
424530d68baSNigel Croxon     INTN        i, j;
425530d68baSNigel Croxon     BOOLEAN     ValidMbr;
426530d68baSNigel Croxon 
427530d68baSNigel Croxon     if (Mbr->Signature != MBR_SIGNATURE) {
428530d68baSNigel Croxon         //
429530d68baSNigel Croxon         // The BPB also has this signature, so it can not be used alone.
430530d68baSNigel Croxon         //
431530d68baSNigel Croxon         return FALSE;
432530d68baSNigel Croxon     }
433530d68baSNigel Croxon 
434530d68baSNigel Croxon     ValidMbr = FALSE;
435530d68baSNigel Croxon     for (i=0; i<MAX_MBR_PARTITIONS; i++) {
436530d68baSNigel Croxon         if ( Mbr->Partition[i].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) == 0 ) {
437530d68baSNigel Croxon             continue;
438530d68baSNigel Croxon         }
439530d68baSNigel Croxon         ValidMbr = TRUE;
440530d68baSNigel Croxon         StartingLBA = EXTRACT_UINT32(Mbr->Partition[i].StartingLBA);
441530d68baSNigel Croxon         EndingLBA = StartingLBA + EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) - 1;
442530d68baSNigel Croxon         if (EndingLBA > BlkIo->Media->LastBlock) {
443530d68baSNigel Croxon             //
444530d68baSNigel Croxon             // Compatability Errata:
445530d68baSNigel Croxon             //  Some systems try to hide drive space with thier INT 13h driver
446530d68baSNigel Croxon             //  This does not hide space from the OS driver. This means the MBR
447530d68baSNigel Croxon             //  that gets created from DOS is smaller than the MBR created from
448530d68baSNigel Croxon             //  a real OS (NT & Win98). This leads to BlkIo->LastBlock being
449530d68baSNigel Croxon             //  wrong on some systems FDISKed by the OS.
450530d68baSNigel Croxon             //
451530d68baSNigel Croxon             //
452530d68baSNigel Croxon             if (BlkIo->Media->LastBlock < MIN_MBR_DEVICE_SIZE) {
453530d68baSNigel Croxon                 //
454530d68baSNigel Croxon                 // If this is a very small device then trust the BlkIo->LastBlock
455530d68baSNigel Croxon                 //
456530d68baSNigel Croxon                 return FALSE;
457530d68baSNigel Croxon             }
458530d68baSNigel Croxon 
459530d68baSNigel Croxon             if (EndingLBA > (BlkIo->Media->LastBlock + MBR_ERRATA_PAD)) {
460530d68baSNigel Croxon                 return FALSE;
461530d68baSNigel Croxon             }
462530d68baSNigel Croxon 
463530d68baSNigel Croxon         }
464530d68baSNigel Croxon         for (j=i+1; j<MAX_MBR_PARTITIONS; j++) {
465530d68baSNigel Croxon             if (Mbr->Partition[j].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) == 0) {
466530d68baSNigel Croxon                 continue;
467530d68baSNigel Croxon             }
468530d68baSNigel Croxon             if (   EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) >= StartingLBA &&
469530d68baSNigel Croxon                    EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) <= EndingLBA       ) {
470530d68baSNigel Croxon                 //
471530d68baSNigel Croxon                 // The Start of this region overlaps with the i'th region
472530d68baSNigel Croxon                 //
473530d68baSNigel Croxon                 return FALSE;
474530d68baSNigel Croxon             }
475530d68baSNigel Croxon             NewEndingLBA = EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) + EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) - 1;
476530d68baSNigel Croxon             if ( NewEndingLBA >= StartingLBA && NewEndingLBA <= EndingLBA ) {
477530d68baSNigel Croxon                 //
478530d68baSNigel Croxon                 // The End of this region overlaps with the i'th region
479530d68baSNigel Croxon                 //
480530d68baSNigel Croxon                 return FALSE;
481530d68baSNigel Croxon             }
482530d68baSNigel Croxon         }
483530d68baSNigel Croxon     }
484530d68baSNigel Croxon     //
485530d68baSNigel Croxon     // Non of the regions overlapped so MBR is O.K.
486530d68baSNigel Croxon     //
487530d68baSNigel Croxon     return ValidMbr;
488530d68baSNigel Croxon }
489530d68baSNigel Croxon 
490530d68baSNigel Croxon 
491530d68baSNigel Croxon UINT8
492530d68baSNigel Croxon DecimaltoBCD(
493530d68baSNigel Croxon     IN  UINT8 DecValue
494530d68baSNigel Croxon     )
495530d68baSNigel Croxon {
496530d68baSNigel Croxon     return RtDecimaltoBCD (DecValue);
497530d68baSNigel Croxon }
498530d68baSNigel Croxon 
499530d68baSNigel Croxon 
500530d68baSNigel Croxon UINT8
501530d68baSNigel Croxon BCDtoDecimal(
502530d68baSNigel Croxon     IN  UINT8 BcdValue
503530d68baSNigel Croxon     )
504530d68baSNigel Croxon {
505530d68baSNigel Croxon     return RtBCDtoDecimal (BcdValue);
506530d68baSNigel Croxon }
507530d68baSNigel Croxon 
508530d68baSNigel Croxon EFI_STATUS
509530d68baSNigel Croxon LibGetSystemConfigurationTable(
510530d68baSNigel Croxon     IN EFI_GUID *TableGuid,
511530d68baSNigel Croxon     IN OUT VOID **Table
512530d68baSNigel Croxon     )
513530d68baSNigel Croxon 
514530d68baSNigel Croxon {
515530d68baSNigel Croxon     UINTN Index;
516530d68baSNigel Croxon 
517530d68baSNigel Croxon     for(Index=0;Index<ST->NumberOfTableEntries;Index++) {
518530d68baSNigel Croxon         if (CompareGuid(TableGuid,&(ST->ConfigurationTable[Index].VendorGuid))==0) {
519530d68baSNigel Croxon             *Table = ST->ConfigurationTable[Index].VendorTable;
520530d68baSNigel Croxon             return EFI_SUCCESS;
521530d68baSNigel Croxon         }
522530d68baSNigel Croxon     }
523530d68baSNigel Croxon     return EFI_NOT_FOUND;
524530d68baSNigel Croxon }
525530d68baSNigel Croxon 
526530d68baSNigel Croxon 
527530d68baSNigel Croxon CHAR16 *
528530d68baSNigel Croxon LibGetUiString (
529530d68baSNigel Croxon     IN  EFI_HANDLE      Handle,
530530d68baSNigel Croxon     IN  UI_STRING_TYPE  StringType,
531530d68baSNigel Croxon     IN  ISO_639_2       *LangCode,
532530d68baSNigel Croxon     IN  BOOLEAN         ReturnDevicePathStrOnMismatch
533530d68baSNigel Croxon     )
534530d68baSNigel Croxon {
535530d68baSNigel Croxon     UI_INTERFACE    *Ui;
536530d68baSNigel Croxon     UI_STRING_TYPE  Index;
537530d68baSNigel Croxon     UI_STRING_ENTRY *Array;
538530d68baSNigel Croxon     EFI_STATUS      Status;
539530d68baSNigel Croxon 
540530d68baSNigel Croxon     Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &UiProtocol, (VOID *)&Ui);
541530d68baSNigel Croxon     if (EFI_ERROR(Status)) {
542530d68baSNigel Croxon         return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
543530d68baSNigel Croxon     }
544530d68baSNigel Croxon 
545530d68baSNigel Croxon     //
546530d68baSNigel Croxon     // Skip the first strings
547530d68baSNigel Croxon     //
548530d68baSNigel Croxon     for (Index = UiDeviceString, Array = Ui->Entry; Index < StringType; Index++, Array++) {
549530d68baSNigel Croxon         while (Array->LangCode) {
550530d68baSNigel Croxon             Array++;
551530d68baSNigel Croxon         }
552530d68baSNigel Croxon     }
553530d68baSNigel Croxon 
554530d68baSNigel Croxon     //
555530d68baSNigel Croxon     // Search for the match
556530d68baSNigel Croxon     //
557530d68baSNigel Croxon     while (Array->LangCode) {
558530d68baSNigel Croxon         if (strcmpa (Array->LangCode, LangCode) == 0) {
559530d68baSNigel Croxon             return Array->UiString;
560530d68baSNigel Croxon         }
561530d68baSNigel Croxon     }
562530d68baSNigel Croxon     return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
563530d68baSNigel Croxon }
564