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