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