Esempio n. 1
0
UINT64
Power2MaxMemory (
  IN UINT64                     MemoryLength
  )
/*++

Routine Description:

  TODO: Add function description

Arguments:

  MemoryLength  - TODO: add argument description

Returns:

  TODO: add return values

--*/
{
  UINT64  Result;

  if (RShiftU64 (MemoryLength, 32)) {
    Result = LShiftU64 ((UINT64) SetPower2 ((UINT32) RShiftU64 (MemoryLength, 32)), 32);
  } else {
    Result = (UINT64) SetPower2 ((UINT32) MemoryLength);
  }

  return Result;
}
Esempio n. 2
0
/**
  Configure RootPort for downstream PCIe NAND devices.

  @param[in] RpBase             - PCIe configuration space address of this RootPort
  @param[in] BusNumber          - Bus number
  @param[in] MemoryBase         - Memory base address
  @param[in] MemoryLength       - Memory size

**/
VOID
ConfigureRootPortForPcieNand (
  IN UINTN   RpBase,
  IN UINTN   BusNumber,
  IN UINT32  MemoryBase,
  IN UINT32  MemoryLength
  )
{
  UINT32  MemoryLimit;

  DEBUG ((DEBUG_INFO, "ConfigureRootPortForPcieNand, BusNumber: %x, MemoryBase: %x, MemoryLength: %x\n",
    BusNumber, MemoryBase, MemoryLength));

  if (MemoryLength == 0) {
    MemoryLimit = MemoryBase;
  } else {
    MemoryLimit = MemoryBase + MemoryLength + 0xFFFFF; // 1M
  }

  ///
  /// Configue PCIE configuration space for RootPort
  ///
  PciWrite8  (RpBase + NVME_PCIE_BNUM + 1,  (UINT8) BusNumber);           // Secondary Bus Number registers
  PciWrite8  (RpBase + NVME_PCIE_BNUM + 2,  (UINT8) BusNumber);           // Subordinate Bus Number registers
  PciWrite8  (RpBase + NVME_PCIE_IOBL,      0xFF);                        // I/O Base registers
  PciWrite8  (RpBase + NVME_PCIE_IOBL + 1,  0x00);                        // I/O Limit registers
  PciWrite16 (RpBase + NVME_PCIE_MBL,       (UINT16) RShiftU64 ((UINTN)MemoryBase, 16));  // Memory Base register
  PciWrite16 (RpBase + NVME_PCIE_MBL + 2,   (UINT16) RShiftU64 ((UINTN)MemoryLimit, 16)); // Memory Limit register
  PciWrite16 (RpBase + NVME_PCIE_PMBL,      0xFFFF);                      // Prefetchable Memory Base registers
  PciWrite16 (RpBase + NVME_PCIE_PMBL + 2,  0x0000);                      // Prefetchable Memory Limit registers
  PciWrite32 (RpBase + NVME_PCIE_PMBU32,    0xFFFFFFFF);                  // Prefetchable Memory Upper Base registers
  PciWrite32 (RpBase + NVME_PCIE_PMLU32,    0x00000000);                  // Prefetchable Memory Upper Limit registers
}
Esempio n. 3
0
/**
  Set memory cache ability.

  @param    PageTable              PageTable Address
  @param    Address                Memory Address to change cache ability
  @param    Cacheability           Cache ability to set

**/
VOID
SetCacheability (
  IN      UINT64                    *PageTable,
  IN      UINTN                     Address,
  IN      UINT8                     Cacheability
  )
{
  UINTN   PTIndex;
  VOID    *NewPageTableAddress;
  UINT64  *NewPageTable;
  UINTN   Index;

  ASSERT ((Address & EFI_PAGE_MASK) == 0);

  if (sizeof (UINTN) == sizeof (UINT64)) {
    PTIndex = (UINTN)RShiftU64 (Address, 39) & 0x1ff;
    ASSERT (PageTable[PTIndex] & IA32_PG_P);
    PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
  }

  PTIndex = (UINTN)RShiftU64 (Address, 30) & 0x1ff;
  ASSERT (PageTable[PTIndex] & IA32_PG_P);
  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);

  //
  // A perfect implementation should check the original cacheability with the
  // one being set, and break a 2M page entry into pieces only when they
  // disagreed.
  //
  PTIndex = (UINTN)RShiftU64 (Address, 21) & 0x1ff;
  if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
    //
    // Allocate a page from SMRAM
    //
    NewPageTableAddress = AllocatePages (1);
    ASSERT (NewPageTableAddress != NULL);

    NewPageTable = (UINT64 *)NewPageTableAddress;

    for (Index = 0; Index < 0x200; Index++) {
      NewPageTable[Index] = PageTable[PTIndex];
      if ((NewPageTable[Index] & IA32_PG_PAT_2M) != 0) {
        NewPageTable[Index] &= ~((UINT64)IA32_PG_PAT_2M);
        NewPageTable[Index] |= (UINT64)IA32_PG_PAT_4K;
      }
      NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);
    }

    PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | IA32_PG_P;
  }

  ASSERT (PageTable[PTIndex] & IA32_PG_P);
  PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);

  PTIndex = (UINTN)RShiftU64 (Address, 12) & 0x1ff;
  ASSERT (PageTable[PTIndex] & IA32_PG_P);
  PageTable[PTIndex] &= ~((UINT64)((IA32_PG_PAT_4K | IA32_PG_CD | IA32_PG_WT)));
  PageTable[PTIndex] |= (UINT64)Cacheability;
}
Esempio n. 4
0
EFI_STATUS
EFIAPI    
PostPmInitCallBack (
  IN EFI_EVENT Event,
  IN VOID      *Context
  )
{
  UINT64      OriginalGTTMMADR;
  UINT32      LoGTBaseAddress;
  UINT32      HiGTBaseAddress;

  //
  // Enable Bus Master, I/O and Memory access on 0:2:0
  //
  PciOr8 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_CMD), (BIT2 | BIT1));

  //
  // only 32bit read/write is legal for device 0:2:0
  //
  OriginalGTTMMADR  = (UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR));
  OriginalGTTMMADR  = LShiftU64 ((UINT64) PciRead32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR + 4)), 32) | (OriginalGTTMMADR);

  //
  // 64bit GTTMADR does not work for S3 save script table since it is executed in PEIM phase
  // Program temporarily 32bits GTTMMADR for POST and S3 resume
  //
  LoGTBaseAddress                   = (UINT32) (GTTMMADR & 0xFFFFFFFF);
  HiGTBaseAddress                   = (UINT32) RShiftU64 ((GTTMMADR & 0xFFFFFFFF00000000), 32);
  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);



  //
  // Restore original GTTMMADR
  //
  LoGTBaseAddress                   = (UINT32) (OriginalGTTMMADR & 0xFFFFFFFF);
  HiGTBaseAddress                   = (UINT32) RShiftU64 ((OriginalGTTMMADR & 0xFFFFFFFF00000000), 32);

  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR), LoGTBaseAddress);
  S3PciWrite32(PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_GTTMMADR+4), HiGTBaseAddress);


  //
  // Lock the following registers, GGC, BDSM, BGSM
  //
  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_MGGC_OFFSET), LockBit);
  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_BSM_OFFSET), LockBit);
  PciOr32 (PCI_LIB_ADDRESS(0, IGD_DEV, 0,IGD_R_BGSM), LockBit);

  gBS->CloseEvent (Event);

  //
  // Return final status
  //
  return EFI_SUCCESS;
}
Esempio n. 5
0
EFI_RUNTIMESERVICE
EFI_STATUS
EFIAPI
MonotonicCounterDriverGetNextHighMonotonicCount (
  OUT UINT32  *HighCount
  )
/*++

Routine Description:

Arguments:

Returns:

--*/
{
  EFI_STATUS  Status;
  EFI_TPL     OldTpl;

  //
  // Check input parameters
  //
  if (HighCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!mEfiAtRuntime) {
    //
    // Use a lock if called before ExitBootServices()
    //
    OldTpl      = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
    *HighCount  = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;
    mEfiMtc     = LShiftU64 (*HighCount, 32);
    gBS->RestoreTPL (OldTpl);
  } else {
    *HighCount  = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;
    mEfiMtc     = LShiftU64 (*HighCount, 32);
  }
  //
  // Update the NvRam store to match the new high part
  //
  Status = gRT->SetVariable (
                  mEfiMtcName,
                  &mEfiMtcGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                  sizeof (UINT32),
                  HighCount
                  );

  return Status;
}
/**
  This is the standard EFI driver point that detects whether there is a
  MemoryConfigurationData Variable and, if so, reports memory configuration info
  to the DataHub.

  @param  ImageHandle  Handle for the image of this driver
  @param  SystemTable  Pointer to the EFI System Table

  @return EFI_SUCCESS if the data is successfully reported
  @return EFI_NOT_FOUND if the HOB list could not be located.

**/
EFI_STATUS
LogMemorySmbiosRecord (
  VOID
  )
{
  EFI_STATUS                      Status;
  UINT64                          TotalMemorySize;
  UINT8                           NumSlots;
  SMBIOS_TABLE_TYPE19             *Type19Record;
  EFI_SMBIOS_HANDLE               MemArrayMappedAddrSmbiosHandle;
  EFI_SMBIOS_PROTOCOL             *Smbios;
  CHAR16                          *MemString;

  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
  ASSERT_EFI_ERROR (Status);

  NumSlots        = 1;

  //
  // Process Memory String in form size!size ...
  // So 64!64 is 128 MB
  //
  MemString   = (CHAR16 *)PcdGetPtr (PcdEmuMemorySize);
  for (TotalMemorySize = 0; *MemString != '\0';) {
    TotalMemorySize += StrDecimalToUint64 (MemString);
    while (*MemString != '\0') {
      if (*MemString == '!') {
        MemString++;
        break;
      }
      MemString++;
    }
  }

  //
  // Convert Total Memory Size to based on KiloByte
  //
  TotalMemorySize = LShiftU64 (TotalMemorySize, 20);
  //
  // Generate Memory Array Mapped Address info
  //
  Type19Record = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE19) + 2);
  Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
  Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
  Type19Record->Hdr.Handle = 0;
  Type19Record->StartingAddress = 0;
  Type19Record->EndingAddress =  (UINT32)RShiftU64(TotalMemorySize, 10) - 1;
  Type19Record->MemoryArrayHandle = 0;
  Type19Record->PartitionWidth = (UINT8)(NumSlots);

  //
  // Generate Memory Array Mapped Address info (TYPE 19)
  //
  Status = AddSmbiosRecord (Smbios, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record);

  FreePool(Type19Record);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
Esempio n. 7
0
/**

  This function initialize host VMCS.

**/
VOID
InitHostVmcs (
  UINTN Index
  )
{
  UINT64  Data64;
  UINTN   Size;

  //
  // VMCS size
  //
  Data64 = AsmReadMsr64 (IA32_VMX_BASIC_MSR_INDEX);
  Size = (UINTN)(RShiftU64 (Data64, 32) & 0xFFFF);

  //
  // Allocate
  //
  mHostContextCommon.HostContextPerCpu[Index].Vmcs = (UINT64)(UINTN)AllocatePages (FRM_SIZE_TO_PAGES(Size));

  //
  // Set RevisionIdentifier
  //
  *(UINT32 *)(UINTN)mHostContextCommon.HostContextPerCpu[Index].Vmcs = (UINT32)Data64;

  return ;
}
Esempio n. 8
0
/**
  Converts a size, in bytes, to a number of EFI_PAGESs.

  NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.

  @param  Size      A size in bytes.

  @return  The number of EFI_PAGESs associated with the number of bytes specified
           by Size.

**/
STATIC
UINT64
EfiSizeToPages (
  IN UINT64 Size
  )
{
  return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);
}
Esempio n. 9
0
EFI_STATUS
EFIAPI
Stall (
  IN CONST EFI_PEI_SERVICES   **PeiServices,
  IN CONST EFI_PEI_STALL_PPI      *This,
  IN UINTN              Microseconds
  )
{
  UINTN   Ticks;
  UINTN   Counts;
  UINT32  CurrentTick;
  UINT32  OriginalTick;
  UINT32  RemainingTick;

  if (Microseconds == 0) {
    return EFI_SUCCESS;
  }

  OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);
  OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);
  CurrentTick = OriginalTick;

  //
  // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks
  //
  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;

  //
  // The loops needed for timer overflow
  //
  Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);

  //
  // Remaining clocks within one loop
  //
  RemainingTick = Ticks & 0xFFFFFF;

  //
  // Do not intend to use TMROF_STS bit of register PM1_STS, because this add extra
  // one I/O operation, and may generate SMI
  //
  while (Counts != 0) {
    CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
    if (CurrentTick <= OriginalTick) {
      Counts--;
    }
    OriginalTick = CurrentTick;
  }

  while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
    OriginalTick  = CurrentTick;
    CurrentTick   = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
  }

  return EFI_SUCCESS;
}
Esempio n. 10
0
/**
  Convert FV attrbiutes to FV2 attributes.

  @param Fv2Attributes FV2 attributes.

  @return FV attributes.

**/
FRAMEWORK_EFI_FV_ATTRIBUTES
Fv2AttributesToFvAttributes (
    IN  EFI_FV_ATTRIBUTES Fv2Attributes
)
{
    //
    // Clear those filed that is not defined in Framework FV spec and Alignment conversion.
    //
    return (Fv2Attributes & 0x1ff) | ((UINTN) EFI_FV_ALIGNMENT_2 << RShiftU64((Fv2Attributes & EFI_FV2_ALIGNMENT), 16));
}
Esempio n. 11
0
/**
  Get the PCI-E Address from a PCI address format 0x0000ssbbddffrrr
  where ss is SEGMENT, bb is BUS, dd is DEVICE, ff is FUNCTION
  and rrr is REGISTER (extension format for PCI-E).

  @param[in] InputAddress       PCI address format on input.
  @param[out]PciEAddress        PCI-E address extention format.
**/
VOID
EFIAPI
GetPciEAddressFromInputAddress (
  IN UINT64                 InputAddress,
  OUT UINT64                *PciEAddress
  )
{
  *PciEAddress = RShiftU64(InputAddress & ~(UINT64) 0xFFF, 4);
  *PciEAddress += LShiftU64((UINT16) InputAddress & 0x0FFF, 32);
}
Esempio n. 12
0
/**
  Calculate the maximum value which is a power of 2, but less the MemoryLength.

  @param  MemoryLength        The number to pass in.
  @return The maximum value which is align to power of 2 and less the MemoryLength

**/
UINT64
Power2MaxMemory (
  IN UINT64                     MemoryLength
  )
{
  UINT64  Result;

  if (RShiftU64 (MemoryLength, 32) != 0) {
    Result = LShiftU64 (
               (UINT64) GetPowerOfTwo32 (
                          (UINT32) RShiftU64 (MemoryLength, 32)
                          ),
               32
               );
  } else {
    Result = (UINT64) GetPowerOfTwo32 ((UINT32) MemoryLength);
  }

  return Result;
}
Esempio n. 13
0
/**
  Internal worker function to call the Metronome Architectural Protocol for 
  the number of ticks specified by the UINT64 Counter value.  WaitForTick() 
  service of the Metronome Architectural Protocol uses a UINT32 for the number
  of ticks to wait, so this function loops when Counter is larger than 0xffffffff.

  @param  Counter           Number of ticks to wait.

**/
VOID
CoreInternalWaitForTick (
  IN UINT64  Counter
  )
{
  while (RShiftU64 (Counter, 32) > 0) {
    gMetronome->WaitForTick (gMetronome, 0xffffffff);
    Counter -= 0xffffffff;
  }
  gMetronome->WaitForTick (gMetronome, (UINT32)Counter);
}
Esempio n. 14
0
/**
  Get microcode update signature of currently loaded microcode update.

  @return  Microcode signature.

**/
UINT32
GetCurrentMicrocodeSignature (
  VOID
  )
{
  UINT64 Signature;

  AsmWriteMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID, 0);
  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL);
  Signature = AsmReadMsr64 (EFI_MSR_IA32_BIOS_SIGN_ID);
  return (UINT32) RShiftU64 (Signature, 32);
}
Esempio n. 15
0
/**
  Returns a bit field from a 64-bit value.

  Returns the bitfield specified by the StartBit and the EndBit from Operand.

  If 64-bit operations are not supported, then ASSERT().
  If StartBit is greater than 63, then ASSERT().
  If EndBit is greater than 63, then ASSERT().
  If EndBit is less than StartBit, then ASSERT().

  @param  Operand   Operand on which to perform the bitfield operation.
  @param  StartBit  The ordinal of the least significant bit in the bit field.
                    Range 0..63.
  @param  EndBit    The ordinal of the most significant bit in the bit field.
                    Range 0..63.

  @return The bit field read.

**/
UINT64
EFIAPI
BitFieldRead64 (
  IN      UINT64                    Operand,
  IN      UINTN                     StartBit,
  IN      UINTN                     EndBit
  )
{
  ASSERT (EndBit < sizeof (Operand) * 8);
  ASSERT (StartBit <= EndBit);
  return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit);
}
Esempio n. 16
0
/**
  WRITE_DMA_EXT command

  @param  CardData             Pointer to CARD_DATA.
  @param  LBA                  The starting logical block address to read from on the device.
  @param  Buffer               A pointer to the destination buffer for the data. The caller
                               is responsible for either having implicit or explicit ownership
                               of the buffer.
  @param  SectorCount          Size in 512 bytes unit.

  @retval EFI_SUCCESS                Success
  @retval EFI_DEVICE_ERROR           Hardware Error
  @retval EFI_INVALID_PARAMETER      Parameter is error
  @retval EFI_NO_MEDIA               No media
  @retval EFI_MEDIA_CHANGED          Media Change
  @retval EFI_BAD_BUFFER_SIZE        Buffer size is bad

**/
EFI_STATUS
WriteDMAExt (
  IN  CARD_DATA   *CardData,
  IN  EFI_LBA     LBA,
  IN  UINT8       *Buffer,
  IN  UINT16      SectorCount
  )
{

  EFI_STATUS  Status;

  ZeroMem (&CardData->TaskFile, sizeof (TASK_FILE));
  //
  //The host only supports nIEN = 0
  //
  CardData->TaskFile.Command_Status = WRITE_DMA_EXT;

  CardData->TaskFile.SectorCount     = (UINT8)SectorCount;
  CardData->TaskFile.SectorCount_Exp = (UINT8)(SectorCount >> 8);

  CardData->TaskFile.LBALow          = (UINT8)LBA;
  CardData->TaskFile.LBAMid          = (UINT8)RShiftU64(LBA, 8);
  CardData->TaskFile.LBAHigh         = (UINT8)RShiftU64(LBA, 16);

  CardData->TaskFile.LBALow_Exp      = (UINT8)RShiftU64(LBA, 24);
  CardData->TaskFile.LBAMid_Exp      = (UINT8)RShiftU64(LBA, 32);
  CardData->TaskFile.LBAHigh_Exp     = (UINT8)RShiftU64(LBA, 40);

  Status = SendATACommand (
             CardData,
             &CardData->TaskFile,
             TRUE,
             Buffer,
             SectorCount
             );
  return Status;

}
Esempio n. 17
0
VOID
SetEncodedSizeOfBuf(
    UINT64 EncodedSize,
    UINT8* EncodedData
)
{
    INT32   Index;

    EncodedData[LZMA_PROPS_SIZE] = EncodedSize & 0xFF;
    for (Index = LZMA_PROPS_SIZE + 1; Index <= LZMA_PROPS_SIZE + 7; Index++)
    {
        EncodedSize = RShiftU64(EncodedSize, 8);
        EncodedData[Index] = EncodedSize & 0xFF;
    }
}
EFI_STATUS
EFIAPI
GetNextHighMonotonicCount (
  OUT UINT32  *HighCount
  )
{
  if (HighCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  gCurrentMonotonicCount += 0x0000000100000000ULL;
  
  *HighCount = (UINT32)RShiftU64 (gCurrentMonotonicCount, 32) & 0xFFFFFFFF;

  return EFI_SUCCESS;
}
Esempio n. 19
0
/**
  Returns the bit position of the lowest bit set in a 64-bit value.

  This function computes the bit position of the lowest bit set in the 64-bit
  value specified by Operand. If Operand is zero, then -1 is returned.
  Otherwise, a value between 0 and 63 is returned.

  @param  Operand The 64-bit operand to evaluate.

  @retval 0..63  The lowest bit set in Operand was found.
  @retval -1     Operand is zero.


**/
INTN
EFIAPI
LowBitSet64 (
  IN      UINT64                    Operand
  )
{
  INTN                              BitIndex;

  if (Operand == 0) {
    return -1;
  }

  for (BitIndex = 0;
       (Operand & 1) == 0;
       BitIndex++, Operand = RShiftU64 (Operand, 1));
  return BitIndex;
}
Esempio n. 20
0
/**
  Saves a PCI configuration value to the boot script.

  This internal worker function saves a PCI configuration value in
  the S3 script to be replayed on S3 resume.

  If the saving process fails, then ASSERT().

  @param  Width   The width of PCI configuration.
  @param  Address Address that encodes the PCI Bus, Device, Function and
                  Register.
  @param  Buffer  The buffer containing value.

**/
VOID
InternalSavePciSegmentWriteValueToBootScript (
  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN UINT64                 Address,
  IN VOID                   *Buffer
  )
{
  RETURN_STATUS                Status;

  Status = S3BootScriptSavePciCfg2Write (
             Width,
             RShiftU64 ((Address), 32) & 0xffff,
             PCI_SEGMENT_LIB_ADDRESS_TO_S3_BOOT_SCRIPT_PCI_ADDRESS (Address),
             1,
             Buffer
             );
  ASSERT_RETURN_ERROR (Status);
}
/**
  Get bit value in bitmap table for the given address.

  @param[in]  Address     The address to retrieve for.

  @return 1 or 0.
**/
UINTN
EFIAPI
GetGuardMapBit (
  IN EFI_PHYSICAL_ADDRESS    Address
  )
{
  UINT64        *GuardMap;

  FindGuardedMemoryMap (Address, FALSE, &GuardMap);
  if (GuardMap != NULL) {
    if (RShiftU64 (*GuardMap,
                   GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address)) & 1) {
      return 1;
    }
  }

  return 0;
}
Esempio n. 22
0
STATIC
EFI_STATUS
EFIAPI
Virtio10SetGuestFeatures (
  IN VIRTIO_DEVICE_PROTOCOL  *This,
  IN UINT64                   Features
  )
{
  VIRTIO_1_0_DEV *Dev;
  UINT32         Selector;
  UINT32         Features32[2];

  Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);

  Features32[0] = (UINT32)Features;
  Features32[1] = (UINT32)RShiftU64 (Features, 32);

  for (Selector = 0; Selector < 2; ++Selector) {
    EFI_STATUS Status;

    //
    // Select the low or high half of the features.
    //
    Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
               OFFSET_OF (VIRTIO_PCI_COMMON_CFG, DriverFeatureSelect),
               sizeof Selector, &Selector);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Write that half.
    //
    Status = Virtio10Transfer (Dev->PciIo, &Dev->CommonConfig, TRUE,
               OFFSET_OF (VIRTIO_PCI_COMMON_CFG, DriverFeature),
               sizeof Features32[Selector], &Features32[Selector]);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}
Esempio n. 23
0
EFI_STATUS
EFIAPI
LibMtcGetNextHighMonotonicCount (
  OUT UINT32  *HighCount
  )
{
  EFI_STATUS  Status;
  EFI_TPL     OldTpl;

  //
  // Check input parameters
  //
  if (HighCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }


  if (!EfiAtRuntime ()) {
    // Use a lock if called before ExitBootServices()
    OldTpl      = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
  }

  *HighCount  = (UINT32) RShiftU64 (mEfiMtc, 32) + 1;
  mEfiMtc     = LShiftU64 (*HighCount, 32);

  if (!EfiAtRuntime ()) {
    gBS->RestoreTPL (OldTpl);
  }

  //
  // Update the NvRam store to match the new high part
  //
  Status = EfiSetVariable (
              mEfiMtcName,
              &mEfiMtcGuid,
              EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
              sizeof (UINT32),
              HighCount
              );

  return Status;
}
Esempio n. 24
0
/**
  Copies the data in a caller supplied buffer to a specified range of PCI
  configuration space, and saves the value in the S3 script to be replayed on S3
  resume.

  Writes the range of PCI configuration registers specified by StartAddress and
  Size from the buffer specified by Buffer. This function only allows the PCI
  configuration registers from a single PCI function to be written. Size is
  returned. When possible 32-bit PCI configuration write cycles are used to
  write from StartAdress to StartAddress + Size. Due to alignment restrictions,
  8-bit and 16-bit PCI configuration write cycles may be used at the beginning
  and the end of the range.

  If any reserved bits in StartAddress are set, then ASSERT().
  If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
  If Size > 0 and Buffer is NULL, then ASSERT().

  @param  StartAddress  Starting address that encodes the PCI Segment, Bus, Device,
                        Function and Register.
  @param  Size          Size in bytes of the transfer.
  @param  Buffer        Pointer to a buffer containing the data to write.

  @return The parameter of Size.

**/
UINTN
EFIAPI
S3PciSegmentWriteBuffer (
  IN UINT64                    StartAddress,
  IN UINTN                     Size,
  IN VOID                      *Buffer
  )
{
  RETURN_STATUS    Status;

  Status = S3BootScriptSavePciCfg2Write (
             S3BootScriptWidthUint8,
             RShiftU64 (StartAddress, 32) & 0xffff,
             PCI_SEGMENT_LIB_ADDRESS_TO_S3_BOOT_SCRIPT_PCI_ADDRESS (StartAddress),
             PciSegmentWriteBuffer (StartAddress, Size, Buffer),
             Buffer
             );
  ASSERT_RETURN_ERROR (Status);
  return Size;
}
/**
  Get corresponding bits in bitmap table according to the address.

  The value of bit 0 corresponds to the status of memory at given Address.
  No more than 64 bits can be retrieved in one call.

  @param[in]  Address     Start address to retrieve bits for.
  @param[in]  BitNumber   Number of bits to get.
  @param[in]  BitMap      Pointer to bitmap which covers the Address.

  @return An integer containing the bits information.
**/
STATIC
UINT64
GetBits (
  IN EFI_PHYSICAL_ADDRESS    Address,
  IN UINTN                   BitNumber,
  IN UINT64                  *BitMap
  )
{
  UINTN           StartBit;
  UINTN           EndBit;
  UINTN           Lsbs;
  UINTN           Msbs;
  UINT64          Result;

  ASSERT (BitNumber <= GUARDED_HEAP_MAP_ENTRY_BITS);

  StartBit  = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);
  EndBit    = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;

  if ((StartBit + BitNumber) > GUARDED_HEAP_MAP_ENTRY_BITS) {
    Msbs = GUARDED_HEAP_MAP_ENTRY_BITS - StartBit;
    Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;
  } else {
    Msbs = BitNumber;
    Lsbs = 0;
  }

  if (StartBit == 0 && BitNumber == GUARDED_HEAP_MAP_ENTRY_BITS) {
    Result = *BitMap;
  } else {
    Result    = RShiftU64((*BitMap), StartBit) & (LShiftU64(1, Msbs) - 1);
    if (Lsbs > 0) {
      BitMap  += 1;
      Result  |= LShiftU64 ((*BitMap) & (LShiftU64 (1, Lsbs) - 1), Msbs);
    }
  }

  return Result;
}
Esempio n. 26
0
/**
  Returns the bit position of the highest bit set in a 64-bit value. Equivalent
  to log2(x).

  This function computes the bit position of the highest bit set in the 64-bit
  value specified by Operand. If Operand is zero, then -1 is returned.
  Otherwise, a value between 0 and 63 is returned.

  @param  Operand The 64-bit operand to evaluate.

  @return Position of the highest bit set in Operand if found.
  @retval -1  Operand is zero.

**/
INTN
EFIAPI
HighBitSet64 (
  IN      UINT64                    Operand
  )
{
  if (Operand == (UINT32)Operand) {
    //
    // Operand is just a 32-bit integer
    //
    return HighBitSet32 ((UINT32)Operand);
  }

  //
  // Operand is really a 64-bit integer
  //
  if (sizeof (UINTN) == sizeof (UINT32)) {
    return HighBitSet32 (((UINT32*)&Operand)[1]) + 32;
  } else {
    return HighBitSet32 ((UINT32)RShiftU64 (Operand, 32)) + 32;
  }
}
Esempio n. 27
0
/**
  Function for 'mm' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunMm (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                      Status;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *IoDev;
  UINT64                          Address;
  UINT64                          PciEAddress;
  UINT64                          Value;
  UINT32                          SegmentNumber;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH                    Width;
  EFI_ACCESS_TYPE                 AccessType;
  UINT64                          Buffer;
  UINTN                           Index;
  UINTN                           Size;
//  CHAR16                          *ValueStr;
  BOOLEAN                         Complete;
  CHAR16                          *InputStr;
  BOOLEAN                         Interactive;
  EFI_HANDLE                      *HandleBuffer;
  UINTN                           BufferSize;
  UINTN                           ItemValue;
  LIST_ENTRY                      *Package;
  CHAR16                          *ProblemParam;
  SHELL_STATUS                    ShellStatus;
  CONST CHAR16                    *Temp;

  Value         = 0;
  Address       = 0;
  PciEAddress   = 0;
  IoDev         = NULL;
  HandleBuffer  = NULL;
  BufferSize    = 0;
  SegmentNumber = 0;
  ShellStatus   = SHELL_SUCCESS;
  InputStr      = NULL;

  //
  // Parse arguments
  //
  Width       = EfiPciWidthUint8;
  Size        = 1;
  AccessType  = EfiMemory;
//  ValueStr    = NULL;
  Interactive = TRUE;
  Package     = NULL;

  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } else {
      ASSERT(FALSE);
    }
  } else {
    if (ShellCommandLineGetCount(Package) < 2) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } else if (ShellCommandLineGetCount(Package) > 3) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } else if (ShellCommandLineGetFlag(Package, L"-w") && ShellCommandLineGetValue(Package, L"-w") == NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"-w");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } else {
      if (ShellCommandLineGetFlag(Package, L"-mmio")) {
        AccessType = EFIMemoryMappedIo;
        if (ShellCommandLineGetFlag(Package, L"-mem")
          ||ShellCommandLineGetFlag(Package, L"-io")
          ||ShellCommandLineGetFlag(Package, L"-pci")
          ||ShellCommandLineGetFlag(Package, L"-pcie")
        ){
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
          ShellStatus = SHELL_INVALID_PARAMETER;
          goto Done;
        }
      } else if (ShellCommandLineGetFlag(Package, L"-mem")) {
        AccessType = EfiMemory;
        if (ShellCommandLineGetFlag(Package, L"-io")
          ||ShellCommandLineGetFlag(Package, L"-pci")
          ||ShellCommandLineGetFlag(Package, L"-pcie")
        ){
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
          ShellStatus = SHELL_INVALID_PARAMETER;
          goto Done;
        }
      } else if (ShellCommandLineGetFlag(Package, L"-io")) {
        AccessType = EfiIo;
        if (ShellCommandLineGetFlag(Package, L"-pci")
          ||ShellCommandLineGetFlag(Package, L"-pcie")
        ){
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
          ShellStatus = SHELL_INVALID_PARAMETER;
          goto Done;
        }
      } else if (ShellCommandLineGetFlag(Package, L"-pci")) {
        AccessType = EfiPciConfig;
        if (ShellCommandLineGetFlag(Package, L"-pcie")
        ){
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
          ShellStatus = SHELL_INVALID_PARAMETER;
          goto Done;
        }
      } else if (ShellCommandLineGetFlag(Package, L"-pcie")) {
        AccessType = EfiPciEConfig;
      }
    }

    //
    // Non interactive for a script file or for the specific parameter
    //
    if (gEfiShellProtocol->BatchIsActive() || ShellCommandLineGetFlag (Package, L"-n")) {
      Interactive = FALSE;
    }

    Temp = ShellCommandLineGetValue(Package, L"-w");
    if (Temp != NULL) {
      ItemValue = ShellStrToUintn (Temp);

      switch (ItemValue) {
      case 1:
        Width = EfiPciWidthUint8;
        Size  = 1;
        break;

      case 2:
        Width = EfiPciWidthUint16;
        Size  = 2;
        break;

      case 4:
        Width = EfiPciWidthUint32;
        Size  = 4;
        break;

      case 8:
        Width = EfiPciWidthUint64;
        Size  = 8;
        break;

      default:
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, L"-w");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    Temp = ShellCommandLineGetRawValue(Package, 1);
    if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, (UINT64*)&Address, TRUE, FALSE))) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    Temp = ShellCommandLineGetRawValue(Package, 2);
    if (Temp != NULL) {
      //
      // Per spec if value is specified, then -n is assumed.
      //
      Interactive = FALSE;

      if (!ShellIsHexOrDecimalNumber(Temp, TRUE, FALSE) || EFI_ERROR(ShellConvertStringToUint64(Temp, &Value, TRUE, FALSE))) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
      switch (Size) {
      case 1:
        if (Value > 0xFF) {
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
        break;

      case 2:
        if (Value > 0xFFFF) {
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
        break;

      case 4:
        if (Value > 0xFFFFFFFF) {
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
        break;

      default:
        break;
      }

      if (ShellStatus != SHELL_SUCCESS) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Temp);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    if ((Address & (Size - 1)) != 0) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_NOT_ALIGNED), gShellDebug1HiiHandle, Address);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }
    //
    // locate DeviceIO protocol interface
    //
    if (AccessType != EfiMemory) {
      Status = gBS->LocateHandleBuffer (
                 ByProtocol,
                 &gEfiPciRootBridgeIoProtocolGuid,
                 NULL,
                 &BufferSize,
                 &HandleBuffer
                );
      if (EFI_ERROR (Status)) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PCIRBIO_NF), gShellDebug1HiiHandle);
        ShellStatus = SHELL_NOT_FOUND;
        goto Done;
      }
      //
      // In the case of PCI or PCIE
      // Get segment number and mask the segment bits in Address
      //
      if (AccessType == EfiPciEConfig) {
        SegmentNumber = (UINT32) RShiftU64 (Address, 36) & 0xff;
        Address      &= 0xfffffffffULL;
      } else {
        if (AccessType == EfiPciConfig) {
          SegmentNumber = (UINT32) RShiftU64 (Address, 32) & 0xff;
          Address      &= 0xffffffff;
        }
      }
      //
      // Find the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL of the specified segment number
      //
      for (Index = 0; Index < BufferSize; Index++) {
        Status = gBS->HandleProtocol (
                       HandleBuffer[Index],
                       &gEfiPciRootBridgeIoProtocolGuid,
                       (VOID *) &IoDev
                      );
        if (EFI_ERROR (Status)) {
          continue;
        }
        if (IoDev->SegmentNumber != SegmentNumber) {
          IoDev = NULL;
        }
      }
      if (IoDev == NULL) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_SEGMENT_NOT_FOUND), gShellDebug1HiiHandle, SegmentNumber);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    if (AccessType == EfiIo && Address + Size > 0x10000) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE), gShellDebug1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    if (AccessType == EfiPciEConfig) {
      GetPciEAddressFromInputAddress (Address, &PciEAddress);
    }

    //
    // Set value
    //
    if (ShellCommandLineGetRawValue(Package, 2) != NULL) {
      if (AccessType == EFIMemoryMappedIo) {
        IoDev->Mem.Write (IoDev, Width, Address, 1, &Value);
      } else if (AccessType == EfiIo) {
        IoDev->Io.Write (IoDev, Width, Address, 1, &Value);
      } else if (AccessType == EfiPciConfig) {
        IoDev->Pci.Write (IoDev, Width, Address, 1, &Value);
      } else if (AccessType == EfiPciEConfig) {
        IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Value);
      } else {
        WriteMem (Width, Address, 1, &Value);
      }

      ASSERT(ShellStatus == SHELL_SUCCESS);
      goto Done;
    }


    //
    // non-interactive mode
    //
    if (!Interactive) {
      Buffer = 0;
      if (AccessType == EFIMemoryMappedIo) {
        if (!gEfiShellProtocol->BatchIsActive()) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
        }
        IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
      } else if (AccessType == EfiIo) {
        if (!gEfiShellProtocol->BatchIsActive()) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
        }
        IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
      } else if (AccessType == EfiPciConfig) {
        if (!gEfiShellProtocol->BatchIsActive()) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
        }
        IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
      } else if (AccessType == EfiPciEConfig) {
        if (!gEfiShellProtocol->BatchIsActive()) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
        }
        IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
      } else {
        if (!gEfiShellProtocol->BatchIsActive()) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
        }
        ReadMem (Width, Address, 1, &Buffer);
      }
      if (!gEfiShellProtocol->BatchIsActive()) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);
      }
      if (Size == 1) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
      } else if (Size == 2) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
      } else if (Size == 4) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
      } else if (Size == 8) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
      }

      ShellPrintEx(-1, -1, L"\r\n");

      ASSERT(ShellStatus == SHELL_SUCCESS);
      goto Done;
    }
    //
    // interactive mode
    //
    Complete = FALSE;
    do {
      if (AccessType == EfiIo && Address + Size > 0x10000) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS_RANGE2), gShellDebug1HiiHandle);
        break;
      }

      Buffer = 0;
      if (AccessType == EFIMemoryMappedIo) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MMIO), gShellDebug1HiiHandle);
        IoDev->Mem.Read (IoDev, Width, Address, 1, &Buffer);
      } else if (AccessType == EfiIo) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_IO), gShellDebug1HiiHandle);
        IoDev->Io.Read (IoDev, Width, Address, 1, &Buffer);
      } else if (AccessType == EfiPciConfig) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCI), gShellDebug1HiiHandle);
        IoDev->Pci.Read (IoDev, Width, Address, 1, &Buffer);
      } else if (AccessType == EfiPciEConfig) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_PCIE), gShellDebug1HiiHandle);
        IoDev->Pci.Read (IoDev, Width, PciEAddress, 1, &Buffer);
      } else {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_MEM), gShellDebug1HiiHandle);
        ReadMem (Width, Address, 1, &Buffer);
      }

      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ADDRESS), gShellDebug1HiiHandle, Address);

      if (Size == 1) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF2), gShellDebug1HiiHandle, (UINTN)Buffer);
      } else if (Size == 2) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF4), gShellDebug1HiiHandle, (UINTN)Buffer);
      } else if (Size == 4) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF8), gShellDebug1HiiHandle, (UINTN)Buffer);
      } else if (Size == 8) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_BUF16), gShellDebug1HiiHandle, Buffer);
      }
      ShellPrintEx(-1, -1, L" > ");
      //
      // wait user input to modify
      //
      if (InputStr != NULL) {
        FreePool(InputStr);
        InputStr = NULL;
      }
      ShellPromptForResponse(ShellPromptResponseTypeFreeform, NULL, (VOID**)&InputStr);

      //
      // skip space characters
      //
      for (Index = 0; InputStr != NULL && InputStr[Index] == ' '; Index++);

      //
      // parse input string
      //
      if (InputStr != NULL && (InputStr[Index] == '.' || InputStr[Index] == 'q' || InputStr[Index] == 'Q')) {
        Complete = TRUE;
      } else if (InputStr == NULL || InputStr[Index] == CHAR_NULL) {
        //
        // Continue to next address
        //
      } else if (GetHex (InputStr + Index, &Buffer) && Buffer <= MaxNum[Width]) {
        if (AccessType == EFIMemoryMappedIo) {
          IoDev->Mem.Write (IoDev, Width, Address, 1, &Buffer);
        } else if (AccessType == EfiIo) {
          IoDev->Io.Write (IoDev, Width, Address, 1, &Buffer);
        } else if (AccessType == EfiPciConfig) {
          IoDev->Pci.Write (IoDev, Width, Address, 1, &Buffer);
        } else if (AccessType == EfiPciEConfig) {
          IoDev->Pci.Write (IoDev, Width, PciEAddress, 1, &Buffer);
        } else {
          WriteMem (Width, Address, 1, &Buffer);
        }
      } else {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_MM_ERROR), gShellDebug1HiiHandle);
        continue;
  //      PrintToken (STRING_TOKEN (STR_IOMOD_ERROR), HiiHandle);
      }

      Address += Size;
      if (AccessType == EfiPciEConfig) {
        GetPciEAddressFromInputAddress (Address, &PciEAddress);
      }
      ShellPrintEx(-1, -1, L"\r\n");
  //    Print (L"\n");
    } while (!Complete);
  }
  ASSERT(ShellStatus == SHELL_SUCCESS);
Done:

  if (InputStr != NULL) {
    FreePool(InputStr);
  }
  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }
  if (Package != NULL) {
    ShellCommandLineFreeVarList (Package);
  }
  return ShellStatus;
}
Esempio n. 28
0
/**
  This function will get the memory cache type of the specific address.

  This function is mainly for debug purpose.

  @param  Address   The specific address

  @return Memory cache type of the sepcific address

**/
MTRR_MEMORY_CACHE_TYPE
EFIAPI
MtrrGetMemoryAttribute (
  IN PHYSICAL_ADDRESS   Address
  )
{
  UINT64                  TempQword;
  UINTN                   Index;
  UINTN                   SubIndex;
  UINT64                  MtrrType;
  UINT64                  TempMtrrType;
  MTRR_MEMORY_CACHE_TYPE  CacheType;
  VARIABLE_MTRR           VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
  UINT64                  MtrrValidBitsMask;
  UINT64                  MtrrValidAddressMask;
  UINTN                   VariableMtrrCount;

  if (!IsMtrrSupported ()) {
    return CacheUncacheable;
  }

  //
  // Check if MTRR is enabled, if not, return UC as attribute
  //
  TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);
  MtrrType = MTRR_CACHE_INVALID_TYPE;

  if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
    return CacheUncacheable;
  }

  //
  // If address is less than 1M, then try to go through the fixed MTRR
  //
  if (Address < BASE_1MB) {
    if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) {
      //
      // Go through the fixed MTRR
      //
      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
         if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&
             Address  < (
                          mMtrrLibFixedMtrrTable[Index].BaseAddress +
                          (mMtrrLibFixedMtrrTable[Index].Length * 8)
                        )
            ) {
           SubIndex =
             ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
               mMtrrLibFixedMtrrTable[Index].Length;
           TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;
           return GetMemoryCacheTypeFromMtrrType (MtrrType);
         }
      }
    }
  }
  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
  MtrrGetMemoryAttributeInVariableMtrr(
    MtrrValidBitsMask,
    MtrrValidAddressMask,
    VariableMtrr
    );

  //
  // Go through the variable MTRR
  //
  VariableMtrrCount = GetVariableMtrrCount ();
  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);

  for (Index = 0; Index < VariableMtrrCount; Index++) {
    if (VariableMtrr[Index].Valid) {
      if (Address >= VariableMtrr[Index].BaseAddress &&
          Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {
        TempMtrrType = VariableMtrr[Index].Type;
        MtrrType = MtrrPrecedence (MtrrType, TempMtrrType);
      }
    }
  }
  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType);

  return CacheType;
}
Esempio n. 29
0
/**
  This function will update any runtime platform specific information.
  This currently includes:
    Setting OEM table values, ID, table ID, creator ID and creator revision.
    Enabling the proper processor entries in the APIC tables.

  @param[in]  Table       The table to update.

  @retval  EFI_SUCCESS    The function completed successfully.

**/
EFI_STATUS
PlatformUpdateTables (
  IN OUT EFI_ACPI_COMMON_HEADER  *Table
  )
{
  EFI_ACPI_DESCRIPTION_HEADER                                 *TableHeader;
  UINT8                                                       *CurrPtr;
  UINT8                                                       *EndPtr;
  ACPI_APIC_STRUCTURE_PTR                                     *ApicPtr;
  UINT8                                                       CurrProcessor;
  EFI_STATUS                                                  Status;
  EFI_MP_SERVICES_PROTOCOL                                    *MpService;
  UINTN                                                       MaximumNumberOfCPUs;
  UINTN                                                       NumberOfEnabledCPUs;
  UINTN                                                       BufferSize;
  ACPI_APIC_STRUCTURE_PTR                                     *ProcessorLocalApicEntry;
  UINTN                                                       BspIndex;
  EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE                          *AsfEntry;
  EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER            *HpetTbl;
  UINT64                                                      OemIdValue;
  UINT8                                                       Index;
  EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE                   *Facp;
  EFI_ACPI_OSFR_TABLE                                         *OsfrTable;
  EFI_ACPI_OSFR_OCUR_OBJECT                                   *pOcurObject;
  EFI_ACPI_OSFR_OCUR_OBJECT                                   OcurObject = {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0};
  CHAR16                                                      *OcurMfgStringBuffer = NULL;
  CHAR16                                                      *OcurModelStringBuffer = NULL;
  UINT8                                                       *OcurRefDataBlockBuffer = NULL;
  UINTN                                                       OcurMfgStringBufferSize;
  UINTN                                                       OcurModelStringBufferSize;
  UINTN                                                       OcurRefDataBlockBufferSize;
#if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED
  EFI_ACPI_ASPT_TABLE                                         *pSpttTable;
#endif
  UINT16                                                      NumberOfHpets;
  UINT16                                                      HpetCapIdValue;
  UINT32                                                      HpetBlockID;
  UINTN                                                       LocalApicCounter;
  EFI_PROCESSOR_INFORMATION                                   ProcessorInfoBuffer;
  UINT8                                                       TempVal;
  EFI_ACPI_3_0_IO_APIC_STRUCTURE                              *IOApicType;
  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER         *APICTableHeader;

  CurrPtr                 = NULL;
  EndPtr                  = NULL;
  ApicPtr                 = NULL;
  LocalApicCounter        = 0;
  CurrProcessor           = 0;
  ProcessorLocalApicEntry = NULL;


 if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
    TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
    //
    // Update the OEMID.
    //
    OemIdValue = mPlatformInfo->AcpiOemId;

    *(UINT32 *)(TableHeader->OemId)     = (UINT32)OemIdValue;
    *(UINT16 *)(TableHeader->OemId + 4) = *(UINT16*)(((UINT8 *)&OemIdValue) + 4);

    if ((Table->Signature != EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) {
    //
    // Update the OEM Table ID.
    //
      TableHeader->OemTableId = mPlatformInfo->AcpiOemTableId;
    }

    //
    // Update the OEM Table ID.
    //
    TableHeader->OemRevision = EFI_ACPI_OEM_REVISION;

    //
    // Update the creator ID.
    //
    TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;

    //
    // Update the creator revision.
    //
    TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
  }

  //
  // Complete this function.
  //
  //
  // Locate the MP services protocol.
  //
  //
  // Find the MP Protocol. This is an MP platform, so MP protocol must be
  // there.
  //
  Status = gBS->LocateProtocol (
                  &gEfiMpServiceProtocolGuid,
                  NULL,
                  (VOID **) &MpService
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Determine the number of processors.
  //
  MpService->GetNumberOfProcessors (
              MpService,
              &MaximumNumberOfCPUs,
              &NumberOfEnabledCPUs
              );

  ASSERT (MaximumNumberOfCPUs <= MAX_CPU_NUM && NumberOfEnabledCPUs >= 1);


  //
  // Assign a invalid intial value for update.
  //
  //
  // Update the processors in the APIC table.
  //
  switch (Table->Signature) {
    case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
      //
      if (mSystemConfig.Asf == 1) {
        return  EFI_UNSUPPORTED;
      }
      AsfEntry = (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE *) Table;
      TempVal = (mNumberSmbusAddress < ASF_ADDR_DEVICE_ARRAY_LENGTH)? mNumberSmbusAddress : ASF_ADDR_DEVICE_ARRAY_LENGTH;
      for (Index = 0; Index < TempVal; Index++) {
        AsfEntry->AsfAddr.FixedSmbusAddresses[Index] = mSmbusRsvdAddresses[Index];
      }
      break;

    case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:

      Status = MpService->WhoAmI (
                            MpService,
                            &BspIndex
                            );

      //
      // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
      //
      APICTableHeader = (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;
      APICTableHeader->Flags |= EFI_ACPI_3_0_PCAT_COMPAT;

      CurrPtr = (UINT8 *) &((EFI_ACPI_DESCRIPTION_HEADER *) Table)[1];
      CurrPtr = CurrPtr + 8;

      //
      // Size of Local APIC Address & Flag.
      //
      EndPtr  = (UINT8 *) Table;
      EndPtr  = EndPtr + Table->Length;
      while (CurrPtr < EndPtr) {
        ApicPtr = (ACPI_APIC_STRUCTURE_PTR *) CurrPtr;
        switch (ApicPtr->AcpiApicCommon.Type) {
          case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC:
            //
            // ESS override
            // Fix for Ordering of MADT to be maintained as it is in MADT table.
            //
            // Update processor enabled or disabled and keep the local APIC
            // order in MADT intact.
            //
            // Sanity check to make sure proc-id is not arbitrary.
            //
            DEBUG ((EFI_D_ERROR, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \
            ApicPtr->AcpiLocalApic.AcpiProcessorId, MaximumNumberOfCPUs));
            if(ApicPtr->AcpiLocalApic.AcpiProcessorId > MaximumNumberOfCPUs) {
              ApicPtr->AcpiLocalApic.AcpiProcessorId = (UINT8)MaximumNumberOfCPUs;
            }

            BufferSize                    = 0;
            ApicPtr->AcpiLocalApic.Flags  = 0;

            for (CurrProcessor = 0; CurrProcessor < MaximumNumberOfCPUs; CurrProcessor++) {
              Status = MpService->GetProcessorInfo (
                                    MpService,
                                    CurrProcessor,
                                    &ProcessorInfoBuffer
                                    );

              if (Status == EFI_SUCCESS && ProcessorInfoBuffer.ProcessorId == ApicPtr->AcpiLocalApic.ApicId) {
                //
                // Check to see whether or not a processor (or thread) is enabled.
                //
                if ((BspIndex == CurrProcessor) || ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0)) {
                  //
                  // Go on and check if Hyper Threading is enabled. If HT not enabled
                  // hide this thread from OS by not setting the flag to 1.  This is the
                  // software way to disable Hyper Threading.  Basically we just hide it
                  // from the OS.
                  //
                  ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_1_0_LOCAL_APIC_ENABLED;


                  if(ProcessorInfoBuffer.Location.Thread != 0) {
                    ApicPtr->AcpiLocalApic.Flags = 0;
                  }

                  AppendCpuMapTableEntry (&(ApicPtr->AcpiLocalApic));
                }
                break;
              }
            }

            //
            // If no APIC-ID match, the cpu may not be populated.
            //
            break;

          case EFI_ACPI_3_0_IO_APIC:

            IOApicType = (EFI_ACPI_3_0_IO_APIC_STRUCTURE *)CurrPtr;
            IOApicType->IoApicId = 0x02;
            //
            // IO APIC entries can be patched here.
            //
            break;
        }

        CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
      }
      break;

    case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:

       Facp = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
       Facp->Flags &= (UINT32)(~(3<<2));

      break;

    case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Patch the memory resource.
      //
      PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER *) Table);
      break;

    case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Gv3 support
      //
      // TBD: Need re-design based on the ValleyTrail platform.
      //
      break;

    case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
      //
      // Adjust HPET Table to correct the Base Address.
      //
      // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
      //
      MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);


      HpetTbl = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table;
      HpetTbl->BaseAddressLower32Bit.Address = HPET_BASE_ADDRESS;
      HpetTbl->EventTimerBlockId = *((UINT32*)(UINTN)HPET_BASE_ADDRESS);

      HpetCapIdValue = *(UINT16 *)(UINTN)(HPET_BASE_ADDRESS);
      NumberOfHpets = HpetCapIdValue & B_PCH_PCH_HPET_GCID_NT;  // Bits [8:12] contains the number of Hpets
      HpetBlockID = EFI_ACPI_EVENT_TIMER_BLOCK_ID;

      if((NumberOfHpets) && (NumberOfHpets & B_PCH_PCH_HPET_GCID_NT)) {
        HpetBlockID |= (NumberOfHpets);
      }
      HpetTbl->EventTimerBlockId = HpetBlockID;

      break;

    case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
      //
      // Update MCFG base and end bus number.
      //
      ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].BaseAddress
        = mPlatformInfo->PciData.PciExpressBase;
      ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].EndBusNumber
        = (UINT8)RShiftU64 (mPlatformInfo->PciData.PciExpressSize, 20) - 1;
      break;


    case EFI_ACPI_OSFR_TABLE_SIGNATURE:
      //
      // Get size of OSFR variable.
      //
      OcurMfgStringBufferSize = 0;
      Status = gRT->GetVariable (
                      gACPIOSFRMfgStringVariableName,
                      &gACPIOSFRMfgStringVariableGuid,
                      NULL,
                      &OcurMfgStringBufferSize,
                      NULL
                      );
      if (Status != EFI_BUFFER_TOO_SMALL) {
        //
        // Variable must not be present on the system.
        //
        return EFI_UNSUPPORTED;
      }

      //
      // Allocate memory for variable data.
      //
      OcurMfgStringBuffer = AllocatePool (OcurMfgStringBufferSize);
      Status = gRT->GetVariable (
                      gACPIOSFRMfgStringVariableName,
                      &gACPIOSFRMfgStringVariableGuid,
                      NULL,
                      &OcurMfgStringBufferSize,
                      OcurMfgStringBuffer
                      );
      if (!EFI_ERROR (Status)) {
        OcurModelStringBufferSize = 0;
        Status = gRT->GetVariable (
                        gACPIOSFRModelStringVariableName,
                        &gACPIOSFRModelStringVariableGuid,
                        NULL,
                        &OcurModelStringBufferSize,
                        NULL
                        );
        if (Status != EFI_BUFFER_TOO_SMALL) {
          //
          // Variable must not be present on the system.
          //
          return EFI_UNSUPPORTED;
        }

        //
        // Allocate memory for variable data.
        //
        OcurModelStringBuffer = AllocatePool (OcurModelStringBufferSize);
        Status = gRT->GetVariable (
                        gACPIOSFRModelStringVariableName,
                        &gACPIOSFRModelStringVariableGuid,
                        NULL,
                        &OcurModelStringBufferSize,
                        OcurModelStringBuffer
                        );
        if (!EFI_ERROR (Status)) {
          OcurRefDataBlockBufferSize = 0;
          Status = gRT->GetVariable (
                          gACPIOSFRRefDataBlockVariableName,
                          &gACPIOSFRRefDataBlockVariableGuid,
                          NULL,
                          &OcurRefDataBlockBufferSize,
                          NULL
                          );
          if (Status == EFI_BUFFER_TOO_SMALL) {
            //
            // Allocate memory for variable data.
            //
            OcurRefDataBlockBuffer = AllocatePool (OcurRefDataBlockBufferSize);
            Status = gRT->GetVariable (
                            gACPIOSFRRefDataBlockVariableName,
                            &gACPIOSFRRefDataBlockVariableGuid,
                            NULL,
                            &OcurRefDataBlockBufferSize,
                            OcurRefDataBlockBuffer
                            );
          }
          OsfrTable = (EFI_ACPI_OSFR_TABLE *) Table;
          //
          // Currently only one object is defined: OCUR_OSFR_TABLE.
          //
          OsfrTable->ObjectCount = 1;
          //
          // Initialize table length to fixed portion of the ACPI OSFR table.
          //
          OsfrTable->Header.Length = sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION);
          *(UINT32 *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION)) = \
            (UINT32) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + sizeof (UINT32));
          pOcurObject = (EFI_ACPI_OSFR_OCUR_OBJECT *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + \
            sizeof (UINT32));
          CopyMem (pOcurObject, &OcurObject, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));
          pOcurObject->ManufacturerNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
            sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));
          pOcurObject->ModelNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
            sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize);
          if (OcurRefDataBlockBufferSize > 0) {
            pOcurObject->MicrosoftReferenceOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \
              sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + OcurModelStringBufferSize);
          }
          CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT)), OcurMfgStringBuffer, \
            OcurMfgStringBufferSize);
          CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize), \
            OcurModelStringBuffer, OcurModelStringBufferSize);
          if (OcurRefDataBlockBufferSize > 0) {
            CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + \
            OcurModelStringBufferSize),OcurRefDataBlockBuffer, OcurRefDataBlockBufferSize);
          }
          OsfrTable->Header.Length += (UINT32)(OcurMfgStringBufferSize + OcurModelStringBufferSize + OcurRefDataBlockBufferSize);
          OsfrTable->Header.Length += sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + sizeof (UINT32);
        }
      }
      gBS->FreePool (OcurMfgStringBuffer);
      gBS->FreePool (OcurModelStringBuffer);
      gBS->FreePool (OcurRefDataBlockBuffer);
      break;
    default:
      break;
  }

  //
  //
  // Update the hardware signature in the FACS structure.
  //
  //
  // Locate the SPCR table and update based on current settings.
  // The user may change CR settings via setup or other methods.
  // The SPCR table must match.
  //
  return EFI_SUCCESS;
}
Esempio n. 30
0
/**
  Check parameters to a CPU I/O PPI service request.

  @param[in]  MmioOperation  TRUE for an MMIO operation, FALSE for I/O Port operation.
  @param[in]  Width          The width of the access. Enumerated in bytes.
  @param[in]  Address        The physical address of the access.
  @param[in]  Count          The number of accesses to perform.
  @param[in]  Buffer         A pointer to the buffer of data.

  @retval EFI_SUCCESS            The parameters for this request pass the checks.
  @retval EFI_INVALID_PARAMETER  Width is invalid for this EFI system.
  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
                                 and Count is not valid for this EFI system.

**/
EFI_STATUS
CpuIoCheckParameter (
  IN BOOLEAN                   MmioOperation,
  IN EFI_PEI_CPU_IO_PPI_WIDTH  Width,
  IN UINT64                    Address,
  IN UINTN                     Count,
  IN VOID                      *Buffer
  )
{
  UINT64  MaxCount;
  UINT64  Limit;

  //
  // Check to see if Buffer is NULL
  //
  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check to see if Width is in the valid range
  //
  if ((UINT32)Width >= EfiPeiCpuIoWidthMaximum) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // For FIFO type, the target address won't increase during the access,
  // so treat Count as 1
  //
  if (Width >= EfiPeiCpuIoWidthFifoUint8 && Width <= EfiPeiCpuIoWidthFifoUint64) {
    Count = 1;
  }

  //
  // Check to see if Width is in the valid range for I/O Port operations
  //
  Width = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
  if (!MmioOperation && (Width == EfiPeiCpuIoWidthUint64)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check to see if any address associated with this transfer exceeds the maximum
  // allowed address.  The maximum address implied by the parameters passed in is
  // Address + Size * Count.  If the following condition is met, then the transfer
  // is not supported.
  //
  //    Address + Size * Count > (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS) + 1
  //
  // Since MAX_ADDRESS can be the maximum integer value supported by the CPU and Count
  // can also be the maximum integer value supported by the CPU, this range
  // check must be adjusted to avoid all overflow conditions.
  //
  // The following form of the range check is equivalent but assumes that
  // MAX_ADDRESS and MAX_IO_PORT_ADDRESS are of the form (2^n - 1).
  //
  Limit = (MmioOperation ? MAX_ADDRESS : MAX_IO_PORT_ADDRESS);
  if (Count == 0) {
    if (Address > Limit) {
      return EFI_UNSUPPORTED;
    }
  } else {
    MaxCount = RShiftU64 (Limit, Width);
    if (MaxCount < (Count - 1)) {
      return EFI_UNSUPPORTED;
    }
    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
      return EFI_UNSUPPORTED;
    }
  }

  return EFI_SUCCESS;
}