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