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