Home | History | Annotate | Line # | Download | only in lib
misc.c revision 1.1.1.1.36.1
      1 /*	$NetBSD: misc.c,v 1.1.1.1.36.1 2019/06/10 22:08:36 christos 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 CONST VOID     *Src,
    117     IN UINTN    len
    118     )
    119 {
    120     RtCopyMem (Dest, Src, len);
    121 }
    122 
    123 INTN
    124 CompareMem (
    125     IN CONST VOID     *Dest,
    126     IN CONST 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     Status = EFI_SUCCESS;
    222     Buffer = NULL;
    223     BufferSize = sizeof(EFI_MEMORY_DESCRIPTOR);
    224 
    225     //
    226     // Call the real function
    227     //
    228 
    229     while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {
    230         Status = uefi_call_wrapper(BS->GetMemoryMap, 5, &BufferSize, Buffer, MapKey, DescriptorSize, DescriptorVersion);
    231     }
    232 
    233     //
    234     // Convert buffer size to NoEntries
    235     //
    236 
    237     if (!EFI_ERROR(Status)) {
    238         *NoEntries = BufferSize / *DescriptorSize;
    239     }
    240 
    241     return Buffer;
    242 }
    243 
    244 VOID *
    245 LibGetVariableAndSize (
    246     IN CHAR16               *Name,
    247     IN EFI_GUID             *VendorGuid,
    248     OUT UINTN               *VarSize
    249     )
    250 {
    251     EFI_STATUS              Status;
    252     VOID                    *Buffer;
    253     UINTN                   BufferSize;
    254 
    255     //
    256     // Initialize for GrowBuffer loop
    257     //
    258 
    259     Buffer = NULL;
    260     BufferSize = 100;
    261 
    262     //
    263     // Call the real function
    264     //
    265 
    266     while (GrowBuffer (&Status, &Buffer, BufferSize)) {
    267         Status = uefi_call_wrapper(
    268 		    RT->GetVariable,
    269 			5,
    270                     Name,
    271                     VendorGuid,
    272                     NULL,
    273                     &BufferSize,
    274                     Buffer
    275                     );
    276     }
    277     if (Buffer) {
    278         *VarSize = BufferSize;
    279     } else {
    280         *VarSize = 0;
    281     }
    282     return Buffer;
    283 }
    284 
    285 VOID *
    286 LibGetVariable (
    287     IN CHAR16               *Name,
    288     IN EFI_GUID             *VendorGuid
    289     )
    290 {
    291     UINTN   VarSize;
    292 
    293     return LibGetVariableAndSize (Name, VendorGuid, &VarSize);
    294 }
    295 
    296 EFI_STATUS
    297 LibDeleteVariable (
    298     IN CHAR16   *VarName,
    299     IN EFI_GUID *VarGuid
    300     )
    301 {
    302     VOID        *VarBuf;
    303     EFI_STATUS  Status;
    304 
    305     VarBuf = LibGetVariable(VarName,VarGuid);
    306 
    307     Status = EFI_NOT_FOUND;
    308 
    309     if (VarBuf) {
    310         //
    311         // Delete variable from Storage
    312         //
    313         Status = uefi_call_wrapper(
    314 		    RT->SetVariable,
    315 			5,
    316                     VarName, VarGuid,
    317                     EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
    318                     0, NULL
    319                  );
    320         ASSERT (!EFI_ERROR(Status));
    321         FreePool(VarBuf);
    322     }
    323 
    324     return (Status);
    325 }
    326 
    327 EFI_STATUS
    328 LibSetNVVariable (
    329     IN CHAR16   *VarName,
    330     IN EFI_GUID *VarGuid,
    331     IN UINTN	 DataSize,
    332     IN VOID     *Data
    333     )
    334 {
    335     EFI_STATUS  Status;
    336 
    337     Status = uefi_call_wrapper(
    338 	    RT->SetVariable,
    339 	    5,
    340 	    VarName, VarGuid,
    341 	    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
    342 	    DataSize, Data
    343 	    );
    344     ASSERT (!EFI_ERROR(Status));
    345     return (Status);
    346 }
    347 
    348 EFI_STATUS
    349 LibSetVariable (
    350     IN CHAR16   *VarName,
    351     IN EFI_GUID *VarGuid,
    352     IN UINTN	 DataSize,
    353     IN VOID     *Data
    354     )
    355 {
    356     EFI_STATUS  Status;
    357 
    358     Status = uefi_call_wrapper(
    359 	    RT->SetVariable,
    360 	    5,
    361 	    VarName, VarGuid,
    362 	    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    363 	    DataSize, Data
    364 	    );
    365     ASSERT (!EFI_ERROR(Status));
    366     return (Status);
    367 }
    368 
    369 EFI_STATUS
    370 LibInsertToTailOfBootOrder (
    371     IN  UINT16  BootOption,
    372     IN  BOOLEAN OnlyInsertIfEmpty
    373     )
    374 {
    375     UINT16      *BootOptionArray;
    376     UINT16      *NewBootOptionArray;
    377     UINTN       VarSize;
    378     UINTN       Index;
    379     EFI_STATUS  Status;
    380 
    381     BootOptionArray = LibGetVariableAndSize (VarBootOrder, &EfiGlobalVariable, &VarSize);
    382     if (VarSize != 0 && OnlyInsertIfEmpty) {
    383         if (BootOptionArray) {
    384             FreePool (BootOptionArray);
    385         }
    386         return EFI_UNSUPPORTED;
    387     }
    388 
    389     VarSize += sizeof(UINT16);
    390     NewBootOptionArray = AllocatePool (VarSize);
    391 
    392     for (Index = 0; Index < ((VarSize/sizeof(UINT16)) - 1); Index++) {
    393         NewBootOptionArray[Index] = BootOptionArray[Index];
    394     }
    395     //
    396     // Insert in the tail of the array
    397     //
    398     NewBootOptionArray[Index] = BootOption;
    399 
    400     Status = uefi_call_wrapper(
    401 		RT->SetVariable,
    402 		5,
    403                 VarBootOrder, &EfiGlobalVariable,
    404                 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
    405                 VarSize, (VOID*) NewBootOptionArray
    406                 );
    407 
    408     if (NewBootOptionArray) {
    409         FreePool (NewBootOptionArray);
    410     }
    411     if (BootOptionArray) {
    412         FreePool (BootOptionArray);
    413     }
    414     return Status;
    415 }
    416 
    417 
    418 BOOLEAN
    419 ValidMBR(
    420     IN  MASTER_BOOT_RECORD  *Mbr,
    421     IN  EFI_BLOCK_IO        *BlkIo
    422     )
    423 {
    424     UINT32      StartingLBA, EndingLBA;
    425     UINT32      NewEndingLBA;
    426     INTN        i, j;
    427     BOOLEAN     ValidMbr;
    428 
    429     if (Mbr->Signature != MBR_SIGNATURE) {
    430         //
    431         // The BPB also has this signature, so it can not be used alone.
    432         //
    433         return FALSE;
    434     }
    435 
    436     ValidMbr = FALSE;
    437     for (i=0; i<MAX_MBR_PARTITIONS; i++) {
    438         if ( Mbr->Partition[i].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) == 0 ) {
    439             continue;
    440         }
    441         ValidMbr = TRUE;
    442         StartingLBA = EXTRACT_UINT32(Mbr->Partition[i].StartingLBA);
    443         EndingLBA = StartingLBA + EXTRACT_UINT32(Mbr->Partition[i].SizeInLBA) - 1;
    444         if (EndingLBA > BlkIo->Media->LastBlock) {
    445             //
    446             // Compatability Errata:
    447             //  Some systems try to hide drive space with thier INT 13h driver
    448             //  This does not hide space from the OS driver. This means the MBR
    449             //  that gets created from DOS is smaller than the MBR created from
    450             //  a real OS (NT & Win98). This leads to BlkIo->LastBlock being
    451             //  wrong on some systems FDISKed by the OS.
    452             //
    453             //
    454             if (BlkIo->Media->LastBlock < MIN_MBR_DEVICE_SIZE) {
    455                 //
    456                 // If this is a very small device then trust the BlkIo->LastBlock
    457                 //
    458                 return FALSE;
    459             }
    460 
    461             if (EndingLBA > (BlkIo->Media->LastBlock + MBR_ERRATA_PAD)) {
    462                 return FALSE;
    463             }
    464 
    465         }
    466         for (j=i+1; j<MAX_MBR_PARTITIONS; j++) {
    467             if (Mbr->Partition[j].OSIndicator == 0x00 || EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) == 0) {
    468                 continue;
    469             }
    470             if (   EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) >= StartingLBA &&
    471                    EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) <= EndingLBA       ) {
    472                 //
    473                 // The Start of this region overlaps with the i'th region
    474                 //
    475                 return FALSE;
    476             }
    477             NewEndingLBA = EXTRACT_UINT32(Mbr->Partition[j].StartingLBA) + EXTRACT_UINT32(Mbr->Partition[j].SizeInLBA) - 1;
    478             if ( NewEndingLBA >= StartingLBA && NewEndingLBA <= EndingLBA ) {
    479                 //
    480                 // The End of this region overlaps with the i'th region
    481                 //
    482                 return FALSE;
    483             }
    484         }
    485     }
    486     //
    487     // Non of the regions overlapped so MBR is O.K.
    488     //
    489     return ValidMbr;
    490 }
    491 
    492 
    493 UINT8
    494 DecimaltoBCD(
    495     IN  UINT8 DecValue
    496     )
    497 {
    498     return RtDecimaltoBCD (DecValue);
    499 }
    500 
    501 
    502 UINT8
    503 BCDtoDecimal(
    504     IN  UINT8 BcdValue
    505     )
    506 {
    507     return RtBCDtoDecimal (BcdValue);
    508 }
    509 
    510 EFI_STATUS
    511 LibGetSystemConfigurationTable(
    512     IN EFI_GUID *TableGuid,
    513     IN OUT VOID **Table
    514     )
    515 
    516 {
    517     UINTN Index;
    518 
    519     for(Index=0;Index<ST->NumberOfTableEntries;Index++) {
    520         if (CompareGuid(TableGuid,&(ST->ConfigurationTable[Index].VendorGuid))==0) {
    521             *Table = ST->ConfigurationTable[Index].VendorTable;
    522             return EFI_SUCCESS;
    523         }
    524     }
    525     return EFI_NOT_FOUND;
    526 }
    527 
    528 
    529 CHAR16 *
    530 LibGetUiString (
    531     IN  EFI_HANDLE      Handle,
    532     IN  UI_STRING_TYPE  StringType,
    533     IN  ISO_639_2       *LangCode,
    534     IN  BOOLEAN         ReturnDevicePathStrOnMismatch
    535     )
    536 {
    537     UI_INTERFACE    *Ui;
    538     UI_STRING_TYPE  Index;
    539     UI_STRING_ENTRY *Array;
    540     EFI_STATUS      Status;
    541 
    542     Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &UiProtocol, (VOID *)&Ui);
    543     if (EFI_ERROR(Status)) {
    544         return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
    545     }
    546 
    547     //
    548     // Skip the first strings
    549     //
    550     for (Index = UiDeviceString, Array = Ui->Entry; Index < StringType; Index++, Array++) {
    551         while (Array->LangCode) {
    552             Array++;
    553         }
    554     }
    555 
    556     //
    557     // Search for the match
    558     //
    559     while (Array->LangCode) {
    560         if (strcmpa (Array->LangCode, LangCode) == 0) {
    561             return Array->UiString;
    562         }
    563     }
    564     return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL;
    565 }
    566