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 * 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 * 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 * 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 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 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 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 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 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 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 * 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 * 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 * 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 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 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 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 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 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 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 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 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 * 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