1 1.3 jmcneill /* $NetBSD: misc.c,v 1.3 2021/09/30 19:02:48 jmcneill 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.3 jmcneill EFI_STATUS Status = EFI_SUCCESS; 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.3 jmcneill if (!NewBootOptionArray) 393 1.3 jmcneill return EFI_OUT_OF_RESOURCES; 394 1.3 jmcneill 395 1.1 jakllsch for (Index = 0; Index < ((VarSize/sizeof(UINT16)) - 1); Index++) { 396 1.1 jakllsch NewBootOptionArray[Index] = BootOptionArray[Index]; 397 1.1 jakllsch } 398 1.1 jakllsch // 399 1.1 jakllsch // Insert in the tail of the array 400 1.1 jakllsch // 401 1.1 jakllsch NewBootOptionArray[Index] = BootOption; 402 1.1 jakllsch 403 1.1 jakllsch Status = uefi_call_wrapper( 404 1.1 jakllsch RT->SetVariable, 405 1.1 jakllsch 5, 406 1.1 jakllsch VarBootOrder, &EfiGlobalVariable, 407 1.1 jakllsch EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 408 1.1 jakllsch VarSize, (VOID*) NewBootOptionArray 409 1.1 jakllsch ); 410 1.1 jakllsch 411 1.3 jmcneill FreePool (NewBootOptionArray); 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