VirtualBox

Ignore:
Timestamp:
Oct 28, 2015 8:17:18 PM (9 years ago)
Author:
vboxsync
Message:

EFI/Firmware: 'svn merge /vendor/edk2/UDK2010.SR1 /vendor/edk2/current .', reverting and removing files+dirs listed in ReadMe.vbox, resolving conflicts with help from ../UDK2014.SP1/. This is a raw untested merge.

Location:
trunk/src/VBox/Devices/EFI/Firmware
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/Firmware

  • trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/CapsuleRuntimeDxe/X64/SaveLongModeContext.c

    r48674 r58459  
    33  for transferring into long mode in IA32 capsule PEI.
    44
    5 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
     5Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
    66This program and the accompanying materials
    77are licensed and made available under the terms and conditions of the BSD License
     
    1818#include <Protocol/Capsule.h>
    1919#include <Protocol/DxeSmmReadyToLock.h>
     20#include <Protocol/VariableLock.h>
    2021
    2122#include <Guid/CapsuleVendor.h>
     
    2829#include <Library/UefiRuntimeLib.h>
    2930#include <Library/BaseLib.h>
    30 #include <Library/LockBoxLib.h>
    3131#include <Library/UefiLib.h>
    3232#include <Library/BaseMemoryLib.h>
     
    3434
    3535/**
    36   Allocate EfiACPIMemoryNVS below 4G memory address.
    37 
    38   This function allocates EfiACPIMemoryNVS below 4G memory address.
    39 
    40   @param  Size         Size of memory to allocate.
    41  
    42   @return Allocated address for output.
     36  Allocate EfiReservedMemoryType below 4G memory address.
     37
     38  This function allocates EfiReservedMemoryType below 4G memory address.
     39
     40  @param  Size      Size of memory to allocate.
     41 
     42  @return Allocated Address for output.
    4343
    4444**/
    4545VOID*
    46 AllocateAcpiNvsMemoryBelow4G (
     46AllocateReservedMemoryBelow4G (
    4747  IN   UINTN   Size
    4848  )
     
    5858  Status  = gBS->AllocatePages (
    5959                   AllocateMaxAddress,
    60                    EfiACPIMemoryNVS,
     60                   EfiReservedMemoryType,
    6161                   Pages,
    6262                   &Address
     
    7171
    7272/**
    73   DxeSmmReadyToLock Protocol notification event handler.
    74   We reuse S3 ACPI NVS reserved memory to do capsule process
    75   after reset.
     73  Register callback function upon VariableLockProtocol
     74  to lock EFI_CAPSULE_LONG_MODE_BUFFER_NAME variable to avoid malicious code to update it.
    7675
    7776  @param[in] Event    Event whose notification function is being invoked.
     
    8079VOID
    8180EFIAPI
    82 DxeSmmReadyToLockNotification (
    83   IN EFI_EVENT  Event,
    84   IN VOID       *Context
     81VariableLockCapsuleLongModeBufferVariable (
     82  IN  EFI_EVENT                             Event,
     83  IN  VOID                                  *Context
    8584  )
    8685{
    8786  EFI_STATUS                    Status;
    88   VOID                          *DxeSmmReadyToLock;
    89   UINTN                         VarSize;
    90   EFI_PHYSICAL_ADDRESS          TempAcpiS3Context;
    91   ACPI_S3_CONTEXT               *AcpiS3Context;
    92   EFI_CAPSULE_LONG_MODE_BUFFER  LongModeBuffer;
    93   UINTN                         TotalPagesNum;
    94   UINT8                         PhysicalAddressBits;
    95   VOID                          *Hob;
    96   UINT32                        NumberOfPml4EntriesNeeded;
    97   UINT32                        NumberOfPdpEntriesNeeded;
    98   BOOLEAN                       LockBoxFound;
    99 
    100   Status = gBS->LocateProtocol (
    101                   &gEfiDxeSmmReadyToLockProtocolGuid,
    102                   NULL,
    103                   &DxeSmmReadyToLock
    104                   );
    105   if (EFI_ERROR (Status)) {
    106     return ;
    107   }
    108 
    109   //
    110   // Get the ACPI NVS pages reserved by AcpiS3Save
    111   //
    112   LockBoxFound = FALSE;
    113   VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
    114   Status = RestoreLockBox (
    115              &gEfiAcpiVariableGuid,
    116              &TempAcpiS3Context,
    117              &VarSize
    118              );
     87  EDKII_VARIABLE_LOCK_PROTOCOL  *VariableLock;
     88  //
     89  // Mark EFI_CAPSULE_LONG_MODE_BUFFER_NAME variable to read-only if the Variable Lock protocol exists
     90  //
     91  Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);
    11992  if (!EFI_ERROR (Status)) {
    120     AcpiS3Context = (ACPI_S3_CONTEXT *)(UINTN)TempAcpiS3Context;
    121     ASSERT (AcpiS3Context != NULL);
    122    
    123     Status = RestoreLockBox (
    124                &gEfiAcpiS3ContextGuid,
    125                NULL,
    126                NULL
    127                );
    128     if (!EFI_ERROR (Status)) {
    129       LongModeBuffer.PageTableAddress = AcpiS3Context->S3NvsPageTableAddress;
    130       LongModeBuffer.StackBaseAddress = AcpiS3Context->BootScriptStackBase;
    131       LongModeBuffer.StackSize        = AcpiS3Context->BootScriptStackSize;
    132       LockBoxFound                    = TRUE;
    133     }
    134   }
    135  
    136   if (!LockBoxFound) {
    137     //
    138     // Page table base address and stack base address can not be found in lock box,
    139     // allocate both here.
    140     //
    141 
    142     //
    143     // Get physical address bits supported from CPU HOB.
    144     //
    145     PhysicalAddressBits = 36;
    146    
     93    Status = VariableLock->RequestToLock (VariableLock, EFI_CAPSULE_LONG_MODE_BUFFER_NAME, &gEfiCapsuleVendorGuid);
     94    ASSERT_EFI_ERROR (Status);
     95  }
     96}
     97
     98/**
     99  1. Allocate Reserved memory for capsule PEIM to establish a 1:1 Virtual to Physical mapping.
     100  2. Allocate Reserved memroy as a stack for capsule PEIM to transfer from 32-bit mdoe to 64-bit mode.
     101
     102**/
     103VOID
     104EFIAPI
     105PrepareContextForCapsulePei (
     106  VOID
     107  )
     108{
     109  UINT32                                        RegEax;
     110  UINT32                                        RegEdx;
     111  UINTN                                         TotalPagesNum;
     112  UINT8                                         PhysicalAddressBits;
     113  VOID                                          *Hob;
     114  UINT32                                        NumberOfPml4EntriesNeeded;
     115  UINT32                                        NumberOfPdpEntriesNeeded;
     116  BOOLEAN                                       Page1GSupport;
     117  EFI_CAPSULE_LONG_MODE_BUFFER                  LongModeBuffer;
     118  EFI_STATUS                                    Status;
     119  VOID                                          *Registration;
     120 
     121  LongModeBuffer.PageTableAddress = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdIdentifyMappingPageTablePtr);
     122
     123  if (LongModeBuffer.PageTableAddress == 0x0) {
     124    //
     125    // Calculate the size of page table, allocate the memory, and set PcdIdentifyMappingPageTablePtr.
     126    //
     127    Page1GSupport = FALSE;
     128    if (PcdGetBool(PcdUse1GPageTable)) {
     129      AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
     130      if (RegEax >= 0x80000001) {
     131        AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
     132        if ((RegEdx & BIT26) != 0) {
     133          Page1GSupport = TRUE;
     134        }
     135      }
     136    }
     137   
     138    //
     139    // Get physical address bits supported.
     140    //
    147141    Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
    148142    if (Hob != NULL) {
    149143      PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;
     144    } else {
     145      AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
     146      if (RegEax >= 0x80000008) {
     147        AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
     148        PhysicalAddressBits = (UINT8) RegEax;
     149      } else {
     150        PhysicalAddressBits = 36;
     151      }
    150152    }
    151153   
     
    159161   
    160162    //
    161     // Calculate page table size and allocate memory for it.
     163    // Calculate the table entries needed.
    162164    //
    163165    if (PhysicalAddressBits <= 39 ) {
    164166      NumberOfPml4EntriesNeeded = 1;
    165       NumberOfPdpEntriesNeeded =  1 << (PhysicalAddressBits - 30);
     167      NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
    166168    } else {
    167       NumberOfPml4EntriesNeeded = 1 << (PhysicalAddressBits - 39);
     169      NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
    168170      NumberOfPdpEntriesNeeded = 512;
    169171    }
    170172   
    171     TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
    172     LongModeBuffer.PageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateAcpiNvsMemoryBelow4G (EFI_PAGES_TO_SIZE (TotalPagesNum));
     173    if (!Page1GSupport) {
     174      TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
     175    } else {
     176      TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
     177    }
     178   
     179    LongModeBuffer.PageTableAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedMemoryBelow4G (EFI_PAGES_TO_SIZE (TotalPagesNum));
    173180    ASSERT (LongModeBuffer.PageTableAddress != 0);
    174    
    175     //
    176     // Allocate stack
    177     //
    178     LongModeBuffer.StackSize        = PcdGet32 (PcdCapsulePeiLongModeStackSize);
    179     LongModeBuffer.StackBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateAcpiNvsMemoryBelow4G (PcdGet32 (PcdCapsulePeiLongModeStackSize));
    180     ASSERT (LongModeBuffer.StackBaseAddress != 0);
    181   }
    182 
     181    PcdSet64 (PcdIdentifyMappingPageTablePtr, LongModeBuffer.PageTableAddress);
     182  }
     183 
     184  //
     185  // Allocate stack
     186  //
     187  LongModeBuffer.StackSize        = PcdGet32 (PcdCapsulePeiLongModeStackSize);
     188  LongModeBuffer.StackBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateReservedMemoryBelow4G (PcdGet32 (PcdCapsulePeiLongModeStackSize));
     189  ASSERT (LongModeBuffer.StackBaseAddress != 0); 
     190 
    183191  Status = gRT->SetVariable (
    184192                  EFI_CAPSULE_LONG_MODE_BUFFER_NAME,
    185193                  &gEfiCapsuleVendorGuid,
    186                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
     194                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
    187195                  sizeof (EFI_CAPSULE_LONG_MODE_BUFFER),
    188196                  &LongModeBuffer
    189197                  );
    190   ASSERT_EFI_ERROR (Status);
    191 
    192   //
    193   // Close event, so it will not be invoked again.
    194   //
    195   gBS->CloseEvent (Event);
    196 
    197   return ;
     198  if (!EFI_ERROR (Status)) {
     199      //
     200      // Register callback function upon VariableLockProtocol
     201      // to lock EFI_CAPSULE_LONG_MODE_BUFFER_NAME variable to avoid malicious code to update it.
     202      //
     203      EfiCreateProtocolNotifyEvent (
     204        &gEdkiiVariableLockProtocolGuid,
     205        TPL_CALLBACK,
     206        VariableLockCapsuleLongModeBufferVariable,
     207        NULL,
     208        &Registration
     209        );   
     210  } else {
     211      DEBUG ((EFI_D_ERROR, "FATAL ERROR: CapsuleLongModeBuffer cannot be saved: %r. Capsule in PEI may fail!\n", Status));
     212      gBS->FreePages (LongModeBuffer.StackBaseAddress, EFI_SIZE_TO_PAGES (LongModeBuffer.StackSize));
     213  }
    198214}
    199215
     
    207223  )
    208224{
    209   VOID        *Registration;
    210  
    211225  if ((FeaturePcdGet(PcdSupportUpdateCapsuleReset)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
    212226    //
    213     // Register event to get ACPI NVS pages reserved from lock box, these pages will be used by
    214     // Capsule IA32 PEI to transfer to long mode to access capsule above 4GB.
    215     //
    216     EfiCreateProtocolNotifyEvent (
    217       &gEfiDxeSmmReadyToLockProtocolGuid,
    218       TPL_CALLBACK,
    219       DxeSmmReadyToLockNotification,
    220       NULL,
    221       &Registration
    222       );
    223   }
    224 }
     227    // Allocate memory for Capsule IA32 PEIM, it will create page table to transfer to long mode to access capsule above 4GB.
     228    //
     229    PrepareContextForCapsulePei ();
     230  }
     231}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette