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 *
AllocatePool(IN UINTN Size)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 *
AllocateZeroPool(IN UINTN Size)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 *
ReallocatePool(IN VOID * OldPool,IN UINTN OldSize,IN UINTN NewSize)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
FreePool(IN VOID * Buffer)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
ZeroMem(IN VOID * Buffer,IN UINTN Size)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
101*deb8a7f2SPeter Jones VOID EFIAPI
SetMem(IN VOID * Buffer,IN UINTN Size,IN UINT8 Value)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
111*deb8a7f2SPeter Jones VOID EFIAPI
CopyMem(IN VOID * Dest,IN VOID * Src,IN UINTN len)112530d68baSNigel Croxon CopyMem (
113530d68baSNigel Croxon IN VOID *Dest,
114*deb8a7f2SPeter Jones IN VOID *Src,
115530d68baSNigel Croxon IN UINTN len
116530d68baSNigel Croxon )
117530d68baSNigel Croxon {
118530d68baSNigel Croxon RtCopyMem (Dest, Src, len);
119530d68baSNigel Croxon }
120530d68baSNigel Croxon
121530d68baSNigel Croxon INTN
CompareMem(IN CONST VOID * Dest,IN CONST VOID * Src,IN UINTN len)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
GrowBuffer(IN OUT EFI_STATUS * Status,IN OUT VOID ** Buffer,IN UINTN BufferSize)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 *
LibMemoryMap(OUT UINTN * NoEntries,OUT UINTN * MapKey,OUT UINTN * DescriptorSize,OUT UINT32 * DescriptorVersion)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 *
LibGetVariableAndSize(IN CHAR16 * Name,IN EFI_GUID * VendorGuid,OUT UINTN * VarSize)243530d68baSNigel Croxon LibGetVariableAndSize (
244530d68baSNigel Croxon IN CHAR16 *Name,
245530d68baSNigel Croxon IN EFI_GUID *VendorGuid,
246530d68baSNigel Croxon OUT UINTN *VarSize
247530d68baSNigel Croxon )
248530d68baSNigel Croxon {
249dfdcd7efSHeinrich 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 *
LibGetVariable(IN CHAR16 * Name,IN EFI_GUID * VendorGuid)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
LibDeleteVariable(IN CHAR16 * VarName,IN EFI_GUID * VarGuid)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
LibSetNVVariable(IN CHAR16 * VarName,IN EFI_GUID * VarGuid,IN UINTN DataSize,IN VOID * Data)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
LibSetVariable(IN CHAR16 * VarName,IN EFI_GUID * VarGuid,IN UINTN DataSize,IN VOID * Data)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
LibInsertToTailOfBootOrder(IN UINT16 BootOption,IN BOOLEAN OnlyInsertIfEmpty)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);
389500c10f1SHeinrich Schuchardt if (!NewBootOptionArray)
390500c10f1SHeinrich Schuchardt return EFI_OUT_OF_RESOURCES;
391530d68baSNigel Croxon
392530d68baSNigel Croxon for (Index = 0; Index < ((VarSize/sizeof(UINT16)) - 1); Index++) {
393530d68baSNigel Croxon NewBootOptionArray[Index] = BootOptionArray[Index];
394530d68baSNigel Croxon }
395530d68baSNigel Croxon //
396530d68baSNigel Croxon // Insert in the tail of the array
397530d68baSNigel Croxon //
398530d68baSNigel Croxon NewBootOptionArray[Index] = BootOption;
399530d68baSNigel Croxon
400530d68baSNigel Croxon Status = uefi_call_wrapper(
401530d68baSNigel Croxon RT->SetVariable,
402530d68baSNigel Croxon 5,
403530d68baSNigel Croxon VarBootOrder, &EfiGlobalVariable,
404530d68baSNigel Croxon EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
405530d68baSNigel Croxon VarSize, (VOID*) NewBootOptionArray
406530d68baSNigel Croxon );
407530d68baSNigel Croxon
408530d68baSNigel Croxon FreePool (NewBootOptionArray);
409530d68baSNigel Croxon if (BootOptionArray) {
410530d68baSNigel Croxon FreePool (BootOptionArray);
411530d68baSNigel Croxon }
412530d68baSNigel Croxon return Status;
413530d68baSNigel Croxon }
414530d68baSNigel Croxon
415530d68baSNigel Croxon
416530d68baSNigel Croxon BOOLEAN
ValidMBR(IN MASTER_BOOT_RECORD * Mbr,IN EFI_BLOCK_IO * BlkIo)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
DecimaltoBCD(IN UINT8 DecValue)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
BCDtoDecimal(IN UINT8 BcdValue)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
LibGetSystemConfigurationTable(IN EFI_GUID * TableGuid,IN OUT VOID ** Table)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 *
LibGetUiString(IN EFI_HANDLE Handle,IN UI_STRING_TYPE StringType,IN ISO_639_2 * LangCode,IN BOOLEAN ReturnDevicePathStrOnMismatch)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