Пример #1
0
/**
  Checks if the given GUID is a zero GUID.

  This function checks whether the given GUID is a zero GUID. If the GUID is
  identical to a zero GUID then TRUE is returned. Otherwise, FALSE is returned.

  If Guid is NULL, then ASSERT().

  @param  Guid        The pointer to a 128 bit GUID.

  @retval TRUE        Guid is a zero GUID.
  @retval FALSE       Guid is not a zero GUID.

**/
BOOLEAN
EFIAPI
IsZeroGuid (
  IN CONST GUID  *Guid
  )
{
  UINT64  LowPartOfGuid;
  UINT64  HighPartOfGuid;

  LowPartOfGuid  = ReadUnaligned64 ((CONST UINT64*) Guid);
  HighPartOfGuid = ReadUnaligned64 ((CONST UINT64*) Guid + 1);

  return (BOOLEAN) (LowPartOfGuid == 0 && HighPartOfGuid == 0);
}
Пример #2
0
/**
  Compares two GUIDs.

  This function compares Guid1 to Guid2.  If the GUIDs are identical then TRUE is returned.
  If there are any bit differences in the two GUIDs, then FALSE is returned.
  If Guid1 is NULL, then ASSERT().
  If Guid2 is NULL, then ASSERT().

  @param  Guid1       A pointer to a 128 bit GUID.
  @param  Guid2       A pointer to a 128 bit GUID.

  @retval TRUE        Guid1 and Guid2 are identical.
  @retval FALSE       Guid1 and Guid2 are not identical.

**/
BOOLEAN
EFIAPI
GlueCompareGuid (
  IN CONST GUID  *Guid1,
  IN CONST GUID  *Guid2
  )
{
  return (BOOLEAN)(
           ReadUnaligned64 ((CONST UINT64*)Guid1)
             == ReadUnaligned64 ((CONST UINT64*)Guid2) &&
           ReadUnaligned64 ((CONST UINT64*)Guid1 + 1)
             == ReadUnaligned64 ((CONST UINT64*)Guid2 + 1)
           );
}
Пример #3
0
EFIAPI
CopyGuid (
  OUT GUID       *DestinationGuid,
  IN CONST GUID  *SourceGuid
  )
{
  WriteUnaligned64 (
    (UINT64*)DestinationGuid,
    ReadUnaligned64 ((CONST UINT64*)SourceGuid)
    );
  WriteUnaligned64 (
    (UINT64*)DestinationGuid + 1,
    ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
    );
  return DestinationGuid;
}
Пример #4
0
/**
  Write Nvm Express admin completion queue base address register.

  @param  Private          The pointer to the NVME_CONTROLLER_PRIVATE_DATA data structure.
  @param  Acq              The buffer used to store the content to be written into admin completion queue base address register.

  @return EFI_SUCCESS      Successfully write data into the admin completion queue base address register.
  @return EFI_DEVICE_ERROR Fail to write data into the admin completion queue base address register.

**/
EFI_STATUS
WriteNvmeAdminCompletionQueueBaseAddress (
  IN NVME_CONTROLLER_PRIVATE_DATA     *Private,
  IN NVME_ACQ                         *Acq
  )
{
  EFI_PCI_IO_PROTOCOL   *PciIo;
  EFI_STATUS            Status;
  UINT64                Data;

  PciIo  = Private->PciIo;
  Data   = ReadUnaligned64 ((UINT64*)Acq);

  Status = PciIo->Mem.Write (
                        PciIo,
                        EfiPciIoWidthUint32,
                        NVME_BAR,
                        NVME_ACQ_OFFSET,
                        2,
                        &Data
                        );

  if (EFI_ERROR(Status)) {
    return Status;
  }

  DEBUG ((EFI_D_INFO, "Acq: %lxh\n", *Acq));

  return EFI_SUCCESS;
}
Пример #5
0
/**

  Override function for SDHCI capability bits

  @param[in]      PassThru              A pointer to the
                                        EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
  @param[in]      ControllerHandle      The EFI_HANDLE of the controller.
  @param[in]      Slot                  The 0 based slot index.
  @param[in,out]  SdMmcHcSlotCapability The SDHCI capability structure.

  @retval EFI_SUCCESS           The override function completed successfully.
  @retval EFI_NOT_FOUND         The specified controller or slot does not exist.
  @retval EFI_INVALID_PARAMETER SdMmcHcSlotCapability is NULL

**/
STATIC
EFI_STATUS
EFIAPI
SynQuacerSdMmcCapability (
  IN      EFI_HANDLE                      ControllerHandle,
  IN      UINT8                           Slot,
  IN  OUT VOID                            *SdMmcHcSlotCapability
  )
{
  UINT64 Capability;

  if (ControllerHandle != mSdMmcControllerHandle) {
    return EFI_SUCCESS;
  }

  ASSERT (Slot == 0);

  //
  // Clear the SDR104 capability bit. This avoids the need for a HS200 tuning
  // quirk that is difficult to support using the generic driver.
  // Clear the DDR50 bit as well to work around an issue with the Kingston
  // EMMC08G-M325-A52 part that was fitted on 96board DeveloperBox samples.
  //
  Capability = ReadUnaligned64 (SdMmcHcSlotCapability);
  Capability &= ~(UINT64)(SD_HC_CAP_SDR104 | SD_HC_CAP_DDR50);
  WriteUnaligned64 (SdMmcHcSlotCapability, Capability);

  return EFI_SUCCESS;
}
Пример #6
0
Файл: Pcd.c Проект: b-man/edk2
/**
  Retrieves an 64-bit value for a given PCD token.

  Retrieves the current 64-bits value for a PCD token number.
  If the TokenNumber is invalid, the results are unpredictable.

  @param[in]  TokenNumber The PCD token number.

  @return The UINT64 value.

**/
UINT64
EFIAPI
DxePcdGet64 (
  IN UINTN                     TokenNumber
  )
{
  return ReadUnaligned64(GetWorker (TokenNumber, sizeof (UINT64)));
}
Пример #7
0
Файл: Pcd.c Проект: b-man/edk2
/**
  Retrieves an 64-bit value for a given PCD token.

  Retrieves the 64-bit value of a particular PCD token.
  If the TokenNumber is invalid or the token space
  specified by Guid does not exist, the results are
  unpredictable.

  @param[in]  Guid The token space for the token number.
  @param[in]  ExTokenNumber The PCD token number.

  @return The size 64-bit value for the PCD token.

**/
UINT64
EFIAPI
DxePcdGet64Ex (
  IN CONST EFI_GUID        *Guid,
  IN UINTN                 ExTokenNumber
  )
{
  return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof(UINT64)));
}
Пример #8
0
/**
  Compares two GUIDs.

  This function compares Guid1 to Guid2.  If the GUIDs are identical then TRUE is returned.
  If there are any bit differences in the two GUIDs, then FALSE is returned.
  
  If Guid1 is NULL, then ASSERT().
  If Guid2 is NULL, then ASSERT().

  @param  Guid1       A pointer to a 128 bit GUID.
  @param  Guid2       A pointer to a 128 bit GUID.

  @retval TRUE        Guid1 and Guid2 are identical.
  @retval FALSE       Guid1 and Guid2 are not identical.

**/
BOOLEAN
EFIAPI
CompareGuid (
  IN CONST GUID  *Guid1,
  IN CONST GUID  *Guid2
  )
{
  UINT64  LowPartOfGuid1;
  UINT64  LowPartOfGuid2;
  UINT64  HighPartOfGuid1;
  UINT64  HighPartOfGuid2;

  LowPartOfGuid1  = ReadUnaligned64 ((CONST UINT64*) Guid1);
  LowPartOfGuid2  = ReadUnaligned64 ((CONST UINT64*) Guid2);
  HighPartOfGuid1 = ReadUnaligned64 ((CONST UINT64*) Guid1 + 1);
  HighPartOfGuid2 = ReadUnaligned64 ((CONST UINT64*) Guid2 + 1);

  return (BOOLEAN) (LowPartOfGuid1 == LowPartOfGuid2 && HighPartOfGuid1 == HighPartOfGuid2);
}
Пример #9
0
/**
  Writes memory-mapped registers.

  @param[in]  PeiServices  An indirect pointer to the PEI Services Table
                           published by the PEI Foundation.
  @param[in]  This         Pointer to local data for the interface.
  @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 function completed successfully.
  @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
EFIAPI
CpuMemoryServiceWrite (
  IN CONST EFI_PEI_SERVICES    **PeiServices,
  IN CONST EFI_PEI_CPU_IO_PPI  *This,
  IN EFI_PEI_CPU_IO_PPI_WIDTH  Width,
  IN UINT64                    Address,
  IN UINTN                     Count,
  IN VOID                      *Buffer
  )
{
  EFI_STATUS                Status;
  UINT8                     InStride;
  UINT8                     OutStride;
  EFI_PEI_CPU_IO_PPI_WIDTH  OperationWidth;
  BOOLEAN                   Aligned;
  UINT8                     *Uint8Buffer;

  Status = CpuIoCheckParameter (TRUE, Width, Address, Count, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Select loop based on the width of the transfer
  //
  InStride = mInStride[Width];
  OutStride = mOutStride[Width];
  OperationWidth = (EFI_PEI_CPU_IO_PPI_WIDTH) (Width & 0x03);
  Aligned = (BOOLEAN)(((UINTN)Buffer & (mInStride[OperationWidth] - 1)) == 0x00);
  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
    if (OperationWidth == EfiPeiCpuIoWidthUint8) {
      MmioWrite8 ((UINTN)Address, *Uint8Buffer);
    } else if (OperationWidth == EfiPeiCpuIoWidthUint16) {
      if (Aligned) {
        MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
      } else {
        MmioWrite16 ((UINTN)Address, ReadUnaligned16 ((UINT16 *)Uint8Buffer));
      }
    } else if (OperationWidth == EfiPeiCpuIoWidthUint32) {
      if (Aligned) {
        MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
      } else {
        MmioWrite32 ((UINTN)Address, ReadUnaligned32 ((UINT32 *)Uint8Buffer));
      }
    } else if (OperationWidth == EfiPeiCpuIoWidthUint64) {
      if (Aligned) {
        MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
      } else {
        MmioWrite64 ((UINTN)Address, ReadUnaligned64 ((UINT64 *)Uint8Buffer));
      }
    }
  }
  return EFI_SUCCESS;
}
Пример #10
0
VOID
ArmPlatformGetGlobalVariable (
  IN  UINTN     VariableOffset,
  IN  UINTN     VariableSize,
  OUT VOID*     Variable
  )
{
  UINTN  GlobalVariableBase;

  // Ensure the Global Variable Size have been initialized
  ASSERT (VariableOffset < PcdGet32 (PcdSecGlobalVariableSize));

  GlobalVariableBase = PcdGet32 (PcdCPUCoresSecStackBase) + PcdGet32 (PcdCPUCoreSecPrimaryStackSize) - PcdGet32 (PcdSecGlobalVariableSize);
  
  if (VariableSize == 4) {
    *(UINT32*)Variable = ReadUnaligned32 ((CONST UINT32*)(GlobalVariableBase + VariableOffset));
  } else if (VariableSize == 8) {
    *(UINT64*)Variable = ReadUnaligned64 ((CONST UINT64*)(GlobalVariableBase + VariableOffset));
  } else {
    CopyMem (Variable, (VOID*)(GlobalVariableBase + VariableOffset), VariableSize);
  }
}
Пример #11
0
/**

  Get the fixed loadding address from image header assigned by build tool. This function only be called
  when Loading module at Fixed address feature enabled.

  @param ImageContext              Pointer to the image context structure that describes the PE/COFF
                                    image that needs to be examined by this function.
  @param Private                    Pointer to the private data passed in from caller

  @retval EFI_SUCCESS               An fixed loading address is assigned to this image by build tools .
  @retval EFI_NOT_FOUND             The image has no assigned fixed loadding address.

**/
EFI_STATUS
GetPeCoffImageFixLoadingAssignedAddress(
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,
  IN     PEI_CORE_INSTANCE             *Private
  )
{
   UINTN                              SectionHeaderOffset;
   EFI_STATUS                         Status;
   EFI_IMAGE_SECTION_HEADER           SectionHeader;
   EFI_IMAGE_OPTIONAL_HEADER_UNION    *ImgHdr;
   EFI_PHYSICAL_ADDRESS               FixLoaddingAddress;
   UINT16                             Index;
   UINTN                              Size;
   UINT16                             NumberOfSections;
   UINT64                             ValueInSectionHeader;
 

   FixLoaddingAddress = 0;
   Status = EFI_NOT_FOUND;

   //
   // Get PeHeader pointer
   //
   ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
   if (ImageContext->IsTeImage) {
     //
     // for TE image, the fix loadding address is saved in first section header that doesn't point
     // to code section.
     //
     SectionHeaderOffset = sizeof (EFI_TE_IMAGE_HEADER);
     NumberOfSections = ImgHdr->Te.NumberOfSections;
   } else {
     SectionHeaderOffset = (UINTN)(
                                 ImageContext->PeCoffHeaderOffset +
                                 sizeof (UINT32) +
                                 sizeof (EFI_IMAGE_FILE_HEADER) +
                                 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
                                 );
      NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
   }
   //
   // Get base address from the first section header that doesn't point to code section.
   //
   for (Index = 0; Index < NumberOfSections; Index++) {
     //
     // Read section header from file
     //
     Size = sizeof (EFI_IMAGE_SECTION_HEADER);
     Status = ImageContext->ImageRead (
                              ImageContext->Handle,
                              SectionHeaderOffset,
                              &Size,
                              &SectionHeader
                              );
     if (EFI_ERROR (Status)) {
       return Status;
     }

     Status = EFI_NOT_FOUND;

     if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
       //
       // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
       // that doesn't point to code section in image header, as well as ImageBase field of image header. A notable thing is
       // that for PEIM, the value in ImageBase field may not be equal to the value in PointerToRelocations & PointerToLineNumbers because
       // for XIP PEIM, ImageBase field holds the image base address running on the Flash. And PointerToRelocations & PointerToLineNumbers
       // hold the image base address when it is shadow to the memory. And there is an assumption that when the feature is enabled, if a
       // module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers fields should NOT be Zero, or
       // else, these 2 fileds should be set to Zero
       //
       ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations);
       if (ValueInSectionHeader != 0) {
         //
         // Found first section header that doesn't point to code section.
         //
         if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0) {
           //
           // When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field
           // hold the absolute address of image base runing in memory
           //
           FixLoaddingAddress = ValueInSectionHeader;
         } else {
           //
           // When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field
           // hold the offset relative to a platform-specific top address.
           //
           FixLoaddingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + (INT64)ValueInSectionHeader);
         }
         //
         // Check if the memory range is avaliable.
         //
         Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoaddingAddress, (UINT32) ImageContext->ImageSize);
         if (!EFI_ERROR(Status)) {
           //
           // The assigned address is valid. Return the specified loadding address
           //
           ImageContext->ImageAddress = FixLoaddingAddress;
         }
       }
       break;
     }
     SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
   }
   DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoaddingAddress, Status));
   return Status;
}
Пример #12
0
/**
  Get the fixed loadding address from image header assigned by build tool. This function only be called 
  when Loading module at Fixed address feature enabled.
  
  @param  ImageContext              Pointer to the image context structure that describes the PE/COFF
                                    image that needs to be examined by this function.
  @retval EFI_SUCCESS               An fixed loading address is assigned to this image by build tools .
  @retval EFI_NOT_FOUND             The image has no assigned fixed loadding address.

**/
EFI_STATUS
GetPeCoffImageFixLoadingAssignedAddress(
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
  )
{
	 UINTN                              SectionHeaderOffset;
	 EFI_STATUS                         Status;
	 EFI_IMAGE_SECTION_HEADER           SectionHeader;
	 EFI_IMAGE_OPTIONAL_HEADER_UNION    *ImgHdr;
	 EFI_PHYSICAL_ADDRESS               FixLoaddingAddress;
	 UINT16                             Index;
	 UINTN                              Size; 
	 UINT16                             NumberOfSections;
	 UINT64                             ValueInSectionHeader;
	 
	 FixLoaddingAddress = 0;
	 Status = EFI_NOT_FOUND;
	
	 //
   // Get PeHeader pointer
   //
   ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
	 SectionHeaderOffset = (UINTN)(
                                 ImageContext->PeCoffHeaderOffset +
                                 sizeof (UINT32) +
                                 sizeof (EFI_IMAGE_FILE_HEADER) +
                                 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
                                 );
   NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
     
   //
   // Get base address from the first section header that doesn't point to code section.
   //
   for (Index = 0; Index < NumberOfSections; Index++) {
     //
     // Read section header from file
     //
     Size = sizeof (EFI_IMAGE_SECTION_HEADER);
     Status = ImageContext->ImageRead (
                              ImageContext->Handle,
                              SectionHeaderOffset,
                              &Size,
                              &SectionHeader
                              );
     if (EFI_ERROR (Status)) {
       return Status;
     }
     
     Status = EFI_NOT_FOUND;
     
     if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
       //
       // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header 
       // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,
       // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields
       // should not be Zero, or else, these 2 fileds should be set to Zero
       //
       ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations);
       if (ValueInSectionHeader != 0) {
         //
         // Found first section header that doesn't point to code section in which uild tool saves the
         // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
         //      
         FixLoaddingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);
         //
         // Check if the memory range is avaliable.
         //
         Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoaddingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
         if (!EFI_ERROR(Status)) {
           //
           // The assigned address is valid. Return the specified loadding address
           //
           ImageContext->ImageAddress = FixLoaddingAddress;
         }
       }
       break;     
     }
     SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);     
   }
   DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoaddingAddress, Status));
   return Status;
}
Пример #13
0
EFI_STATUS
NorFlashPlatformGetDevices (
  OUT NOR_FLASH_DESCRIPTION   **NorFlashDescriptions,
  OUT UINT32                  *Count
  )
{
  FDT_CLIENT_PROTOCOL         *FdtClient;
  INT32                       Node;
  EFI_STATUS                  Status;
  EFI_STATUS                  FindNodeStatus;
  CONST UINT32                *Reg;
  UINT32                      PropSize;
  UINT32                      Num;
  UINT64                      Base;
  UINT64                      Size;

  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
                  (VOID **)&FdtClient);
  ASSERT_EFI_ERROR (Status);

  Num = 0;
  for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient,
                                     "cfi-flash", &Node);
       !EFI_ERROR (FindNodeStatus) && Num < MAX_FLASH_BANKS;
       FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient,
                                     "cfi-flash", Node, &Node)) {

    Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",
                          (CONST VOID **)&Reg, &PropSize);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",
        __FUNCTION__, Status));
      continue;
    }

    ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);

    while (PropSize >= (4 * sizeof (UINT32)) && Num < MAX_FLASH_BANKS) {
      Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
      Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
      Reg += 4;

      PropSize -= 4 * sizeof (UINT32);

      //
      // Disregard any flash devices that overlap with the primary FV.
      // The firmware is not updatable from inside the guest anyway.
      //
      if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) &&
          (Base + Size) > PcdGet64 (PcdFvBaseAddress)) {
        continue;
      }

      mNorFlashDevices[Num].DeviceBaseAddress = (UINTN)Base;
      mNorFlashDevices[Num].RegionBaseAddress = (UINTN)Base;
      mNorFlashDevices[Num].Size              = (UINTN)Size;
      mNorFlashDevices[Num].BlockSize         = QEMU_NOR_BLOCK_SIZE;
      Num++;
    }
  }

  *NorFlashDescriptions = mNorFlashDevices;
  *Count = Num;

  return EFI_SUCCESS;
}
Пример #14
0
/**
  Initialize the system (or sometimes called permanent) memory

  This memory is generally represented by the DRAM.

  This function is called from InitializeMemory() in MemoryInitPeim, in the PEI
  phase.
**/
VOID
ArmPlatformInitializeSystemMemory (
  VOID
  )
{
  VOID         *DeviceTreeBase;
  INT32        Node, Prev;
  UINT64       NewBase;
  UINT64       NewSize;
  CONST CHAR8  *Type;
  INT32        Len;
  CONST UINT64 *RegProp;

  NewBase = 0;
  NewSize = 0;

  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
  ASSERT (DeviceTreeBase != NULL);

  //
  // Make sure we have a valid device tree blob
  //
  ASSERT (fdt_check_header (DeviceTreeBase) == 0);

  //
  // Look for a memory node
  //
  for (Prev = 0;; Prev = Node) {
    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
    if (Node < 0) {
      break;
    }

    //
    // Check for memory node
    //
    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
      //
      // Get the 'reg' property of this node. For now, we will assume
      // two 8 byte quantities for base and size, respectively.
      //
      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
      if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {

        NewBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
        NewSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));

        //
        // Make sure the start of DRAM matches our expectation
        //
        ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
        PcdSet64 (PcdSystemMemorySize, NewSize);

        DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
               __FUNCTION__, NewBase, NewBase + NewSize - 1));
      } else {
        DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
               __FUNCTION__));
      }
      break;
    }
  }

  //
  // We need to make sure that the machine we are running on has at least
  // 128 MB of memory configured, and is currently executing this binary from
  // NOR flash. This prevents a device tree image in DRAM from getting
  // clobbered when our caller installs permanent PEI RAM, before we have a
  // chance of marking its location as reserved or copy it to a freshly
  // allocated block in the permanent PEI RAM in the platform PEIM.
  //
  ASSERT (NewSize >= SIZE_128MB);
  ASSERT (
    (((UINT64)PcdGet64 (PcdFdBaseAddress) +
      (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||
    ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize)));
}
Пример #15
0
STATIC
UINT64
SerialPortGetBaseAddress (
  VOID
  )
{
  UINT64              BaudRate;
  UINT32              ReceiveFifoDepth;
  EFI_PARITY_TYPE     Parity;
  UINT8               DataBits;
  EFI_STOP_BITS_TYPE  StopBits;
  VOID                *DeviceTreeBase;
  INT32               Node, Prev;
  INT32               Len;
  CONST CHAR8         *Compatible;
  CONST CHAR8         *NodeStatus;
  CONST CHAR8         *CompatibleItem;
  CONST UINT64        *RegProperty;
  UINTN               UartBase;
  RETURN_STATUS       Status;

  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);

  if ((DeviceTreeBase == NULL) || (fdt_check_header (DeviceTreeBase) != 0)) {
    return 0;
  }

  //
  // Enumerate all FDT nodes looking for a PL011 and capture its base address
  //
  for (Prev = 0;; Prev = Node) {
    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
    if (Node < 0) {
      break;
    }

    Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
    if (Compatible == NULL) {
      continue;
    }

    //
    // Iterate over the NULL-separated items in the compatible string
    //
    for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len;
      CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) {

      if (AsciiStrCmp (CompatibleItem, "arm,pl011") == 0) {
        NodeStatus = fdt_getprop (DeviceTreeBase, Node, "status", &Len);
        if (NodeStatus != NULL && AsciiStrCmp (NodeStatus, "okay") != 0) {
          continue;
        }

        RegProperty = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
        if (Len != 16) {
          return 0;
        }
        UartBase = (UINTN)fdt64_to_cpu (ReadUnaligned64 (RegProperty));

        BaudRate = (UINTN)FixedPcdGet64 (PcdUartDefaultBaudRate);
        ReceiveFifoDepth = 0; // Use the default value for Fifo depth
        Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
        DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
        StopBits = (EFI_STOP_BITS_TYPE) FixedPcdGet8 (PcdUartDefaultStopBits);

        Status = PL011UartInitializePort (
                   UartBase,
                   FixedPcdGet32 (PL011UartClkInHz),
                   &BaudRate,
                   &ReceiveFifoDepth,
                   &Parity,
                   &DataBits,
                   &StopBits
                   );
        if (!EFI_ERROR (Status)) {
          return UartBase;
        }
      }
    }
  }
  return 0;
}
Пример #16
0
/**
  Execute READ CAPACITY 16 bytes command to request information regarding
  the capacity of the installed medium of the device.

  This function executes READ CAPACITY 16 bytes command to get the capacity
  of the USB mass storage media, including the presence, block size,
  and last block number.

  @param  UsbMass                The device to retireve disk gemotric.

  @retval EFI_SUCCESS            The disk geometry is successfully retrieved.
  @retval EFI_NOT_READY          The returned block size is zero.
  @retval Other                  READ CAPACITY 16 bytes command execution failed.

**/
EFI_STATUS
UsbBootReadCapacity16 (
  IN USB_MASS_DEVICE            *UsbMass
  )
{
  UINT8                         CapacityCmd[16];
  EFI_SCSI_DISK_CAPACITY_DATA16 CapacityData;
  EFI_BLOCK_IO_MEDIA            *Media;
  EFI_STATUS                    Status;
  UINT32                        BlockSize;

  Media   = &UsbMass->BlockIoMedia;

  Media->MediaPresent = FALSE;
  Media->LastBlock    = 0;
  Media->BlockSize    = 0;

  ZeroMem (CapacityCmd, sizeof (CapacityCmd));
  ZeroMem (&CapacityData, sizeof (CapacityData));

  CapacityCmd[0]  = EFI_SCSI_OP_READ_CAPACITY16;
  CapacityCmd[1]  = 0x10;
  //
  // Partial medium indicator, set the bytes 2 ~ 9 of the Cdb as ZERO.
  //
  ZeroMem ((CapacityCmd + 2), 8);

  CapacityCmd[13] = sizeof (CapacityData);

  Status = UsbBootExecCmdWithRetry (
             UsbMass,
             CapacityCmd,
             (UINT8) sizeof (CapacityCmd),
             EfiUsbDataIn,
             &CapacityData,
             sizeof (CapacityData),
             USB_BOOT_GENERAL_CMD_TIMEOUT
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the information on media presence, block size, and last block number
  // from READ CAPACITY data.
  //
  Media->MediaPresent = TRUE;
  Media->LastBlock    = SwapBytes64 (ReadUnaligned64 ((CONST UINT64 *) &(CapacityData.LastLba7)));

  BlockSize           = SwapBytes32 (ReadUnaligned32 ((CONST UINT32 *) &(CapacityData.BlockSize3)));

  Media->LowestAlignedLba = (CapacityData.LowestAlignLogic2 << 8) |
                             CapacityData.LowestAlignLogic1;
  Media->LogicalBlocksPerPhysicalBlock  = (1 << CapacityData.LogicPerPhysical);
  if (BlockSize == 0) {
    //
    //  Get sense data
    //
    return UsbBootRequestSense (UsbMass);
  } else {
    Media->BlockSize = BlockSize;
  }

  return Status;
}
Пример #17
0
/**
  Get the fixed loadding address from image header assigned by build tool. This function only be called
  when Loading module at Fixed address feature enabled.

  @param  ImageContext              Pointer to the image context structure that describes the PE/COFF
                                    image that needs to be examined by this function.
  @retval EFI_SUCCESS               An fixed loading address is assigned to this image by build tools .
  @retval EFI_NOT_FOUND             The image has no assigned fixed loadding address.
**/
EFI_STATUS
GetPeCoffImageFixLoadingAssignedAddress(
  IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
  )
{
   UINTN                              SectionHeaderOffset;
   EFI_STATUS                         Status;
   EFI_IMAGE_SECTION_HEADER           SectionHeader;
   EFI_IMAGE_OPTIONAL_HEADER_UNION    *ImgHdr;
   EFI_PHYSICAL_ADDRESS               FixLoaddingAddress;
   UINT16                             Index;
   UINTN                              Size;
   UINT16                             NumberOfSections;
   EFI_PHYSICAL_ADDRESS               SmramBase;
   UINT64                             SmmCodeSize;
   UINT64                             ValueInSectionHeader;
   //
   // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
   //
   SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32(PcdLoadFixAddressSmmCodePageNumber));
 
   FixLoaddingAddress = 0;
   Status = EFI_NOT_FOUND;
   SmramBase = mCurrentSmramRange->CpuStart;
   //
   // Get PeHeader pointer
   //
   ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
   SectionHeaderOffset = (UINTN)(
                                 ImageContext->PeCoffHeaderOffset +
                                 sizeof (UINT32) +
                                 sizeof (EFI_IMAGE_FILE_HEADER) +
                                 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
                                 );
   NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;

   //
   // Get base address from the first section header that doesn't point to code section.
   //
   for (Index = 0; Index < NumberOfSections; Index++) {
     //
     // Read section header from file
     //
     Size = sizeof (EFI_IMAGE_SECTION_HEADER);
     Status = ImageContext->ImageRead (
                              ImageContext->Handle,
                              SectionHeaderOffset,
                              &Size,
                              &SectionHeader
                              );
     if (EFI_ERROR (Status)) {
       return Status;
     }
     
     Status = EFI_NOT_FOUND;
     
     if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
       //
       // Build tool saves the offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields in the
       // first section header that doesn't point to code section in image header. And there is an assumption that when the
       // feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers
       // fields should NOT be Zero, or else, these 2 fileds should be set to Zero
       //
       ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations);
       if (ValueInSectionHeader != 0) {
         //
         // Found first section header that doesn't point to code section in which uild tool saves the
         // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
         //
         FixLoaddingAddress = (EFI_PHYSICAL_ADDRESS)(SmramBase + (INT64)ValueInSectionHeader);

         if (SmramBase + SmmCodeSize > FixLoaddingAddress && SmramBase <=  FixLoaddingAddress) {
           //
           // The assigned address is valid. Return the specified loadding address
           //
           ImageContext->ImageAddress = FixLoaddingAddress;
           Status = EFI_SUCCESS;
         }
       }
       break;
     }
     SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
   }
   DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoaddingAddress, Status));
   return Status;
}