VirtualBox

Ignore:
Timestamp:
Mar 12, 2019 12:40:12 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129295
Message:

EFI: First step in UDK2018 merge. Does not build yet.

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

Legend:

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

  • trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/CpuDxe/CpuDxe.c

    r58459 r77662  
    11/** @file
    2   CPU DXE Module.
    3 
    4   Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
     2  CPU DXE Module to produce CPU ARCH Protocol.
     3
     4  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1414
    1515#include "CpuDxe.h"
     16#include "CpuMp.h"
     17#include "CpuPageTable.h"
     18
     19#define CACHE_ATTRIBUTE_MASK   (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP)
     20#define MEMORY_ATTRIBUTE_MASK  (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO)
    1621
    1722//
     
    2126EFI_HANDLE                mCpuHandle = NULL;
    2227BOOLEAN                   mIsFlushingGCD;
    23 UINT64                    mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
    24 UINT64                    mValidMtrrBitsMask    = MTRR_LIB_MSR_VALID_MASK;
     28BOOLEAN                   mIsAllocatingPageTable = FALSE;
     29UINT64                    mValidMtrrAddressMask;
     30UINT64                    mValidMtrrBitsMask;
     31UINT64                    mTimerPeriod = 0;
    2532
    2633FIXED_MTRR    mFixedMtrrTable[] = {
    2734  {
    28     MTRR_LIB_IA32_MTRR_FIX64K_00000,
     35    MSR_IA32_MTRR_FIX64K_00000,
    2936    0,
    3037    0x10000
    3138  },
    3239  {
    33     MTRR_LIB_IA32_MTRR_FIX16K_80000,
     40    MSR_IA32_MTRR_FIX16K_80000,
    3441    0x80000,
    3542    0x4000
    3643  },
    3744  {
    38     MTRR_LIB_IA32_MTRR_FIX16K_A0000,
     45    MSR_IA32_MTRR_FIX16K_A0000,
    3946    0xA0000,
    4047    0x4000
    4148  },
    4249  {
    43     MTRR_LIB_IA32_MTRR_FIX4K_C0000,
     50    MSR_IA32_MTRR_FIX4K_C0000,
    4451    0xC0000,
    4552    0x1000
    4653  },
    4754  {
    48     MTRR_LIB_IA32_MTRR_FIX4K_C8000,
     55    MSR_IA32_MTRR_FIX4K_C8000,
    4956    0xC8000,
    5057    0x1000
    5158  },
    5259  {
    53     MTRR_LIB_IA32_MTRR_FIX4K_D0000,
     60    MSR_IA32_MTRR_FIX4K_D0000,
    5461    0xD0000,
    5562    0x1000
    5663  },
    5764  {
    58     MTRR_LIB_IA32_MTRR_FIX4K_D8000,
     65    MSR_IA32_MTRR_FIX4K_D8000,
    5966    0xD8000,
    6067    0x1000
    6168  },
    6269  {
    63     MTRR_LIB_IA32_MTRR_FIX4K_E0000,
     70    MSR_IA32_MTRR_FIX4K_E0000,
    6471    0xE0000,
    6572    0x1000
    6673  },
    6774  {
    68     MTRR_LIB_IA32_MTRR_FIX4K_E8000,
     75    MSR_IA32_MTRR_FIX4K_E8000,
    6976    0xE8000,
    7077    0x1000
    7178  },
    7279  {
    73     MTRR_LIB_IA32_MTRR_FIX4K_F0000,
     80    MSR_IA32_MTRR_FIX4K_F0000,
    7481    0xF0000,
    7582    0x1000
    7683  },
    7784  {
    78     MTRR_LIB_IA32_MTRR_FIX4K_F8000,
     85    MSR_IA32_MTRR_FIX4K_F8000,
    7986    0xF8000,
    8087    0x1000
     
    293300  )
    294301{
     302  UINT64          BeginValue;
     303  UINT64          EndValue;
     304
    295305  if (TimerValue == NULL) {
    296306    return EFI_INVALID_PARAMETER;
     
    304314
    305315  if (TimerPeriod != NULL) {
     316    if (mTimerPeriod == 0) {
    306317      //
    307       // BugBug: Hard coded. Don't know how to do this generically
     318      // Read time stamp counter before and after delay of 100 microseconds
    308319      //
    309       *TimerPeriod = 1000000000;
     320      BeginValue = AsmReadTsc ();
     321      MicroSecondDelay (100);
     322      EndValue   = AsmReadTsc ();
     323      //
     324      // Calculate the actual frequency
     325      //
     326      mTimerPeriod = DivU64x64Remainder (
     327                       MultU64x32 (
     328                         1000 * 1000 * 1000,
     329                         100
     330                         ),
     331                       EndValue - BeginValue,
     332                       NULL
     333                       );
     334    }
     335    *TimerPeriod = mTimerPeriod;
    310336  }
    311337
     
    313339}
    314340
     341/**
     342  A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to
     343  EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure.
     344
     345  @param[in] Buffer  Pointer to an MTRR_SETTINGS object, to be passed to
     346                     MtrrSetAllMtrrs().
     347**/
     348VOID
     349EFIAPI
     350SetMtrrsFromBuffer (
     351  IN VOID *Buffer
     352  )
     353{
     354  MtrrSetAllMtrrs (Buffer);
     355}
    315356
    316357/**
     
    350391  RETURN_STATUS             Status;
    351392  MTRR_MEMORY_CACHE_TYPE    CacheType;
    352 
    353   if (!IsMtrrSupported ()) {
    354     return EFI_UNSUPPORTED;
    355   }
     393  EFI_STATUS                MpStatus;
     394  EFI_MP_SERVICES_PROTOCOL  *MpService;
     395  MTRR_SETTINGS             MtrrSettings;
     396  UINT64                    CacheAttributes;
     397  UINT64                    MemoryAttributes;
     398  MTRR_MEMORY_CACHE_TYPE    CurrentCacheType;
    356399
    357400  //
     
    362405  //
    363406  if (mIsFlushingGCD) {
    364     DEBUG((EFI_D_INFO, "  Flushing GCD\n"));
     407    DEBUG((DEBUG_INFO, "  Flushing GCD\n"));
    365408    return EFI_SUCCESS;
    366409  }
    367410
    368   switch (Attributes) {
    369   case EFI_MEMORY_UC:
    370     CacheType = CacheUncacheable;
    371     break;
    372 
    373   case EFI_MEMORY_WC:
    374     CacheType = CacheWriteCombining;
    375     break;
    376 
    377   case EFI_MEMORY_WT:
    378     CacheType = CacheWriteThrough;
    379     break;
    380 
    381   case EFI_MEMORY_WP:
    382     CacheType = CacheWriteProtected;
    383     break;
    384 
    385   case EFI_MEMORY_WB:
    386     CacheType = CacheWriteBack;
    387     break;
    388 
    389   case EFI_MEMORY_UCE:
    390   case EFI_MEMORY_RP:
    391   case EFI_MEMORY_XP:
    392   case EFI_MEMORY_RUNTIME:
    393     return EFI_UNSUPPORTED;
    394 
    395   default:
     411  //
     412  // During memory attributes updating, new pages may be allocated to setup
     413  // smaller granularity of page table. Page allocation action might then cause
     414  // another calling of CpuSetMemoryAttributes() recursively, due to memory
     415  // protection policy configured (such as PcdDxeNxMemoryProtectionPolicy).
     416  // Since this driver will always protect memory used as page table by itself,
     417  // there's no need to apply protection policy requested from memory service.
     418  // So it's safe to just return EFI_SUCCESS if this time of calling is caused
     419  // by page table memory allocation.
     420  //
     421  if (mIsAllocatingPageTable) {
     422    DEBUG((DEBUG_VERBOSE, "  Allocating page table memory\n"));
     423    return EFI_SUCCESS;
     424  }
     425
     426  CacheAttributes = Attributes & CACHE_ATTRIBUTE_MASK;
     427  MemoryAttributes = Attributes & MEMORY_ATTRIBUTE_MASK;
     428
     429  if (Attributes != (CacheAttributes | MemoryAttributes)) {
    396430    return EFI_INVALID_PARAMETER;
    397431  }
    398   //
    399   // call MTRR libary function
    400   //
    401   Status = MtrrSetMemoryAttribute (
    402              BaseAddress,
    403              Length,
    404              CacheType
    405              );
    406 
    407   return (EFI_STATUS) Status;
     432
     433  if (CacheAttributes != 0) {
     434    if (!IsMtrrSupported ()) {
     435      return EFI_UNSUPPORTED;
     436    }
     437
     438    switch (CacheAttributes) {
     439    case EFI_MEMORY_UC:
     440      CacheType = CacheUncacheable;
     441      break;
     442
     443    case EFI_MEMORY_WC:
     444      CacheType = CacheWriteCombining;
     445      break;
     446
     447    case EFI_MEMORY_WT:
     448      CacheType = CacheWriteThrough;
     449      break;
     450
     451    case EFI_MEMORY_WP:
     452      CacheType = CacheWriteProtected;
     453      break;
     454
     455    case EFI_MEMORY_WB:
     456      CacheType = CacheWriteBack;
     457      break;
     458
     459    default:
     460      return EFI_INVALID_PARAMETER;
     461    }
     462    CurrentCacheType = MtrrGetMemoryAttribute(BaseAddress);
     463    if (CurrentCacheType != CacheType) {
     464      //
     465      // call MTRR libary function
     466      //
     467      Status = MtrrSetMemoryAttribute (
     468                 BaseAddress,
     469                 Length,
     470                 CacheType
     471                 );
     472
     473      if (!RETURN_ERROR (Status)) {
     474        MpStatus = gBS->LocateProtocol (
     475                          &gEfiMpServiceProtocolGuid,
     476                          NULL,
     477                          (VOID **)&MpService
     478                          );
     479        //
     480        // Synchronize the update with all APs
     481        //
     482        if (!EFI_ERROR (MpStatus)) {
     483          MtrrGetAllMtrrs (&MtrrSettings);
     484          MpStatus = MpService->StartupAllAPs (
     485                                  MpService,          // This
     486                                  SetMtrrsFromBuffer, // Procedure
     487                                  FALSE,              // SingleThread
     488                                  NULL,               // WaitEvent
     489                                  0,                  // TimeoutInMicrosecsond
     490                                  &MtrrSettings,      // ProcedureArgument
     491                                  NULL                // FailedCpuList
     492                                  );
     493          ASSERT (MpStatus == EFI_SUCCESS || MpStatus == EFI_NOT_STARTED);
     494        }
     495      }
     496      if (EFI_ERROR(Status)) {
     497        return Status;
     498      }
     499    }
     500  }
     501
     502  //
     503  // Set memory attribute by page table
     504  //
     505  return AssignMemoryPageAttributes (NULL, BaseAddress, Length, MemoryAttributes, NULL);
    408506}
    409507
     
    428526
    429527    PhysicalAddressBits = (UINT8) RegEax;
    430 
    431     mValidMtrrBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;
    432     mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL;
    433528  } else {
    434     mValidMtrrBitsMask    = MTRR_LIB_MSR_VALID_MASK;
    435     mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
    436   }
     529    PhysicalAddressBits = 36;
     530  }
     531
     532  mValidMtrrBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;
     533  mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL;
    437534}
    438535
     
    602699**/
    603700VOID
    604 RefreshGcdMemoryAttributes (
     701RefreshMemoryAttributesFromMtrr (
    605702  VOID
    606703  )
     
    623720  UINT8                               DefaultMemoryType;
    624721
    625   if (!IsMtrrSupported ()) {
    626     return;
    627   }
    628 
    629722  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();
    630723  ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
    631724
    632   mIsFlushingGCD = TRUE;
    633725  MemorySpaceMap = NULL;
    634726
     
    781873    FreePool (MemorySpaceMap);
    782874  }
     875}
     876
     877/**
     878 Check if paging is enabled or not.
     879**/
     880BOOLEAN
     881IsPagingAndPageAddressExtensionsEnabled (
     882  VOID
     883  )
     884{
     885  IA32_CR0  Cr0;
     886  IA32_CR4  Cr4;
     887
     888  Cr0.UintN = AsmReadCr0 ();
     889  Cr4.UintN = AsmReadCr4 ();
     890
     891  return ((Cr0.Bits.PG != 0) && (Cr4.Bits.PAE != 0));
     892}
     893
     894/**
     895  Refreshes the GCD Memory Space attributes according to MTRRs and Paging.
     896
     897  This function refreshes the GCD Memory Space attributes according to MTRRs
     898  and page tables.
     899
     900**/
     901VOID
     902RefreshGcdMemoryAttributes (
     903  VOID
     904  )
     905{
     906  mIsFlushingGCD = TRUE;
     907
     908  if (IsMtrrSupported ()) {
     909    RefreshMemoryAttributesFromMtrr ();
     910  }
     911
     912  if (IsPagingAndPageAddressExtensionsEnabled ()) {
     913    RefreshGcdMemoryAttributesFromPaging ();
     914  }
    783915
    784916  mIsFlushingGCD = FALSE;
     
    826958}
    827959
     960/**
     961  Ensure the compatibility of a memory space descriptor with the MMIO aperture.
     962
     963  The memory space descriptor can come from the GCD memory space map, or it can
     964  represent a gap between two neighboring memory space descriptors. In the
     965  latter case, the GcdMemoryType field is expected to be
     966  EfiGcdMemoryTypeNonExistent.
     967
     968  If the memory space descriptor already has type
     969  EfiGcdMemoryTypeMemoryMappedIo, and its capabilities are a superset of the
     970  required capabilities, then no action is taken -- it is by definition
     971  compatible with the aperture.
     972
     973  Otherwise, the intersection of the memory space descriptor is calculated with
     974  the aperture. If the intersection is the empty set (no overlap), no action is
     975  taken; the memory space descriptor is compatible with the aperture.
     976
     977  Otherwise, the type of the descriptor is investigated again. If the type is
     978  EfiGcdMemoryTypeNonExistent (representing a gap, or a genuine descriptor with
     979  such a type), then an attempt is made to add the intersection as MMIO space
     980  to the GCD memory space map, with the specified capabilities. This ensures
     981  continuity for the aperture, and the descriptor is deemed compatible with the
     982  aperture.
     983
     984  Otherwise, the memory space descriptor is incompatible with the MMIO
     985  aperture.
     986
     987  @param[in] Base         Base address of the aperture.
     988  @param[in] Length       Length of the aperture.
     989  @param[in] Capabilities Capabilities required by the aperture.
     990  @param[in] Descriptor   The descriptor to ensure compatibility with the
     991                          aperture for.
     992
     993  @retval EFI_SUCCESS            The descriptor is compatible. The GCD memory
     994                                 space map may have been updated, for
     995                                 continuity within the aperture.
     996  @retval EFI_INVALID_PARAMETER  The descriptor is incompatible.
     997  @return                        Error codes from gDS->AddMemorySpace().
     998**/
     999EFI_STATUS
     1000IntersectMemoryDescriptor (
     1001  IN  UINT64                                Base,
     1002  IN  UINT64                                Length,
     1003  IN  UINT64                                Capabilities,
     1004  IN  CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor
     1005  )
     1006{
     1007  UINT64                                    IntersectionBase;
     1008  UINT64                                    IntersectionEnd;
     1009  EFI_STATUS                                Status;
     1010
     1011  if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo &&
     1012      (Descriptor->Capabilities & Capabilities) == Capabilities) {
     1013    return EFI_SUCCESS;
     1014  }
     1015
     1016  IntersectionBase = MAX (Base, Descriptor->BaseAddress);
     1017  IntersectionEnd = MIN (Base + Length,
     1018                      Descriptor->BaseAddress + Descriptor->Length);
     1019  if (IntersectionBase >= IntersectionEnd) {
     1020    //
     1021    // The descriptor and the aperture don't overlap.
     1022    //
     1023    return EFI_SUCCESS;
     1024  }
     1025
     1026  if (Descriptor->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
     1027    Status = gDS->AddMemorySpace (EfiGcdMemoryTypeMemoryMappedIo,
     1028                    IntersectionBase, IntersectionEnd - IntersectionBase,
     1029                    Capabilities);
     1030
     1031    DEBUG ((EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
     1032      "%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__,
     1033      IntersectionBase, IntersectionEnd, Status));
     1034    return Status;
     1035  }
     1036
     1037  DEBUG ((DEBUG_ERROR, "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts "
     1038    "with aperture [%Lx, %Lx) cap %Lx\n", gEfiCallerBaseName, __FUNCTION__,
     1039    Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length,
     1040    (UINT32)Descriptor->GcdMemoryType, Descriptor->Capabilities,
     1041    Base, Base + Length, Capabilities));
     1042  return EFI_INVALID_PARAMETER;
     1043}
     1044
     1045/**
     1046  Add MMIO space to GCD.
     1047  The routine checks the GCD database and only adds those which are
     1048  not added in the specified range to GCD.
     1049
     1050  @param Base         Base address of the MMIO space.
     1051  @param Length       Length of the MMIO space.
     1052  @param Capabilities Capabilities of the MMIO space.
     1053
     1054  @retval EFI_SUCCES The MMIO space was added successfully.
     1055**/
     1056EFI_STATUS
     1057AddMemoryMappedIoSpace (
     1058  IN  UINT64                            Base,
     1059  IN  UINT64                            Length,
     1060  IN  UINT64                            Capabilities
     1061  )
     1062{
     1063  EFI_STATUS                            Status;
     1064  UINTN                                 Index;
     1065  UINTN                                 NumberOfDescriptors;
     1066  EFI_GCD_MEMORY_SPACE_DESCRIPTOR       *MemorySpaceMap;
     1067
     1068  Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
     1069  if (EFI_ERROR (Status)) {
     1070    DEBUG ((DEBUG_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n",
     1071      gEfiCallerBaseName, __FUNCTION__, Status));
     1072    return Status;
     1073  }
     1074
     1075  for (Index = 0; Index < NumberOfDescriptors; Index++) {
     1076    Status = IntersectMemoryDescriptor (Base, Length, Capabilities,
     1077               &MemorySpaceMap[Index]);
     1078    if (EFI_ERROR (Status)) {
     1079      goto FreeMemorySpaceMap;
     1080    }
     1081  }
     1082
     1083  DEBUG_CODE (
     1084    //
     1085    // Make sure there are adjacent descriptors covering [Base, Base + Length).
     1086    // It is possible that they have not been merged; merging can be prevented
     1087    // by allocation and different capabilities.
     1088    //
     1089    UINT64                          CheckBase;
     1090    EFI_STATUS                      CheckStatus;
     1091    EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
     1092
     1093    for (CheckBase = Base;
     1094         CheckBase < Base + Length;
     1095         CheckBase = Descriptor.BaseAddress + Descriptor.Length) {
     1096      CheckStatus = gDS->GetMemorySpaceDescriptor (CheckBase, &Descriptor);
     1097      ASSERT_EFI_ERROR (CheckStatus);
     1098      ASSERT (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo);
     1099      ASSERT ((Descriptor.Capabilities & Capabilities) == Capabilities);
     1100    }
     1101    );
     1102
     1103FreeMemorySpaceMap:
     1104  FreePool (MemorySpaceMap);
     1105
     1106  return Status;
     1107}
     1108
     1109/**
     1110  Add and allocate CPU local APIC memory mapped space.
     1111
     1112  @param[in]ImageHandle     Image handle this driver.
     1113
     1114**/
     1115VOID
     1116AddLocalApicMemorySpace (
     1117  IN EFI_HANDLE               ImageHandle
     1118  )
     1119{
     1120  EFI_STATUS              Status;
     1121  EFI_PHYSICAL_ADDRESS    BaseAddress;
     1122
     1123  BaseAddress = (EFI_PHYSICAL_ADDRESS) GetLocalApicBaseAddress();
     1124  Status = AddMemoryMappedIoSpace (BaseAddress, SIZE_4KB, EFI_MEMORY_UC);
     1125  ASSERT_EFI_ERROR (Status);
     1126
     1127  //
     1128  // Try to allocate APIC memory mapped space, does not check return
     1129  // status because it may be allocated by other driver, or DXE Core if
     1130  // this range is built into Memory Allocation HOB.
     1131  //
     1132  Status = gDS->AllocateMemorySpace (
     1133                  EfiGcdAllocateAddress,
     1134                  EfiGcdMemoryTypeMemoryMappedIo,
     1135                  0,
     1136                  SIZE_4KB,
     1137                  &BaseAddress,
     1138                  ImageHandle,
     1139                  NULL
     1140                  );
     1141  if (EFI_ERROR (Status)) {
     1142    DEBUG ((DEBUG_INFO, "%a: %a: AllocateMemorySpace() Status - %r\n",
     1143                         gEfiCallerBaseName, __FUNCTION__, Status));
     1144  }
     1145}
    8281146
    8291147/**
     
    8481166  EFI_EVENT   IdleLoopEvent;
    8491167
     1168  InitializePageTableLib();
     1169
    8501170  InitializeFloatingPointUnits ();
    8511171
     
    8641184  //
    8651185  InitInterruptDescriptorTable ();
    866 
    867   //
    868   // Enable the local APIC for Virtual Wire Mode.
    869   //
    870   ProgramVirtualWireMode ();
    8711186
    8721187  //
     
    8841199  //
    8851200  RefreshGcdMemoryAttributes ();
     1201
     1202  //
     1203  // Add and allocate local APIC memory mapped space
     1204  //
     1205  AddLocalApicMemorySpace (ImageHandle);
    8861206
    8871207  //
     
    8981218  ASSERT_EFI_ERROR (Status);
    8991219
     1220  InitializeMpSupport ();
     1221
    9001222  return Status;
    9011223}
Note: See TracChangeset for help on using the changeset viewer.

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