Subversion Repositories HelenOS

Rev

Rev 2726 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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