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