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