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