Example #1
0
/**
  Allocate a block of memory to be used by the buffer pool.

  @param  Pool           The buffer pool to allocate memory for.
  @param  Pages          How many pages to allocate.

  @return The allocated memory block or NULL if failed.

**/
USBHC_MEM_BLOCK *
UsbHcAllocMemBlock (
  IN  USBHC_MEM_POOL      *Pool,
  IN  UINTN               Pages
  )
{
  USBHC_MEM_BLOCK         *Block;
  EFI_PCI_IO_PROTOCOL     *PciIo;
  VOID                    *BufHost;
  VOID                    *Mapping;
  EFI_PHYSICAL_ADDRESS    MappedAddr;
  UINTN                   Bytes;
  EFI_STATUS              Status;

  PciIo = Pool->PciIo;

  Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK));
  if (Block == NULL) {
    return NULL;
  }

  //
  // each bit in the bit array represents USBHC_MEM_UNIT
  // bytes of memory in the memory block.
  //
  ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);

  Block->BufLen   = EFI_PAGES_TO_SIZE (Pages);
  Block->BitsLen  = Block->BufLen / (USBHC_MEM_UNIT * 8);
  Block->Bits     = AllocateZeroPool (Block->BitsLen);

  if (Block->Bits == NULL) {
    gBS->FreePool (Block);
    return NULL;
  }

  //
  // Allocate the number of Pages of memory, then map it for
  // bus master read and write.
  //
  Status = PciIo->AllocateBuffer (
                    PciIo,
                    AllocateAnyPages,
                    EfiBootServicesData,
                    Pages,
                    &BufHost,
                    0
                    );

  if (EFI_ERROR (Status)) {
    goto FREE_BITARRAY;
  }

  Bytes = EFI_PAGES_TO_SIZE (Pages);
  Status = PciIo->Map (
                    PciIo,
                    EfiPciIoOperationBusMasterCommonBuffer,
                    BufHost,
                    &Bytes,
                    &MappedAddr,
                    &Mapping
                    );

  if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) {
    goto FREE_BUFFER;
  }

  //
  // Check whether the data structure used by the host controller
  // should be restricted into the same 4G
  //
  if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) {
    PciIo->Unmap (PciIo, Mapping);
    goto FREE_BUFFER;
  }

  Block->BufHost  = BufHost;
  Block->Buf      = (UINT8 *) ((UINTN) MappedAddr);
  Block->Mapping  = Mapping;

  return Block;

FREE_BUFFER:
  PciIo->FreeBuffer (PciIo, Pages, BufHost);

FREE_BITARRAY:
  gBS->FreePool (Block->Bits);
  gBS->FreePool (Block);
  return NULL;
}
Example #2
0
/**
  Parse the configuration descriptor and its interfaces.

  @param  DescBuf               The buffer of raw descriptor.
  @param  Len                   The length of the raw descriptor buffer.

  @return The created configuration descriptor.

**/
USB_CONFIG_DESC *
UsbParseConfigDesc (
  IN UINT8                *DescBuf,
  IN UINTN                Len
  )
{
  USB_CONFIG_DESC         *Config;
  USB_INTERFACE_SETTING   *Setting;
  USB_INTERFACE_DESC      *Interface;
  UINTN                   Index;
  UINTN                   NumIf;
  UINTN                   Consumed;

  ASSERT (DescBuf != NULL);

  Config = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_CONFIG, &Consumed);

  if (Config == NULL) {
    return NULL;
  }

  //
  // Initialize an array of setting for the configuration's interfaces.
  //
  NumIf               = Config->Desc.NumInterfaces;
  Config->Interfaces  = AllocateZeroPool (sizeof (USB_INTERFACE_DESC *) * NumIf);

  if (Config->Interfaces == NULL) {
    goto ON_ERROR;
  }

  DEBUG (( EFI_D_INFO, "UsbParseConfigDesc: config %d has %d interfaces\n",
                Config->Desc.ConfigurationValue, (UINT32)NumIf));

  for (Index = 0; Index < NumIf; Index++) {
    Interface = AllocateZeroPool (sizeof (USB_INTERFACE_DESC));

    if (Interface == NULL) {
      goto ON_ERROR;
    }

    Config->Interfaces[Index] = Interface;
  }

  //
  // If a configuration has several interfaces, these interfaces are
  // numbered from zero to n. If a interface has several settings,
  // these settings are also number from zero to m. The interface
  // setting must be organized as |interface 0, setting 0|interface 0
  // setting 1|interface 1, setting 0|interface 2, setting 0|. Check
  // USB2.0 spec, page 267.
  //
  DescBuf += Consumed;
  Len     -= Consumed;

  //
  // Make allowances for devices that return extra data at the
  // end of their config descriptors
  //
  while (Len >= sizeof (EFI_USB_INTERFACE_DESCRIPTOR)) {
    Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed);

    if (Setting == NULL) {
      DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));
      break;

    } else if (Setting->Desc.InterfaceNumber >= NumIf) {
      DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: mal-formated interface descriptor\n"));

      UsbFreeInterfaceDesc (Setting);
      goto ON_ERROR;
    }

    //
    // Insert the descriptor to the corresponding set.
    //
    Interface = Config->Interfaces[Setting->Desc.InterfaceNumber];

    if (Interface->NumOfSetting >= USB_MAX_INTERFACE_SETTING) {
      goto ON_ERROR;
    }

    Interface->Settings[Interface->NumOfSetting] = Setting;
    Interface->NumOfSetting++;

    DescBuf += Consumed;
    Len     -= Consumed;
  }

  return Config;

ON_ERROR:
  UsbFreeConfigDesc (Config);
  return NULL;
}
Example #3
0
/**
  The user code starts with this function.

  @param  FileHandle             Handle of the file being invoked.
  @param  PeiServices            Describes the list of possible PEI Services.

  @retval EFI_SUCCESS            The driver is successfully initialized.
  @retval Others                 Can't initialize the driver.

**/
EFI_STATUS
EFIAPI
InitializeSdMmcHcPeim (
  IN EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES    **PeiServices
  )
{
  EFI_BOOT_MODE                BootMode;
  EFI_STATUS                   Status;
  UINT16                       Bus;
  UINT16                       Device;
  UINT16                       Function;
  UINT32                       Size;
  UINT64                       MmioSize;
  UINT8                        SubClass;
  UINT8                        BaseClass;
  UINT8                        SlotInfo;
  UINT8                        SlotNum;
  UINT8                        FirstBar;
  UINT8                        Index;
  UINT8                        Slot;
  UINT32                       BarAddr;
  SD_MMC_HC_PEI_PRIVATE_DATA   *Private;

  //
  // Shadow this PEIM to run from memory
  //
  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
    return EFI_SUCCESS;
  }

  Status = PeiServicesGetBootMode (&BootMode);
  ///
  /// We do not expose this in S3 boot path, because it is only for recovery.
  ///
  if (BootMode == BOOT_ON_S3_RESUME) {
    return EFI_SUCCESS;
  }

  Private = (SD_MMC_HC_PEI_PRIVATE_DATA *) AllocateZeroPool (sizeof (SD_MMC_HC_PEI_PRIVATE_DATA));
  if (Private == NULL) {
    DEBUG ((EFI_D_ERROR, "Failed to allocate memory for SD_MMC_HC_PEI_PRIVATE_DATA! \n"));
    return EFI_OUT_OF_RESOURCES;
  }

  Private->Signature              = SD_MMC_HC_PEI_SIGNATURE;
  Private->SdMmcHostControllerPpi = mSdMmcHostControllerPpi;
  Private->PpiList                = mPpiList;
  Private->PpiList.Ppi            = &Private->SdMmcHostControllerPpi;

  BarAddr = PcdGet32 (PcdSdMmcPciHostControllerMmioBase);
  for (Bus = 0; Bus < 256; Bus++) {
    for (Device = 0; Device < 32; Device++) {
      for (Function = 0; Function < 8; Function++) {
        SubClass  = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0A));
        BaseClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0B));

        if ((SubClass == PCI_SUBCLASS_SD_HOST_CONTROLLER) && (BaseClass == PCI_CLASS_SYSTEM_PERIPHERAL)) {
          //
          // Get the SD/MMC Pci host controller's Slot Info.
          //
          SlotInfo = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, SD_MMC_HC_PEI_SLOT_OFFSET));
          FirstBar = (*(SD_MMC_HC_PEI_SLOT_INFO*)&SlotInfo).FirstBar;
          SlotNum  = (*(SD_MMC_HC_PEI_SLOT_INFO*)&SlotInfo).SlotNum + 1;
          ASSERT ((FirstBar + SlotNum) < MAX_SD_MMC_SLOTS);

          for (Index = 0, Slot = FirstBar; Slot < (FirstBar + SlotNum); Index++, Slot++) {
            //
            // Get the SD/MMC Pci host controller's MMIO region size.
            //
            PciAnd16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (UINT16)~(EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
            PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot), 0xFFFFFFFF);
            Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot));

            switch (Size & 0x07) {
              case 0x0:
                //
                // Memory space: anywhere in 32 bit address space
                //
                MmioSize = (~(Size & 0xFFFFFFF0)) + 1;
                break;
              case 0x4:
                //
                // Memory space: anywhere in 64 bit address space
                //
                MmioSize = Size & 0xFFFFFFF0;
                PciWrite32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0xFFFFFFFF);
                Size = PciRead32 (PCI_LIB_ADDRESS(Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4));      
                //
                // Fix the length to support some spefic 64 bit BAR
                //
                Size |= ((UINT32)(-1) << HighBitSet32 (Size));
                //
                // Calculate the size of 64bit bar
                //
                MmioSize  |= LShiftU64 ((UINT64) Size, 32);
                MmioSize  = (~(MmioSize)) + 1;
                //
                // Clean the high 32bits of this 64bit BAR to 0 as we only allow a 32bit BAR.
                //
                PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot + 4), 0);
                break;
              default:
                //
                // Unknown BAR type
                //
                ASSERT (FALSE);
                continue;
            };
            //
            // Assign resource to the SdMmc Pci host controller's MMIO BAR.
            // Enable the SdMmc Pci host controller by setting BME and MSE bits of PCI_CMD register.
            //
            PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4 * Slot), BarAddr);
            PciOr16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
            //
            // Record the allocated Mmio base address.
            //
            Private->MmioBar[Private->TotalSdMmcHcs].SlotNum++;
            Private->MmioBar[Private->TotalSdMmcHcs].MmioBarAddr[Index] = BarAddr;
            BarAddr += (UINT32)MmioSize;
          }
          Private->TotalSdMmcHcs++;
          ASSERT (Private->TotalSdMmcHcs < MAX_SD_MMC_HCS);
        }
      }
    }
  }

  ///
  /// Install SdMmc Host Controller PPI
  ///
  Status = PeiServicesInstallPpi (&Private->PpiList);

  ASSERT_EFI_ERROR (Status);
  return Status;
}
Example #4
0
/**
  Add an SMBIOS record.

  @param  This                  The EFI_SMBIOS_PROTOCOL instance.
  @param  ProducerHandle        The handle of the controller or driver associated with the SMBIOS information. NULL
                                means no handle.
  @param  SmbiosHandle          On entry, the handle of the SMBIOS record to add. If FFFEh, then a unique handle
                                will be assigned to the SMBIOS record. If the SMBIOS handle is already in use,
                                EFI_ALREADY_STARTED is returned and the SMBIOS record is not updated.
  @param  Record                The data for the fixed portion of the SMBIOS record. The format of the record is
                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined 
                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or 
                                a set of null terminated strings and a null.

  @retval EFI_SUCCESS           Record was added.
  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.
  @retval EFI_ALREADY_STARTED   The SmbiosHandle passed in was already in use.

**/
EFI_STATUS
EFIAPI
SmbiosAdd (
  IN CONST EFI_SMBIOS_PROTOCOL  *This,
  IN EFI_HANDLE                 ProducerHandle, OPTIONAL
  IN OUT EFI_SMBIOS_HANDLE      *SmbiosHandle,
  IN EFI_SMBIOS_TABLE_HEADER    *Record
  )
{
  VOID                        *Raw;
  UINTN                       TotalSize;
  UINTN                       RecordSize;
  UINTN                       StructureSize;
  UINTN                       NumberOfStrings;
  EFI_STATUS                  Status;
  LIST_ENTRY                  *Head;
  SMBIOS_INSTANCE             *Private;
  EFI_SMBIOS_ENTRY            *SmbiosEntry;
  EFI_SMBIOS_HANDLE           MaxSmbiosHandle;
  SMBIOS_HANDLE_ENTRY         *HandleEntry;
  EFI_SMBIOS_RECORD_HEADER    *InternalRecord;
  BOOLEAN                     Smbios32BitTable;
  BOOLEAN                     Smbios64BitTable;
  
  if (SmbiosHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  Private = SMBIOS_INSTANCE_FROM_THIS (This);
  //
  // Check whether SmbiosHandle is already in use
  //
  Head = &Private->AllocatedHandleListHead;
  if (*SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED && CheckSmbiosHandleExistance(Head, *SmbiosHandle)) {
    return EFI_ALREADY_STARTED;
  }

  //
  // when SmbiosHandle is 0xFFFE, an available handle will be assigned
  //
  if (*SmbiosHandle == SMBIOS_HANDLE_PI_RESERVED) {
    Status = GetAvailableSmbiosHandle(This, SmbiosHandle);
    if (EFI_ERROR(Status)) {
      return Status;
    }
  } else {
    //
    // Check this handle validity
    //
    GetMaxSmbiosHandle(This, &MaxSmbiosHandle);
    if (*SmbiosHandle > MaxSmbiosHandle) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Calculate record size and string number
  //
  Status = GetSmbiosStructureSize(This, Record, &StructureSize, &NumberOfStrings);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  Smbios32BitTable = FALSE;
  Smbios64BitTable = FALSE;
  if ((This->MajorVersion < 0x3) || 
      ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) {
    //
    // For SMBIOS 32-bit table, the length of the entire structure table (including all strings) must be reported
    // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
    // which is a WORD field limited to 65,535 bytes. So the max size of 32-bit table should not exceed 65,535 bytes.
    //
    if ((EntryPointStructure != NULL) && 
        (EntryPointStructure->TableLength + StructureSize > SMBIOS_TABLE_MAX_LENGTH)) {
      DEBUG ((EFI_D_INFO, "SmbiosAdd: Total length exceeds max 32-bit table length with type = %d size = 0x%x\n", Record->Type, StructureSize));
    } else {
      Smbios32BitTable = TRUE;
      DEBUG ((EFI_D_INFO, "SmbiosAdd: Smbios type %d with size 0x%x is added to 32-bit table\n", Record->Type, StructureSize));
    }
  }
  
  //
  // For SMBIOS 3.0, Structure table maximum size in Entry Point structure is DWORD field limited to 0xFFFFFFFF bytes.
  //
  if ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) {
    //
    // For SMBIOS 64-bit table, Structure table maximum size in SMBIOS 3.0 (64-bit) Entry Point
    // is a DWORD field limited to 0xFFFFFFFF bytes. So the max size of 64-bit table should not exceed 0xFFFFFFFF bytes.
    //
    if ((Smbios30EntryPointStructure != NULL) && 
        (Smbios30EntryPointStructure->TableMaximumSize + StructureSize > SMBIOS_3_0_TABLE_MAX_LENGTH)) {
      DEBUG ((EFI_D_INFO, "SmbiosAdd: Total length exceeds max 64-bit table length with type = %d size = 0x%x\n", Record->Type, StructureSize));
    } else {
      DEBUG ((EFI_D_INFO, "SmbiosAdd: Smbios type %d with size 0x%x is added to 64-bit table\n", Record->Type, StructureSize));
      Smbios64BitTable = TRUE;
    }
  }

  if ((!Smbios32BitTable) && (!Smbios64BitTable)) {
    //
    // If both 32-bit and 64-bit table are not updated, quit
    //
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Enter into critical section
  //  
  Status = EfiAcquireLockOrFail (&Private->DataLock);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  RecordSize  = sizeof (EFI_SMBIOS_RECORD_HEADER) + StructureSize;
  TotalSize   = sizeof (EFI_SMBIOS_ENTRY) + RecordSize;

  //
  // Allocate internal buffer
  //
  SmbiosEntry = AllocateZeroPool (TotalSize);
  if (SmbiosEntry == NULL) {
    EfiReleaseLock (&Private->DataLock);
    return EFI_OUT_OF_RESOURCES;
  }
  HandleEntry = AllocateZeroPool (sizeof(SMBIOS_HANDLE_ENTRY));
  if (HandleEntry == NULL) {
    EfiReleaseLock (&Private->DataLock);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Build Handle Entry and insert into linked list
  //
  HandleEntry->Signature     = SMBIOS_HANDLE_ENTRY_SIGNATURE;
  HandleEntry->SmbiosHandle  = *SmbiosHandle;
  InsertTailList(&Private->AllocatedHandleListHead, &HandleEntry->Link);

  InternalRecord  = (EFI_SMBIOS_RECORD_HEADER *) (SmbiosEntry + 1);
  Raw     = (VOID *) (InternalRecord + 1);

  //
  // Build internal record Header
  //
  InternalRecord->Version     = EFI_SMBIOS_RECORD_HEADER_VERSION;
  InternalRecord->HeaderSize  = (UINT16) sizeof (EFI_SMBIOS_RECORD_HEADER);
  InternalRecord->RecordSize  = RecordSize;
  InternalRecord->ProducerHandle = ProducerHandle;
  InternalRecord->NumberOfStrings = NumberOfStrings;
  //
  // Insert record into the internal linked list
  //
  SmbiosEntry->Signature    = EFI_SMBIOS_ENTRY_SIGNATURE;
  SmbiosEntry->RecordHeader = InternalRecord;
  SmbiosEntry->RecordSize   = TotalSize;
  SmbiosEntry->Smbios32BitTable = Smbios32BitTable;
  SmbiosEntry->Smbios64BitTable = Smbios64BitTable;
  InsertTailList (&Private->DataListHead, &SmbiosEntry->Link);

  CopyMem (Raw, Record, StructureSize);
  ((EFI_SMBIOS_TABLE_HEADER*)Raw)->Handle = *SmbiosHandle;

  //
  // Some UEFI drivers (such as network) need some information in SMBIOS table.
  // Here we create SMBIOS table and publish it in
  // configuration table, so other UEFI drivers can get SMBIOS table from
  // configuration table without depending on PI SMBIOS protocol.
  //
  SmbiosTableConstruction (Smbios32BitTable, Smbios64BitTable);
  
  //
  // Leave critical section
  //
  EfiReleaseLock (&Private->DataLock);
  return EFI_SUCCESS;
}
Example #5
0
/**
  Create a descriptor.

  @param  DescBuf               The buffer of raw descriptor.
  @param  Len                   The length of the raw descriptor buffer.
  @param  Type                  The type of descriptor to create.
  @param  Consumed              Number of bytes consumed.

  @return Created descriptor or NULL.

**/
VOID *
UsbCreateDesc (
  IN  UINT8               *DescBuf,
  IN  UINTN               Len,
  IN  UINT8               Type,
  OUT UINTN               *Consumed
  )
{
  USB_DESC_HEAD           *Head;
  UINTN                   DescLen;
  UINTN                   CtrlLen;
  UINTN                   Offset;
  VOID                    *Desc;

  DescLen   = 0;
  CtrlLen   = 0;
  *Consumed = 0;

  switch (Type) {
  case USB_DESC_TYPE_DEVICE:
    DescLen = sizeof (EFI_USB_DEVICE_DESCRIPTOR);
    CtrlLen = sizeof (USB_DEVICE_DESC);
    break;

  case USB_DESC_TYPE_CONFIG:
    DescLen = sizeof (EFI_USB_CONFIG_DESCRIPTOR);
    CtrlLen = sizeof (USB_CONFIG_DESC);
    break;

  case USB_DESC_TYPE_INTERFACE:
    DescLen = sizeof (EFI_USB_INTERFACE_DESCRIPTOR);
    CtrlLen = sizeof (USB_INTERFACE_SETTING);
    break;

  case USB_DESC_TYPE_ENDPOINT:
    DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);
    CtrlLen = sizeof (USB_ENDPOINT_DESC);
    break;

  default:
    ASSERT (FALSE);
    return NULL;
  }

  //
  // Total length is too small that cannot hold the single descriptor header plus data.
  //
  if (Len <= sizeof (USB_DESC_HEAD)) {
    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len));
    return NULL;
  }

  //
  // All the descriptor has a common LTV (Length, Type, Value)
  // format. Skip the descriptor that isn't of this Type
  //
  Offset = 0;
  Head   = (USB_DESC_HEAD *)DescBuf;
  while (Offset < Len - sizeof (USB_DESC_HEAD)) {
    //
    // Above condition make sure Head->Len and Head->Type are safe to access
    //
    Head = (USB_DESC_HEAD *)&DescBuf[Offset];

    if (Head->Len == 0) {
      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
      return NULL;
    }

    //
    // Make sure no overflow when adding Head->Len to Offset.
    //
    if (Head->Len > MAX_UINTN - Offset) {
      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head->Len));
      return NULL;
    }

    Offset += Head->Len;

    if (Head->Type == Type) {
      break;
    }
  }

  //
  // Head->Len is invalid resulting data beyond boundary, or
  // Descriptor cannot be found: No such type.
  //
  if (Len < Offset) {
    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset, Len));
    return NULL;
  }

  if ((Head->Type != Type) || (Head->Len < DescLen)) {
    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head->Type, Head->Len));
    return NULL;
  }

  Desc = AllocateZeroPool ((UINTN) CtrlLen);
  if (Desc == NULL) {
    return NULL;
  }

  CopyMem (Desc, Head, (UINTN) DescLen);

  *Consumed = Offset;

  return Desc;
}
Example #6
0
/**
  Find the EFI_HII_HANDLE by device path.

  @param[in] DevPath1     The Device Path to match.
  @param[out] HiiHandle   The EFI_HII_HANDLE after the converstion.
  @param[in] HiiDb        The Hii database protocol

  @retval EFI_SUCCESS     The operation was successful.
  @retval EFI_NOT_FOUND   There was no EFI_HII_HANDLE found for that deviec path.
**/
EFI_STATUS
EFIAPI
FindHiiHandleViaDevPath(
  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath1,
  OUT EFI_HII_HANDLE                *HiiHandle,
  IN EFI_HII_DATABASE_PROTOCOL      *HiiDb
  )
{
  EFI_HII_HANDLE                *HandleBuffer;
  UINTN                         HandleBufferSize;
  VOID                          *MainBuffer;
  UINTN                         MainBufferSize;
  EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
  EFI_HII_PACKAGE_HEADER        *PackageHeader;
  UINTN                         LoopVariable;
  EFI_DEVICE_PATH_PROTOCOL      *DevPath2;
  EFI_STATUS                    Status;

  ASSERT(DevPath1 != NULL);
  ASSERT(HiiHandle != NULL);
  ASSERT(*HiiHandle == NULL);
  ASSERT(HiiDb != NULL);

  HandleBufferSize  = 0;
  HandleBuffer      = NULL;
  Status = HiiDb->ListPackageLists(HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HandleBuffer = AllocateZeroPool(HandleBufferSize);
    ASSERT (HandleBuffer != NULL);
    Status = HiiDb->ListPackageLists(HiiDb, EFI_HII_PACKAGE_DEVICE_PATH, NULL, &HandleBufferSize, HandleBuffer);
  }
  if (EFI_ERROR(Status)) {
    SHELL_FREE_NON_NULL(HandleBuffer);
    return (Status);
  }

  if (HandleBuffer == NULL) {
    return EFI_NOT_FOUND;
  }

  for (LoopVariable = 0 ; LoopVariable < (HandleBufferSize/sizeof(HandleBuffer[0])) && *HiiHandle == NULL ; LoopVariable++) {
    MainBufferSize    = 0;
    MainBuffer        = NULL;
    Status = HiiDb->ExportPackageLists(HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
    if (Status == EFI_BUFFER_TOO_SMALL) {
      MainBuffer = AllocateZeroPool(MainBufferSize);
      ASSERT (MainBuffer != NULL);
      Status = HiiDb->ExportPackageLists(HiiDb, HandleBuffer[LoopVariable], &MainBufferSize, MainBuffer);
    }
    //
    // Enumerate through the block of returned memory.
    // This should actually be a small block, but we need to be sure.
    //
    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer
      ;  PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && *HiiHandle == NULL
      ;  PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) {
        for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER))
          ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END && *HiiHandle == NULL
          ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) {
            if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
              DevPath2 = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER));
              if (DevicePathCompare(&DevPath1, &DevPath2) == 0) {
                *HiiHandle = HandleBuffer[LoopVariable];
                break;
              }
            }
        }
    }
    SHELL_FREE_NON_NULL(MainBuffer);
  }
  SHELL_FREE_NON_NULL(HandleBuffer);

  if (*HiiHandle == NULL) {
    return (EFI_NOT_FOUND);
  }
  return (EFI_SUCCESS);
}
Example #7
0
File: UsbHub.c Project: Cutty/edk2
/**
  The callback function to the USB hub status change
  interrupt endpoint. It is called periodically by
  the underlying host controller.

  @param  Data                  The data read.
  @param  DataLength            The length of the data read.
  @param  Context               The context.
  @param  Result                The result of the last interrupt transfer.

  @retval EFI_SUCCESS           The process is OK.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource.

**/
EFI_STATUS
EFIAPI
UsbOnHubInterrupt (
  IN  VOID                *Data,
  IN  UINTN               DataLength,
  IN  VOID                *Context,
  IN  UINT32              Result
  )
{
  USB_INTERFACE               *HubIf;
  EFI_USB_IO_PROTOCOL         *UsbIo;
  EFI_USB_ENDPOINT_DESCRIPTOR *EpDesc;
  EFI_STATUS                  Status;

  HubIf   = (USB_INTERFACE *) Context;
  UsbIo   = &(HubIf->UsbIo);
  EpDesc  = &(HubIf->HubEp->Desc);

  if (Result != EFI_USB_NOERROR) {
    //
    // If endpoint is stalled, clear the stall. Use UsbIo to access
    // the control transfer so internal status are maintained.
    //
    if (USB_BIT_IS_SET (Result, EFI_USB_ERR_STALL)) {
      UsbIoClearFeature (
        UsbIo,
        USB_TARGET_ENDPOINT,
        USB_FEATURE_ENDPOINT_HALT,
        EpDesc->EndpointAddress
        );
    }

    //
    // Delete and submit a new async interrupt
    //
    Status = UsbIo->UsbAsyncInterruptTransfer (
                      UsbIo,
                      EpDesc->EndpointAddress,
                      FALSE,
                      0,
                      0,
                      NULL,
                      NULL
                      );

    if (EFI_ERROR (Status)) {
      DEBUG (( EFI_D_ERROR, "UsbOnHubInterrupt: failed to remove async transfer - %r\n", Status));
      return Status;
    }

    Status = UsbIo->UsbAsyncInterruptTransfer (
                      UsbIo,
                      EpDesc->EndpointAddress,
                      TRUE,
                      USB_HUB_POLL_INTERVAL,
                      HubIf->NumOfPort / 8 + 1,
                      UsbOnHubInterrupt,
                      HubIf
                      );

    if (EFI_ERROR (Status)) {
      DEBUG (( EFI_D_ERROR, "UsbOnHubInterrupt: failed to submit new async transfer - %r\n", Status));
    }

    return Status;
  }

  if ((DataLength == 0) || (Data == NULL)) {
    return EFI_SUCCESS;
  }

  //
  // OK, actually something is changed, save the change map
  // then signal the HUB to do enumeration. This is a good
  // practise since UsbOnHubInterrupt is called in the context
  // of host contrller's AsyncInterrupt monitor.
  //
  HubIf->ChangeMap = AllocateZeroPool (DataLength);

  if (HubIf->ChangeMap == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (HubIf->ChangeMap, Data, DataLength);
  gBS->SignalEvent (HubIf->HubNotify);

  return EFI_SUCCESS;
}
Example #8
0
/**
  This function allows a caller to extract the current configuration for one
  or more named elements from the target driver.


  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Request         A null-terminated Unicode string in <ConfigRequest> format.
  @param Progress        On return, points to a character in the Request string.
                         Points to the string's null terminator if request was successful.
                         Points to the most recent '&' before the first failing name/value
                         pair (or the beginning of the string if the failure is in the
                         first name/value pair) if the request was not successful.
  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which
                         has all values filled in for the names in the Request string.
                         String to be allocated by the called function.

  @retval  EFI_SUCCESS            The Results is filled with the requested values.
  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
  @retval  EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.
  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.

**/
EFI_STATUS
EFIAPI
BootMaintExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  CONST EFI_STRING                       Request,
  OUT EFI_STRING                             *Progress,
  OUT EFI_STRING                             *Results
  )
{
  EFI_STATUS         Status;
  UINTN              BufferSize;
  BMM_CALLBACK_DATA  *Private;
  EFI_STRING                       ConfigRequestHdr;
  EFI_STRING                       ConfigRequest;
  BOOLEAN                          AllocatedRequest;
  UINTN                            Size;

  if (Progress == NULL || Results == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  Private = BMM_CALLBACK_DATA_FROM_THIS (This);
  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
  //
  BufferSize = sizeof (BMM_FAKE_NV_DATA);
  ConfigRequest = Request;
  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
    //
    // Request has no request element, construct full request string.
    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
    //
    ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);
    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest = AllocateZeroPool (Size);
    ASSERT (ConfigRequest != NULL);
    AllocatedRequest = TRUE;
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
    FreePool (ConfigRequestHdr);
  }

  Status = gHiiConfigRouting->BlockToConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *) &Private->BmmFakeNvData,
                                BufferSize,
                                Results,
                                Progress
                                );
  //
  // Free the allocated config request string.
  //
  if (AllocatedRequest) {
    FreePool (ConfigRequest);
    ConfigRequest = NULL;
  }
  //
  // Set Progress string to the original request string.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return Status;
}
Example #9
0
/**
  Initialize the Boot Maintenance Utitliy.


  @retval  EFI_SUCCESS      utility ended successfully
  @retval  others           contain some errors

**/
EFI_STATUS
InitializeBM (
  VOID
  )
{
  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;
  BMM_CALLBACK_DATA           *BmmCallbackInfo;
  EFI_STATUS                  Status;
  UINT8                       *Ptr;

  Status = EFI_SUCCESS;

  //
  // Create CallbackData structures for Driver Callback
  //
  BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
  if (BmmCallbackInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Create LoadOption in BmmCallbackInfo for Driver Callback
  //
  Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
  if (Ptr == NULL) {
    FreePool (BmmCallbackInfo);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Initialize Bmm callback data.
  //
  BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
  Ptr += sizeof (BM_LOAD_CONTEXT);

  BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
  Ptr += sizeof (BM_FILE_CONTEXT);

  BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
  Ptr += sizeof (BM_HANDLE_CONTEXT);

  BmmCallbackInfo->MenuEntry      = (BM_MENU_ENTRY *) Ptr;

  BmmCallbackInfo->Signature                     = BMM_CALLBACK_DATA_SIGNATURE;
  BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
  BmmCallbackInfo->BmmConfigAccess.RouteConfig   = FakeRouteConfig;
  BmmCallbackInfo->BmmConfigAccess.Callback      = BootMaintCallback;
  BmmCallbackInfo->BmmPreviousPageId             = FORM_MAIN_ID;
  BmmCallbackInfo->BmmCurrentPageId              = FORM_MAIN_ID;
  BmmCallbackInfo->FeConfigAccess.ExtractConfig  = FakeExtractConfig;
  BmmCallbackInfo->FeConfigAccess.RouteConfig    = FakeRouteConfig;
  BmmCallbackInfo->FeConfigAccess.Callback       = FileExplorerCallback;
  BmmCallbackInfo->FeCurrentState                = FileExplorerStateInActive;
  BmmCallbackInfo->FeDisplayContext              = FileExplorerDisplayUnknown;

  //
  // Install Device Path Protocol and Config Access protocol to driver handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &BmmCallbackInfo->BmmDriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mBmmHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &BmmCallbackInfo->BmmConfigAccess,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Install Device Path Protocol and Config Access protocol to driver handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &BmmCallbackInfo->FeDriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mFeHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &BmmCallbackInfo->FeConfigAccess,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Post our Boot Maint VFR binary to the HII database.
  //
  BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
                                    &mBootMaintGuid,
                                    BmmCallbackInfo->BmmDriverHandle,
                                    BmBin,
                                    BdsDxeStrings,
                                    NULL
                                    );
  ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);

  //
  // Post our File Explorer VFR binary to the HII database.
  //
  BmmCallbackInfo->FeHiiHandle = HiiAddPackages (
                                   &mFileExplorerGuid,
                                   BmmCallbackInfo->FeDriverHandle,
                                   FEBin,
                                   BdsDxeStrings,
                                   NULL
                                   );
  ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);

  //
  // Init OpCode Handle and Allocate space for creation of Buffer
  //
  mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (mStartOpCodeHandle == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (mEndOpCodeHandle == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  mEndLabel->Number       = LABEL_END;

  InitializeStringDepository ();

  InitAllMenu (BmmCallbackInfo);

  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);

  UpdateBootDelPage (BmmCallbackInfo);
  UpdateDrvDelPage (BmmCallbackInfo);

  if (TerminalMenu.MenuNumber > 0) {
    BmmCallbackInfo->CurrentTerminal = 0;
    UpdateTerminalPage (BmmCallbackInfo);
  }

  Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
  if (!EFI_ERROR (Status)) {
    RefreshUpdateData ();
    mStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;

    //
    // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
    // in BootOption form: legacy FD/HD/CD/NET/BEV
    //
    HiiCreateGotoOpCode (
      mStartOpCodeHandle,
      FORM_SET_FD_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
      EFI_IFR_FLAG_CALLBACK,
      FORM_SET_FD_ORDER_ID
      );

    HiiCreateGotoOpCode (
      mStartOpCodeHandle,
      FORM_SET_HD_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
      EFI_IFR_FLAG_CALLBACK,
      FORM_SET_HD_ORDER_ID
      );

    HiiCreateGotoOpCode (
      mStartOpCodeHandle,
      FORM_SET_CD_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
      EFI_IFR_FLAG_CALLBACK,
      FORM_SET_CD_ORDER_ID
      );

    HiiCreateGotoOpCode (
      mStartOpCodeHandle,
      FORM_SET_NET_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
      EFI_IFR_FLAG_CALLBACK,
      FORM_SET_NET_ORDER_ID
      );

    HiiCreateGotoOpCode (
      mStartOpCodeHandle,
      FORM_SET_BEV_ORDER_ID,
      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
      EFI_IFR_FLAG_CALLBACK,
      FORM_SET_BEV_ORDER_ID
      );
    
    HiiUpdateForm (
      BmmCallbackInfo->BmmHiiHandle,
      &mBootMaintGuid,
      FORM_BOOT_SETUP_ID,
      mStartOpCodeHandle, // Label FORM_BOOT_LEGACY_DEVICE_ID
      mEndOpCodeHandle    // LABEL_END
      );
  }

  //
  // Dispatch BMM main formset and File Explorer formset.
  //
  FormSetDispatcher (BmmCallbackInfo);

  //
  // Remove our IFR data from HII database
  //
  HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);
  HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);

  CleanUpStringDepository ();

  FreeAllMenu ();

Exit:
  if (mStartOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (mStartOpCodeHandle);
  }

  if (mEndOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (mEndOpCodeHandle);
  }

  if (BmmCallbackInfo->FeDriverHandle != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           BmmCallbackInfo->FeDriverHandle,
           &gEfiDevicePathProtocolGuid,
           &mFeHiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &BmmCallbackInfo->FeConfigAccess,
           NULL
           );
  }

  if (BmmCallbackInfo->BmmDriverHandle != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           BmmCallbackInfo->BmmDriverHandle,
           &gEfiDevicePathProtocolGuid,
           &mBmmHiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &BmmCallbackInfo->BmmConfigAccess,
           NULL
           );
  }

  FreePool (BmmCallbackInfo->LoadContext);
  FreePool (BmmCallbackInfo);

  return Status;
}
Example #10
0
/**
  This function create a currently loaded Boot Option from 
  the BMM. It then appends this Boot Option to the end of 
  the "BootOrder" list. It also append this Boot Opotion to the end
  of BootOptionMenu.

  @param CallbackData    The BMM context data.
  @param NvRamMap        The file explorer formset internal state.

  @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
  @retval EFI_SUCCESS          If function completes successfully.

**/
EFI_STATUS
Var_UpdateBootOption (
  IN  BMM_CALLBACK_DATA                   *CallbackData,
  IN  FILE_EXPLORER_NV_DATA               *NvRamMap
  )
{
  UINT16          *BootOrderList;
  UINT16          *NewBootOrderList;
  UINTN           BootOrderListSize;
  UINT16          BootString[10];
  VOID            *Buffer;
  UINTN           BufferSize;
  UINT8           *Ptr;
  UINT16          Index;
  BM_MENU_ENTRY   *NewMenuEntry;
  BM_LOAD_CONTEXT *NewLoadContext;
  BOOLEAN         OptionalDataExist;
  EFI_STATUS      Status;

  OptionalDataExist = FALSE;

  Index = BOpt_GetBootOptionNumber () ;
  UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);

  if (NvRamMap->BootDescriptionData[0] == 0x0000) {
    StrCpyS (
      NvRamMap->BootDescriptionData,
      sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]),
      BootString
      );
  }

  BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->BootDescriptionData);
  BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);

  if (NvRamMap->BootOptionalData[0] != 0x0000) {
    OptionalDataExist = TRUE;
    BufferSize += StrSize (NvRamMap->BootOptionalData);
  }

  Buffer = AllocateZeroPool (BufferSize);
  if (NULL == Buffer) {
    return EFI_OUT_OF_RESOURCES;
  }

  NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
  if (NULL == NewMenuEntry) {
    return EFI_OUT_OF_RESOURCES;
  }

  NewLoadContext                  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
  NewLoadContext->Deleted         = FALSE;
  NewLoadContext->LoadOptionSize  = BufferSize;
  Ptr = (UINT8 *) Buffer;
  NewLoadContext->LoadOption = Ptr;
  *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
  NewLoadContext->Attributes = *((UINT32 *) Ptr);
  NewLoadContext->IsActive = TRUE;
  NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);

  Ptr += sizeof (UINT32);
  *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
  NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
  Ptr += sizeof (UINT16);

  CopyMem (
    Ptr,
    NvRamMap->BootDescriptionData,
    StrSize (NvRamMap->BootDescriptionData)
    );

  NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData));
  ASSERT (NewLoadContext->Description != NULL);

  NewMenuEntry->DisplayString = NewLoadContext->Description;
  CopyMem (
    NewLoadContext->Description,
    (VOID *) Ptr,
    StrSize (NvRamMap->BootDescriptionData)
    );

  Ptr += StrSize (NvRamMap->BootDescriptionData);
  CopyMem (
    Ptr,
    CallbackData->LoadContext->FilePathList,
    GetDevicePathSize (CallbackData->LoadContext->FilePathList)
    );

  NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
  ASSERT (NewLoadContext->FilePathList != NULL);

  CopyMem (
    NewLoadContext->FilePathList,
    (VOID *) Ptr,
    GetDevicePathSize (CallbackData->LoadContext->FilePathList)
    );

  NewMenuEntry->HelpString    = DevicePathToStr (NewLoadContext->FilePathList);
  NewMenuEntry->OptionNumber  = Index;
  NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
                                      CallbackData,
                                      BootOptionStrDepository
                                      );
  NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL);

  NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
                                    CallbackData,
                                    BootOptionHelpStrDepository
                                    );
  NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL);

  if (OptionalDataExist) {
    Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);

    CopyMem (Ptr, NvRamMap->BootOptionalData, StrSize (NvRamMap->BootOptionalData));
  }

  Status = gRT->SetVariable (
                  BootString,
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                  BufferSize,
                  Buffer
                  );
  if (!EFI_ERROR (Status)) {

    BootOrderList = BdsLibGetVariableAndSize (
                      L"BootOrder",
                      &gEfiGlobalVariableGuid,
                      &BootOrderListSize
                      );
    ASSERT (BootOrderList != NULL);
    NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
    ASSERT (NewBootOrderList != NULL);
    CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
    NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;

    if (BootOrderList != NULL) {
      FreePool (BootOrderList);
    }

    Status = gRT->SetVariable (
                    L"BootOrder",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    BootOrderListSize + sizeof (UINT16),
                    NewBootOrderList
                    );
    if (!EFI_ERROR (Status)) {

      FreePool (NewBootOrderList);
      NewBootOrderList = NULL;
      InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
      BootOptionMenu.MenuNumber++;

      //
      // Update "change driver order" page used data, append the new add driver
      // option at the end.
      //
      Index = 0;
      while (CallbackData->BmmFakeNvData.BootOptionOrder[Index] != 0) {
        Index++;
      }
      CallbackData->BmmFakeNvData.BootOptionOrder[Index] = (UINT32) (NewMenuEntry->OptionNumber + 1);

      NvRamMap->BootDescriptionData[0]  = 0x0000;
      NvRamMap->BootOptionalData[0]     = 0x0000;
    }
  }
  return EFI_SUCCESS;
}
Example #11
0
/**
  After any operation on Boot####, there will be a discrepancy in BootOrder.
  Since some are missing but in BootOrder, while some are present but are
  not reflected by BootOrder. Then a function rebuild BootOrder from
  scratch by content from BootOptionMenu is needed.


  

  @retval  EFI_SUCCESS  The boot order is updated successfully.
  @return               EFI_STATUS other than EFI_SUCCESS if failed to
                        Set the "BootOrder" EFI Variable.

**/
EFI_STATUS
Var_ChangeBootOrder (
  VOID
  )
{

  EFI_STATUS    Status;
  BM_MENU_ENTRY *NewMenuEntry;
  UINT16        *BootOrderList;
  UINT16        *BootOrderListPtr;
  UINTN         BootOrderListSize;
  UINTN         Index;

  BootOrderList     = NULL;
  BootOrderListSize = 0;

  //
  // First check whether BootOrder is present in current configuration
  //
  BootOrderList = BdsLibGetVariableAndSize (
                    L"BootOrder",
                    &gEfiGlobalVariableGuid,
                    &BootOrderListSize
                    );

  //
  // If exists, delete it to hold new BootOrder
  //
  if (BootOrderList != NULL) {
    EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
    FreePool (BootOrderList);
    BootOrderList = NULL;
  }
  //
  // Maybe here should be some check method to ensure that
  // no new added boot options will be added
  // but the setup engine now will give only one callback
  // that is to say, user are granted only one chance to
  // decide whether the boot option will be added or not
  // there should be no indictor to show whether this
  // is a "new" boot option
  //
  BootOrderListSize = BootOptionMenu.MenuNumber;

  if (BootOrderListSize > 0) {
    BootOrderList = AllocateZeroPool (BootOrderListSize * sizeof (UINT16));
    ASSERT (BootOrderList != NULL);
    BootOrderListPtr = BootOrderList;

    //
    // Get all current used Boot#### from BootOptionMenu.
    // OptionNumber in each BM_LOAD_OPTION is really its
    // #### value.
    //
    for (Index = 0; Index < BootOrderListSize; Index++) {
      NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
      *BootOrderList  = (UINT16) NewMenuEntry->OptionNumber;
      BootOrderList++;
    }

    BootOrderList = BootOrderListPtr;

    //
    // After building the BootOrderList, write it back
    //
    Status = gRT->SetVariable (
                    L"BootOrder",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    BootOrderListSize * sizeof (UINT16),
                    BootOrderList
                    );
    //
    // Changing variable without increasing its size with current variable implementation shouldn't fail.
    //
    ASSERT_EFI_ERROR (Status);
  }
  return EFI_SUCCESS;
}
Example #12
0
/**
  After any operation on Driver####, there will be a discrepancy in
  DriverOrder. Since some are missing but in DriverOrder, while some
  are present but are not reflected by DriverOrder. Then a function
  rebuild DriverOrder from scratch by content from DriverOptionMenu is
  needed.

  @retval  EFI_SUCCESS  The driver order is updated successfully.
  @return  Other status than EFI_SUCCESS if failed to set the "DriverOrder" EFI Variable.

**/
EFI_STATUS
Var_ChangeDriverOrder (
  VOID
  )
{
  EFI_STATUS    Status;
  BM_MENU_ENTRY *NewMenuEntry;
  UINT16        *DriverOrderList;
  UINT16        *DriverOrderListPtr;
  UINTN         DriverOrderListSize;
  UINTN         Index;

  DriverOrderList     = NULL;
  DriverOrderListSize = 0;

  //
  // First check whether DriverOrder is present in current configuration
  //
  DriverOrderList = BdsLibGetVariableAndSize (
                      L"DriverOrder",
                      &gEfiGlobalVariableGuid,
                      &DriverOrderListSize
                      );

  //
  // If exists, delete it to hold new DriverOrder
  //
  if (DriverOrderList != NULL) {
    EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
    FreePool (DriverOrderList);
    DriverOrderList = NULL;
  }

  DriverOrderListSize = DriverOptionMenu.MenuNumber;

  if (DriverOrderListSize > 0) {
    DriverOrderList = AllocateZeroPool (DriverOrderListSize * sizeof (UINT16));
    ASSERT (DriverOrderList != NULL);
    DriverOrderListPtr = DriverOrderList;

    //
    // Get all current used Driver#### from DriverOptionMenu.
    // OptionNumber in each BM_LOAD_OPTION is really its
    // #### value.
    //
    for (Index = 0; Index < DriverOrderListSize; Index++) {
      NewMenuEntry      = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
      *DriverOrderList  = (UINT16) NewMenuEntry->OptionNumber;
      DriverOrderList++;
    }

    DriverOrderList = DriverOrderListPtr;

    //
    // After building the DriverOrderList, write it back
    //
    Status = gRT->SetVariable (
                    L"DriverOrder",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    DriverOrderListSize * sizeof (UINT16),
                    DriverOrderList
                    );
    //
    // Changing variable without increasing its size with current variable implementation shouldn't fail.
    //
    ASSERT_EFI_ERROR (Status);
  }
  return EFI_SUCCESS;
}
Example #13
0
/**
  Update the legacy BBS boot option. VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid EFI Variable
  is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
  is also updated.

  @param CallbackData    The context data for BMM.
  @param FormId          The form id.

  @return EFI_SUCCESS           The function completed successfully.
  @retval EFI_NOT_FOUND         If VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid EFI Variable can be found.
  @retval EFI_OUT_OF_RESOURCES  Fail to allocate memory resource
**/
EFI_STATUS
Var_UpdateBBSOption (
  IN BMM_CALLBACK_DATA            *CallbackData,
  IN EFI_FORM_ID                  FormId
  )
{
  UINTN                       Index;
  UINTN                       Index2;
  VOID                        *BootOptionVar;
  CHAR16                      VarName[100];
  UINTN                       OptionSize;
  EFI_STATUS                  Status;
  UINT32                      *Attribute;
  BM_MENU_OPTION              *OptionMenu;
  UINT8                       *LegacyDev;
  UINT8                       *VarData;
  UINTN                       VarSize;
  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
  UINT8                       *OriginalPtr;
  UINT8                       *DisMap;
  UINTN                       Pos;
  UINTN                       Bit;
  UINT16                      *NewOrder;
  UINT16                      Tmp;
  UINT16                      *EnBootOption;
  UINTN                       EnBootOptionCount;
  UINT16                      *DisBootOption;
  UINTN                       DisBootOptionCount;

  DisMap              = NULL;
  NewOrder            = NULL;

  switch (FormId) {
    case FORM_SET_FD_ORDER_ID:
      OptionMenu            = (BM_MENU_OPTION *) &LegacyFDMenu;
      LegacyDev             = CallbackData->BmmFakeNvData.LegacyFD;
      CallbackData->BbsType = BBS_FLOPPY;
      break;

    case FORM_SET_HD_ORDER_ID:
      OptionMenu            = (BM_MENU_OPTION *) &LegacyHDMenu;
      LegacyDev             = CallbackData->BmmFakeNvData.LegacyHD;
      CallbackData->BbsType = BBS_HARDDISK;
      break;

    case FORM_SET_CD_ORDER_ID:
      OptionMenu            = (BM_MENU_OPTION *) &LegacyCDMenu;
      LegacyDev             = CallbackData->BmmFakeNvData.LegacyCD;
      CallbackData->BbsType = BBS_CDROM;
      break;

    case FORM_SET_NET_ORDER_ID:
      OptionMenu            = (BM_MENU_OPTION *) &LegacyNETMenu;
      LegacyDev             = CallbackData->BmmFakeNvData.LegacyNET;
      CallbackData->BbsType = BBS_EMBED_NETWORK;
      break;

    default:
      ASSERT (FORM_SET_BEV_ORDER_ID == CallbackData->BmmPreviousPageId);
      OptionMenu            = (BM_MENU_OPTION *) &LegacyBEVMenu;
      LegacyDev             = CallbackData->BmmFakeNvData.LegacyBEV;
      CallbackData->BbsType = BBS_BEV_DEVICE;
      break;
  }

  DisMap  = CallbackData->BmmOldFakeNVData.DisableMap;
  Status  = EFI_SUCCESS;


  //
  // Update the Variable "LegacyDevOrder"
  //
  VarData = (UINT8 *) BdsLibGetVariableAndSize (
                        VAR_LEGACY_DEV_ORDER,
                        &gEfiLegacyDevOrderVariableGuid,
                        &VarSize
                        );

  if (VarData == NULL) {
    return EFI_NOT_FOUND;
  }

  OriginalPtr = VarData;
  DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) VarData;

  while (VarData < OriginalPtr + VarSize) {
    if (DevOrder->BbsType == CallbackData->BbsType) {
      break;
    }

    VarData += sizeof (BBS_TYPE) + DevOrder->Length;
    DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
  }

  if (VarData >= OriginalPtr + VarSize) {
    FreePool (OriginalPtr);
    return EFI_NOT_FOUND;
  }

  NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));
  if (NewOrder == NULL) {
    FreePool (OriginalPtr);
    return EFI_OUT_OF_RESOURCES;
  }

  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
    if (0xFF == LegacyDev[Index]) {
      break;
    }

    NewOrder[Index] = LegacyDev[Index];
  }
  //
  // Only the enable/disable state of each boot device with same device type can be changed,
  // so we can count on the index information in DevOrder.
  // DisMap bit array is the only reliable source to check a device's en/dis state,
  // so we use DisMap to set en/dis state of each item in NewOrder array
  //
  for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
    Tmp = (UINT16) (DevOrder->Data[Index2] & 0xFF);
    Pos = Tmp / 8;
    Bit = 7 - (Tmp % 8);
    if ((DisMap[Pos] & (1 << Bit)) != 0) {
      NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
      Index++;
    }
  }

  CopyMem (
    DevOrder->Data,
    NewOrder,
    DevOrder->Length - sizeof (DevOrder->Length)
    );
  FreePool (NewOrder);

  Status = gRT->SetVariable (
                  VAR_LEGACY_DEV_ORDER,
                  &gEfiLegacyDevOrderVariableGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                  VarSize,
                  OriginalPtr
                  );


  //
  // Update BootOrder and Boot####.Attribute
  //
  // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order
  //
  ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);

  OrderLegacyBootOption4SameType (
    DevOrder->Data,
    DevOrder->Length / sizeof (UINT16) - 1,
    &EnBootOption,
    &EnBootOptionCount,
    &DisBootOption,
    &DisBootOptionCount
    );

  //
  // 2. Deactivate the DisBootOption and activate the EnBootOption
  //
  for (Index = 0; Index < DisBootOptionCount; Index++) {
    UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);
    BootOptionVar = BdsLibGetVariableAndSize (
                      VarName,
                      &gEfiGlobalVariableGuid,
                      &OptionSize
                      );
    if (BootOptionVar != NULL) {
      Attribute   = (UINT32 *) BootOptionVar;
      *Attribute &= ~LOAD_OPTION_ACTIVE;

      Status = gRT->SetVariable (
                      VarName,
                      &gEfiGlobalVariableGuid,
                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                      OptionSize,
                      BootOptionVar
                      );
      //
      // Changing the content without increasing its size with current variable implementation shouldn't fail.
      //
      ASSERT_EFI_ERROR (Status);

      FreePool (BootOptionVar);
    }
  }

  for (Index = 0; Index < EnBootOptionCount; Index++) {
    UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);
    BootOptionVar = BdsLibGetVariableAndSize (
                      VarName,
                      &gEfiGlobalVariableGuid,
                      &OptionSize
                      );
    if (BootOptionVar != NULL) {
      Attribute   = (UINT32 *) BootOptionVar;
      *Attribute |= LOAD_OPTION_ACTIVE;

      Status = gRT->SetVariable (
                      VarName,
                      &gEfiGlobalVariableGuid,
                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                      OptionSize,
                      BootOptionVar
                      );
      //
      // Changing the content without increasing its size with current variable implementation shouldn't fail.
      //
      ASSERT_EFI_ERROR (Status);

      FreePool (BootOptionVar);
    }
  }

  BOpt_GetBootOptions (CallbackData);

  FreePool (OriginalPtr);
  FreePool (EnBootOption);
  FreePool (DisBootOption);
  return Status;
}
Example #14
0
EFI_STATUS EFIAPI fsw_efi_DriverBinding_Start(IN EFI_DRIVER_BINDING_PROTOCOL  *This,
                                              IN EFI_HANDLE                   ControllerHandle,
                                              IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath)
{
    EFI_STATUS              Status;
    EFI_BLOCK_IO_PROTOCOL  *BlockIo;
    EFI_BLOCK_IO2_PROTOCOL *BlockIo2;
    EFI_DISK_IO_PROTOCOL   *DiskIo;
    EFI_DISK_IO2_PROTOCOL  *DiskIo2;
    FSW_VOLUME_DATA     *Volume;

#if DEBUG_LEVEL
//    Print(L"fsw_efi_DriverBinding_Start\n");
#endif

    // open consumed protocols
    Status = BS->OpenProtocol(ControllerHandle,
                              &PROTO_NAME(BlockIo2Protocol),
                              (VOID **) &BlockIo2,
                              This->DriverBindingHandle,
                              ControllerHandle,
                              EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    if (EFI_ERROR(Status)) {
      BlockIo2 = NULL;
    }

    Status = BS->OpenProtocol(ControllerHandle,
                              &PROTO_NAME(BlockIoProtocol),
                              (VOID **) &BlockIo,
                              This->DriverBindingHandle,
                              ControllerHandle,
                              EFI_OPEN_PROTOCOL_GET_PROTOCOL);   // NOTE: we only want to look at the MediaId
    if ((BlockIo2 == NULL) && EFI_ERROR(Status)) {
//        Print(L"Fsw ERROR: OpenProtocol(BlockIo) returned %x\n", Status);
        return Status;
    }

    Status = BS->OpenProtocol(ControllerHandle,
                              &PROTO_NAME(DiskIo2Protocol),
                              (VOID **) &DiskIo2,
                              This->DriverBindingHandle,
                              ControllerHandle,
                              EFI_OPEN_PROTOCOL_BY_DRIVER);
    if (EFI_ERROR(Status)) {
      DiskIo2 = NULL;
    }

    Status = BS->OpenProtocol(ControllerHandle,
                              &PROTO_NAME(DiskIoProtocol),
                              (VOID **) &DiskIo,
                              This->DriverBindingHandle,
                              ControllerHandle,
                              EFI_OPEN_PROTOCOL_BY_DRIVER);
    if ((DiskIo2 == NULL) && EFI_ERROR(Status)) {
 //       DBG("Fsw ERROR: OpenProtocol(DiskIo) returned %r\n", Status);
        return Status;
    }

    // allocate volume structure
    Volume = AllocateZeroPool(sizeof(FSW_VOLUME_DATA));
    Volume->Signature       = FSW_VOLUME_DATA_SIGNATURE;
    Volume->Handle          = ControllerHandle;
    Volume->DiskIo          = DiskIo;
    Volume->DiskIo2         = DiskIo2;
    Volume->LastIOStatus    = EFI_SUCCESS;

    if (BlockIo2 != NULL) {
      Volume->MediaId         = BlockIo2->Media->MediaId;
    } else {
      Volume->MediaId         = BlockIo->Media->MediaId;
    }

    // mount the filesystem
    Status = fsw_efi_map_status(fsw_mount(Volume, &fsw_efi_host_table,
                                          &FSW_FSTYPE_TABLE_NAME(FSTYPE), &Volume->vol),
                                Volume);

    if (!EFI_ERROR(Status)) {
        // register the SimpleFileSystem protocol
        Volume->FileSystem.Revision     = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
        Volume->FileSystem.OpenVolume   = fsw_efi_FileSystem_OpenVolume;
        Status = BS->InstallMultipleProtocolInterfaces(
											&ControllerHandle,
											&PROTO_NAME(SimpleFileSystemProtocol), 
											&Volume->FileSystem,
                                            NULL);
        if (EFI_ERROR(Status)) {
//            Print(L"Fsw ERROR: InstallMultipleProtocolInterfaces returned %x\n", Status);
        }
    }

    // on errors, close the opened protocols
    if (EFI_ERROR(Status)) {
        if (Volume->vol != NULL)
            fsw_unmount(Volume->vol);
        FreePool(Volume);

        BS->CloseProtocol(ControllerHandle,
                          &PROTO_NAME(DiskIo2Protocol),
                          This->DriverBindingHandle,
                          ControllerHandle);

        BS->CloseProtocol(ControllerHandle,
                          &PROTO_NAME(DiskIoProtocol),
                          This->DriverBindingHandle,
                          ControllerHandle);
    }

    return Status;
}
Example #15
0
/**
  Function to print out all HII configuration information to a file.

  @param[in] Handle           The handle to get info on.  NULL to do all handles.
  @param[in] FileName         The filename to rwite the info to.
**/
SHELL_STATUS
EFIAPI
ConfigToFile(
  IN CONST EFI_HANDLE     Handle,
  IN CONST CHAR16         *FileName
  )
{
  EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
  EFI_STATUS                    Status;
  VOID                          *MainBuffer;
  UINTN                         MainBufferSize;
  EFI_HII_HANDLE                HiiHandle;
  SHELL_FILE_HANDLE             FileHandle;

  HiiDatabase       = NULL;
  MainBufferSize    = 0;
  MainBuffer        = NULL;
  FileHandle        = NULL;

  Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1,
      -1,
      NULL,
      STRING_TOKEN(STR_GEN_FILE_OPEN), 
      gShellDriver1HiiHandle, 
      FileName, 
      Status);
    return (SHELL_DEVICE_ERROR);
  }

  //
  // Locate HII Database protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **) &HiiDatabase
                  );

  if (EFI_ERROR(Status) || HiiDatabase == NULL) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL,
      STRING_TOKEN(STR_GEN_PROTOCOL_NF), 
      gShellDriver1HiiHandle, 
      L"EfiHiiDatabaseProtocol", 
      &gEfiHiiDatabaseProtocolGuid);
    ShellCloseFile(&FileHandle);
    return (SHELL_NOT_FOUND);
  }

  Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase);
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL, 
      STRING_TOKEN(STR_GEN_HANDLE_NOT), 
      gShellDriver1HiiHandle, 
      ConvertHandleToHandleIndex(Handle), 
      L"Device");
    ShellCloseFile(&FileHandle);
    return (SHELL_DEVICE_ERROR);   
  }

  Status = HiiDatabase->ExportPackageLists(HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    MainBuffer = AllocateZeroPool(MainBufferSize);
    Status = HiiDatabase->ExportPackageLists(HiiDatabase, HiiHandle, &MainBufferSize, MainBuffer);
  }

  Status = ShellWriteFile(FileHandle, &MainBufferSize, MainBuffer);

  ShellCloseFile(&FileHandle);
  SHELL_FREE_NON_NULL(MainBuffer);

  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1,
      NULL,
      STRING_TOKEN(STR_FILE_WRITE_FAIL), 
      gShellDriver1HiiHandle, 
      FileName, 
      Status);
    return (SHELL_DEVICE_ERROR);   
  }
  ShellPrintHiiEx(
    -1, 
    -1,
    NULL,
    STRING_TOKEN(STR_DRVCFG_COMP), 
    gShellDriver1HiiHandle);

  return (SHELL_SUCCESS);
}
Example #16
0
/**
  Use SystemTable Conout to stop video based Simple Text Out consoles from going
  to the video device. Put up LogoFile on every video device that is a console.

  @param[in]  LogoFile   File name of logo to display on the center of the screen.

  @retval EFI_SUCCESS     ConsoleControl has been flipped to graphics and logo displayed.
  @retval EFI_UNSUPPORTED Logo not found

**/
EFI_STATUS
EFIAPI
EnableQuietBoot (
  IN  EFI_GUID  *LogoFile
  )
{
  EFI_STATUS                    Status;
  EFI_OEM_BADGING_PROTOCOL      *Badging;
  UINT32                        SizeOfX;
  UINT32                        SizeOfY;
  INTN                          DestX;
  INTN                          DestY;
  UINT8                         *ImageData;
  UINTN                         ImageSize;
  UINTN                         BltSize;
  UINT32                        Instance;
  EFI_BADGING_FORMAT            Format;
  EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
  UINTN                         CoordinateX;
  UINTN                         CoordinateY;
  UINTN                         Height;
  UINTN                         Width;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
  EFI_UGA_DRAW_PROTOCOL         *UgaDraw;
  UINT32                        ColorDepth;
  UINT32                        RefreshRate;
  EFI_GRAPHICS_OUTPUT_PROTOCOL  *GraphicsOutput;
  EFI_BOOT_LOGO_PROTOCOL        *BootLogo;
  UINTN                         NumberOfLogos;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt;
  UINTN                         LogoDestX;
  UINTN                         LogoDestY;
  UINTN                         LogoHeight;
  UINTN                         LogoWidth;
  UINTN                         NewDestX;
  UINTN                         NewDestY;
  UINTN                         NewHeight;
  UINTN                         NewWidth;

  UgaDraw = NULL;
  //
  // Try to open GOP first
  //
  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
    GraphicsOutput = NULL;
    //
    // Open GOP failed, try to open UGA
    //
    Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
  }
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Try to open Boot Logo Protocol.
  //
  BootLogo = NULL;
  gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);

  //
  // Erase Cursor from screen
  //
  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

  Badging = NULL;
  Status  = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging);

  if (GraphicsOutput != NULL) {
    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;

  } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
    Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }
  } else {
    return EFI_UNSUPPORTED;
  }

  Blt = NULL;
  NumberOfLogos = 0;
  LogoDestX = 0;
  LogoDestY = 0;
  LogoHeight = 0;
  LogoWidth = 0;
  NewDestX = 0;
  NewDestY = 0;
  NewHeight = 0;
  NewWidth = 0;
  Instance = 0;
  while (1) {
    ImageData = NULL;
    ImageSize = 0;

    if (Badging != NULL) {
      //
      // Get image from OEMBadging protocol.
      //
      Status = Badging->GetImage (
                          Badging,
                          &Instance,
                          &Format,
                          &ImageData,
                          &ImageSize,
                          &Attribute,
                          &CoordinateX,
                          &CoordinateY
                          );
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      //
      // Currently only support BMP format.
      //
      if (Format != EfiBadgingFormatBMP) {
        if (ImageData != NULL) {
          FreePool (ImageData);
        }
        continue;
      }
    } else {
      //
      // Get the specified image from FV.
      //
      Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize);
      if (EFI_ERROR (Status)) {
        return EFI_UNSUPPORTED;
      }

      CoordinateX = 0;
      CoordinateY = 0;
      if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) {
        Attribute   = EfiBadgingDisplayAttributeCenter;
      } else {
        Attribute   = EfiBadgingDisplayAttributeCustomized;
      } 
    }

    if (Blt != NULL) {
      FreePool (Blt);
    }
    Blt = NULL;
    Status = ConvertBmpToGopBlt (
              ImageData,
              ImageSize,
              (VOID **) &Blt,
              &BltSize,
              &Height,
              &Width
              );
    if (EFI_ERROR (Status)) {
      FreePool (ImageData);

      if (Badging == NULL) {
        return Status;
      } else {
        continue;
      }
    }

    //
    // Calculate the display position according to Attribute.
    //
    switch (Attribute) {
    case EfiBadgingDisplayAttributeLeftTop:
      DestX = CoordinateX;
      DestY = CoordinateY;
      break;

    case EfiBadgingDisplayAttributeCenterTop:
      DestX = (SizeOfX - Width) / 2;
      DestY = CoordinateY;
      break;

    case EfiBadgingDisplayAttributeRightTop:
      DestX = (SizeOfX - Width - CoordinateX);
      DestY = CoordinateY;;
      break;

    case EfiBadgingDisplayAttributeCenterRight:
      DestX = (SizeOfX - Width - CoordinateX);
      DestY = (SizeOfY - Height) / 2;
      break;

    case EfiBadgingDisplayAttributeRightBottom:
      DestX = (SizeOfX - Width - CoordinateX);
      DestY = (SizeOfY - Height - CoordinateY);
      break;

    case EfiBadgingDisplayAttributeCenterBottom:
      DestX = (SizeOfX - Width) / 2;
      DestY = (SizeOfY - Height - CoordinateY);
      break;

    case EfiBadgingDisplayAttributeLeftBottom:
      DestX = CoordinateX;
      DestY = (SizeOfY - Height - CoordinateY);
      break;

    case EfiBadgingDisplayAttributeCenterLeft:
      DestX = CoordinateX;
      DestY = (SizeOfY - Height) / 2;
      break;

    case EfiBadgingDisplayAttributeCenter:
      DestX = (SizeOfX - Width) / 2;
      DestY = (SizeOfY - Height) / 2;
      break;

    case EfiBadgingDisplayAttributeCustomized:
      DestX = (SizeOfX - Width) / 2;
      DestY = ((SizeOfY * 382) / 1000) - Height / 2;
      break;

    default:
      DestX = CoordinateX;
      DestY = CoordinateY;
      break;
    }

    if ((DestX >= 0) && (DestY >= 0)) {
      if (GraphicsOutput != NULL) {
        Status = GraphicsOutput->Blt (
                            GraphicsOutput,
                            Blt,
                            EfiBltBufferToVideo,
                            0,
                            0,
                            (UINTN) DestX,
                            (UINTN) DestY,
                            Width,
                            Height,
                            Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
                            );
      } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
        Status = UgaDraw->Blt (
                            UgaDraw,
                            (EFI_UGA_PIXEL *) Blt,
                            EfiUgaBltBufferToVideo,
                            0,
                            0,
                            (UINTN) DestX,
                            (UINTN) DestY,
                            Width,
                            Height,
                            Width * sizeof (EFI_UGA_PIXEL)
                            );
      } else {
        Status = EFI_UNSUPPORTED;
      }

      //
      // Report displayed Logo information.
      //
      if (!EFI_ERROR (Status)) {
        NumberOfLogos++;

        if (LogoWidth == 0) {
          //
          // The first Logo.
          //
          LogoDestX = (UINTN) DestX;
          LogoDestY = (UINTN) DestY;
          LogoWidth = Width;
          LogoHeight = Height;
        } else {
          //
          // Merge new logo with old one.
          //
          NewDestX = MIN ((UINTN) DestX, LogoDestX);
          NewDestY = MIN ((UINTN) DestY, LogoDestY);
          NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX;
          NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY;

          LogoDestX = NewDestX;
          LogoDestY = NewDestY;
          LogoWidth = NewWidth;
          LogoHeight = NewHeight;
        }
      }
    }

    FreePool (ImageData);

    if (Badging == NULL) {
      break;
    }
  }

Done:
  if (BootLogo == NULL || NumberOfLogos == 0) {
    //
    // No logo displayed.
    //
    if (Blt != NULL) {
      FreePool (Blt);
    }

    return Status;
  }

  //
  // Advertise displayed Logo information.
  //
  if (NumberOfLogos == 1) {
    //
    // Only one logo displayed, use its Blt buffer directly for BootLogo protocol.
    //
    LogoBlt = Blt;
    Status = EFI_SUCCESS;
  } else {
    //
    // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. 
    //
    if (Blt != NULL) {
      FreePool (Blt);
    }

    LogoBlt = AllocateZeroPool (LogoWidth * LogoHeight * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
    if (LogoBlt == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    if (GraphicsOutput != NULL) {
      Status = GraphicsOutput->Blt (
                          GraphicsOutput,
                          LogoBlt,
                          EfiBltVideoToBltBuffer,
                          LogoDestX,
                          LogoDestY,
                          0,
                          0,
                          LogoWidth,
                          LogoHeight,
                          LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
                          );
    } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) {
      Status = UgaDraw->Blt (
                          UgaDraw,
                          (EFI_UGA_PIXEL *) LogoBlt,
                          EfiUgaVideoToBltBuffer,
                          LogoDestX,
                          LogoDestY,
                          0,
                          0,
                          LogoWidth,
                          LogoHeight,
                          LogoWidth * sizeof (EFI_UGA_PIXEL)
                          );
    } else {
      Status = EFI_UNSUPPORTED;
    }
  }

  if (!EFI_ERROR (Status)) {
    BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight);
  }
  FreePool (LogoBlt);

  return Status;
}
Example #17
0
/**
  Function to read in HII configuration information from a file.

  @param[in] Handle           The handle to get info for.
  @param[in] FileName         The filename to read the info from.
**/
SHELL_STATUS
EFIAPI
ConfigFromFile(
  IN       EFI_HANDLE     Handle,
  IN CONST CHAR16         *FileName
  )
{
  EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
  EFI_STATUS                    Status;
  VOID                          *MainBuffer;
  UINT64                        Temp;
  UINTN                         MainBufferSize;
  EFI_HII_HANDLE                HiiHandle;
  SHELL_FILE_HANDLE             FileHandle;
  CHAR16                        *TempDevPathString;
  EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
  EFI_HII_PACKAGE_HEADER        *PackageHeader;
  EFI_DEVICE_PATH_PROTOCOL      *DevPath;
  UINTN                         HandleIndex;

  HiiDatabase       = NULL;
  MainBufferSize    = 0;
  MainBuffer        = NULL;
  FileHandle        = NULL;

  Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1,
      -1,
      NULL,
      STRING_TOKEN(STR_GEN_FILE_OPEN), 
      gShellDriver1HiiHandle, 
      FileName, 
      Status);
    return (SHELL_DEVICE_ERROR);
  }

  //
  // Locate HII Database protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **) &HiiDatabase
                  );

  if (EFI_ERROR(Status) || HiiDatabase == NULL) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL,
      STRING_TOKEN(STR_GEN_PROTOCOL_NF), 
      gShellDriver1HiiHandle, 
      L"EfiHiiDatabaseProtocol", 
      &gEfiHiiDatabaseProtocolGuid);
    ShellCloseFile(&FileHandle);
    return (SHELL_NOT_FOUND);
  }

  Status = ShellGetFileSize(FileHandle, &Temp);
  MainBufferSize = (UINTN)Temp;
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL, 
      STRING_TOKEN(STR_FILE_READ_FAIL), 
      gShellDriver1HiiHandle, 
      FileName,
      Status);
    ShellCloseFile(&FileHandle);
    return (SHELL_DEVICE_ERROR);   
  }
  MainBuffer = AllocateZeroPool((UINTN)MainBufferSize);  
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL, 
      STRING_TOKEN(STR_GEN_OUT_MEM), 
      gShellDriver1HiiHandle);
    ShellCloseFile(&FileHandle);
    return (SHELL_DEVICE_ERROR);   
  }
  Status = ShellReadFile(FileHandle, &MainBufferSize, MainBuffer);
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL, 
      STRING_TOKEN(STR_FILE_READ_FAIL), 
      gShellDriver1HiiHandle, 
      FileName,
      Status);
    ShellCloseFile(&FileHandle);
    SHELL_FREE_NON_NULL(MainBuffer);
    return (SHELL_DEVICE_ERROR);   
  }

  ShellCloseFile(&FileHandle);

  if (Handle != NULL) {
    //
    // User override in place.  Just do it.
    //
    HiiHandle         = NULL;
    Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase);
    if (EFI_ERROR(Status)) {
      ShellPrintHiiEx(
        -1, 
        -1, 
        NULL, 
        STRING_TOKEN(STR_GEN_HANDLE_NOT), 
        gShellDriver1HiiHandle, 
        ConvertHandleToHandleIndex(Handle), 
        L"Device");
      ShellCloseFile(&FileHandle);
      return (SHELL_DEVICE_ERROR);   
    }
    Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, MainBuffer);
    if (EFI_ERROR(Status)) {
      ShellPrintHiiEx(
        -1, 
        -1, 
        NULL, 
        STRING_TOKEN(STR_GEN_UEFI_FUNC_ERROR), 
        gShellDriver1HiiHandle, 
        L"HiiDatabase->UpdatePackageList", 
        Status);
      return (SHELL_DEVICE_ERROR);   
    }
  } else {
    //
    // we need to parse the buffer and try to match the device paths for each item to try to find it's device path.
    //

    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer
      ;  PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize)
      ;  PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) {
        for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER))
          ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END
          ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) {
            if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
              HiiHandle         = NULL;
              Status = FindHiiHandleViaDevPath((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase);
              if (EFI_ERROR(Status)) {
                //
                // print out an error.
                //
                TempDevPathString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), TRUE, TRUE);
                ShellPrintHiiEx(
                  -1, 
                  -1, 
                  NULL, 
                  STRING_TOKEN(STR_DRVCFG_IN_FILE_NF), 
                  gShellDriver1HiiHandle, 
                  TempDevPathString);
                SHELL_FREE_NON_NULL(TempDevPathString);
             } else {
                Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, PackageListHeader);
                if (EFI_ERROR(Status)) {
                  ShellPrintHiiEx(
                    -1, 
                    -1, 
                    NULL, 
                    STRING_TOKEN(STR_GEN_UEFI_FUNC_ERROR), 
                    gShellDriver1HiiHandle, 
                    L"HiiDatabase->UpdatePackageList", 
                    Status);
                  return (SHELL_DEVICE_ERROR);
                } else {
                  DevPath = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER));
                  gBS->LocateDevicePath(&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle);
                  HandleIndex = ConvertHandleToHandleIndex(Handle);
                  ShellPrintHiiEx(
                    -1, 
                    -1, 
                    NULL, 
                    STRING_TOKEN(STR_DRVCFG_DONE_HII), 
                    gShellDriver1HiiHandle, 
                    HandleIndex);
                }
              }              
            }
        }
    }
  }

  SHELL_FREE_NON_NULL(MainBuffer);


  ShellPrintHiiEx(
    -1, 
    -1,
    NULL,
    STRING_TOKEN(STR_DRVCFG_COMP), 
    gShellDriver1HiiHandle);
  return (SHELL_SUCCESS);
}
Example #18
0
/**
  Main entry for this driver.

  @param ImageHandle     Image handle this driver.
  @param SystemTable     Pointer to SystemTable.

  @retval EFI_SUCESS     This function always complete successfully.

**/
EFI_STATUS
EFIAPI
UserProfileManagerInit (
  IN EFI_HANDLE                       ImageHandle,
  IN EFI_SYSTEM_TABLE                 *SystemTable
  )
{
  EFI_STATUS                          Status;
  USER_PROFILE_MANAGER_CALLBACK_INFO  *CallbackInfo;

  Status = gBS->LocateProtocol (
                  &gEfiUserManagerProtocolGuid,
                  NULL,
                  (VOID **) &mUserManager
                  );
  if (EFI_ERROR (Status)) {
    return EFI_SUCCESS;
  }
  
  //
  // Initialize driver private data.
  //
  ZeroMem (&mUserInfo, sizeof (mUserInfo));
  ZeroMem (&mAccessInfo, sizeof (mAccessInfo));

  CallbackInfo = AllocateZeroPool (sizeof (USER_PROFILE_MANAGER_CALLBACK_INFO));
  ASSERT (CallbackInfo != NULL);  

  CallbackInfo->Signature                   = USER_PROFILE_MANAGER_SIGNATURE;
  CallbackInfo->ConfigAccess.ExtractConfig  = FakeExtractConfig;
  CallbackInfo->ConfigAccess.RouteConfig    = FakeRouteConfig;
  CallbackInfo->ConfigAccess.Callback       = UserProfileManagerCallback;
  CallbackInfo->DriverHandle                = NULL;
  
  //
  // Install Device Path Protocol and Config Access protocol to driver handle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &CallbackInfo->DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &CallbackInfo->ConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Publish HII data.
  //
  CallbackInfo->HiiHandle = HiiAddPackages (
                              &gUserProfileManagerGuid,
                              CallbackInfo->DriverHandle,
                              UserProfileManagerStrings,
                              UserProfileManagerVfrBin,
                              NULL
                              );
  ASSERT (CallbackInfo->HiiHandle != NULL);                              
  mCallbackInfo = CallbackInfo;

  return Status;
}
Example #19
0
/**

  This routine is called to see if there are any capsules we need to process.
  If the boot mode is not UPDATE, then we do nothing. Otherwise find the
  capsule HOBS and produce firmware volumes for them via the DXE service.
  Then call the dispatcher to dispatch drivers from them. Finally, check
  the status of the updates.

  This function should be called by BDS in case we need to do some
  sort of processing even if there is no capsule to process. We
  need to do this if an earlier update went away and we need to
  clear the capsule variable so on the next reset PEI does not see it and
  think there is a capsule available.

  @param BootMode                 the current boot mode

  @retval EFI_INVALID_PARAMETER   boot mode is not correct for an update
  @retval EFI_SUCCESS             There is no error when processing capsule

**/
EFI_STATUS
EFIAPI
BdsProcessCapsules (
  EFI_BOOT_MODE BootMode
  )
{
  EFI_STATUS                  Status;
  EFI_PEI_HOB_POINTERS        HobPointer;
  EFI_CAPSULE_HEADER          *CapsuleHeader;
  UINT32                      Size;
  UINT32                      CapsuleNumber;
  UINT32                      CapsuleTotalNumber;
  EFI_CAPSULE_TABLE           *CapsuleTable;
  UINT32                      Index;
  UINT32                      CacheIndex;
  UINT32                      CacheNumber;
  VOID                        **CapsulePtr;
  VOID                        **CapsulePtrCache;
  EFI_GUID                    *CapsuleGuidCache; 
  BOOLEAN                     NeedReset;

  CapsuleNumber = 0;
  CapsuleTotalNumber = 0;
  CacheIndex   = 0;
  CacheNumber  = 0;
  CapsulePtr        = NULL;
  CapsulePtrCache   = NULL;
  CapsuleGuidCache  = NULL;
  NeedReset          = FALSE;

  //
  // We don't do anything else if the boot mode is not flash-update
  //
  if (BootMode != BOOT_ON_FLASH_UPDATE) {
    return EFI_INVALID_PARAMETER;
  }
  
  Status = EFI_SUCCESS;
  //
  // Find all capsule images from hob
  //
  HobPointer.Raw = GetHobList ();
  while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) {
    CapsuleTotalNumber ++;
    HobPointer.Raw = GET_NEXT_HOB (HobPointer);
  }
  
  if (CapsuleTotalNumber == 0) {
    //
    // We didn't find a hob, so had no errors.
    //
    PlatformBdsLockNonUpdatableFlash ();
    return EFI_SUCCESS;
  }
  
  //
  // Init temp Capsule Data table.
  //
  CapsulePtr       = (VOID **) AllocateZeroPool (sizeof (VOID *) * CapsuleTotalNumber);
//  ASSERT (CapsulePtr != NULL);
  CapsulePtrCache  = (VOID **) AllocateZeroPool (sizeof (VOID *) * CapsuleTotalNumber);
//  ASSERT (CapsulePtrCache != NULL);
  CapsuleGuidCache = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID) * CapsuleTotalNumber);
//  ASSERT (CapsuleGuidCache != NULL);
  
  //
  // Find all capsule images from hob
  //
  HobPointer.Raw = GetHobList ();
  while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) {
    CapsulePtr [CapsuleNumber++] = (VOID *) (UINTN) HobPointer.Capsule->BaseAddress;
    HobPointer.Raw = GET_NEXT_HOB (HobPointer);
  }

  //
  //Check the capsule flags,if contains CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE, install
  //capsuleTable to configure table with EFI_CAPSULE_GUID
  //

  //
  // Capsules who have CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE always are used for operating
  // System to have information persist across a system reset. EFI System Table must 
  // point to an array of capsules that contains the same CapsuleGuid value. And agents
  // searching for this type capsule will look in EFI System Table and search for the 
  // capsule's Guid and associated pointer to retrieve the data. Two steps below describes
  // how to sorting the capsules by the unique guid and install the array to EFI System Table. 
  // Firstly, Loop for all coalesced capsules, record unique CapsuleGuids and cache them in an 
  // array for later sorting capsules by CapsuleGuid.
  //
  for (Index = 0; Index < CapsuleTotalNumber; Index++) {
    CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];
    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0) {
      //
      // For each capsule, we compare it with known CapsuleGuid in the CacheArray.
      // If already has the Guid, skip it. Whereas, record it in the CacheArray as 
      // an additional one.
      //
      CacheIndex = 0;
      while (CacheIndex < CacheNumber) {
        if (CompareGuid(&CapsuleGuidCache[CacheIndex],&CapsuleHeader->CapsuleGuid)) {
          break;
        }
        CacheIndex++;
      }
      if (CacheIndex == CacheNumber) {
        CopyMem(&CapsuleGuidCache[CacheNumber++],&CapsuleHeader->CapsuleGuid,sizeof(EFI_GUID));
      }
    }
  }

  //
  // Secondly, for each unique CapsuleGuid in CacheArray, gather all coalesced capsules
  // whose guid is the same as it, and malloc memory for an array which preceding
  // with UINT32. The array fills with entry point of capsules that have the same
  // CapsuleGuid, and UINT32 represents the size of the array of capsules. Then install
  // this array into EFI System Table, so that agents searching for this type capsule
  // will look in EFI System Table and search for the capsule's Guid and associated
  // pointer to retrieve the data.
  //
  CacheIndex = 0;
  while (CacheIndex < CacheNumber) {
    CapsuleNumber = 0;  
    for (Index = 0; Index < CapsuleTotalNumber; Index++) {
      CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];
      if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0) {
        if (CompareGuid (&CapsuleGuidCache[CacheIndex], &CapsuleHeader->CapsuleGuid)) {
          //
          // Cache Caspuleheader to the array, this array is uniqued with certain CapsuleGuid.
          //
          CapsulePtrCache[CapsuleNumber++] = (VOID*)CapsuleHeader;
        }
      }
    }
    if (CapsuleNumber != 0) {
      Size = sizeof(EFI_CAPSULE_TABLE) + (CapsuleNumber - 1) * sizeof(VOID*);  
      CapsuleTable = AllocateRuntimePool (Size);
//      ASSERT (CapsuleTable != NULL);
      CapsuleTable->CapsuleArrayNumber =  CapsuleNumber;
      CopyMem(&CapsuleTable->CapsulePtr[0], CapsulePtrCache, CapsuleNumber * sizeof(VOID*));
      Status = gBS->InstallConfigurationTable (&CapsuleGuidCache[CacheIndex], (VOID*)CapsuleTable);
//      ASSERT_EFI_ERROR (Status);
    }
    CacheIndex++;
  }

  //
  // Besides ones with CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flag, all capsules left are
  // recognized by platform with CapsuleGuid. For general platform driver, UpdateFlash 
  // type is commonly supported, so here only deal with encapsuled FVs capsule. Additional
  // type capsule transaction could be extended. It depends on platform policy.
  //
  for (Index = 0; Index < CapsuleTotalNumber; Index++) {
    CapsuleHeader = (EFI_CAPSULE_HEADER*) CapsulePtr [Index];
    if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) == 0) {
      //
      // Always reset system after all capsule processed if FMP capsule exist
      //
      if (CompareGuid (&gEfiFmpCapsuleGuid, &CapsuleHeader->CapsuleGuid)){
        NeedReset = TRUE;
      }

      //
      // Call capsule library to process capsule image.
      //
      ProcessCapsuleImage (CapsuleHeader);
    }
  }

  if (NeedReset) {
    Print(L"Capsule Request Cold Reboot.\n");

    for (Index = 5; Index > 0; Index--) {
      Print(L"\rResetting system in %d seconds ...", Index);
      gBS->Stall (1000000);
    }

    gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);

    CpuDeadLoop ();
  }

  PlatformBdsLockNonUpdatableFlash ();
  
  //
  // Free the allocated temp memory space.
  //
  FreePool (CapsuleGuidCache);
  FreePool (CapsulePtrCache);
  FreePool (CapsulePtr);

  return Status;
}
Example #20
0
File: UsbDesc.c Project: b-man/edk2
/**
  Create a descriptor.

  @param  DescBuf               The buffer of raw descriptor.
  @param  Len                   The length of the raw descriptor buffer.
  @param  Type                  The type of descriptor to create.
  @param  Consumed              Number of bytes consumed.

  @return Created descriptor or NULL.

**/
VOID *
UsbCreateDesc (
  IN  UINT8               *DescBuf,
  IN  UINTN               Len,
  IN  UINT8               Type,
  OUT UINTN               *Consumed
  )
{
  USB_DESC_HEAD           *Head;
  UINTN                   DescLen;
  UINTN                   CtrlLen;
  UINTN                   Offset;
  VOID                    *Desc;

  DescLen   = 0;
  CtrlLen   = 0;
  *Consumed = 0;

  switch (Type) {
  case USB_DESC_TYPE_DEVICE:
    DescLen = sizeof (EFI_USB_DEVICE_DESCRIPTOR);
    CtrlLen = sizeof (USB_DEVICE_DESC);
    break;

  case USB_DESC_TYPE_CONFIG:
    DescLen = sizeof (EFI_USB_CONFIG_DESCRIPTOR);
    CtrlLen = sizeof (USB_CONFIG_DESC);
    break;

  case USB_DESC_TYPE_INTERFACE:
    DescLen = sizeof (EFI_USB_INTERFACE_DESCRIPTOR);
    CtrlLen = sizeof (USB_INTERFACE_SETTING);
    break;

  case USB_DESC_TYPE_ENDPOINT:
    DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);
    CtrlLen = sizeof (USB_ENDPOINT_DESC);
    break;
  }

  //
  // All the descriptor has a common LTV (Length, Type, Value)
  // format. Skip the descriptor that isn't of this Type
  //
  Offset = 0;
  Head   = (USB_DESC_HEAD*)DescBuf;

  while ((Offset < Len) && (Head->Type != Type)) {
    Offset += Head->Len;
    if (Len <= Offset) {
      DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Beyond boundary!\n"));
      return NULL;
    }
    Head    = (USB_DESC_HEAD*)(DescBuf + Offset);
    if (Head->Len == 0) {
      DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
      return NULL;
    }
  }

  if ((Len <= Offset)      || (Len < Offset + Head->Len) ||
      (Head->Type != Type) || (Head->Len < DescLen)) {
    DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor\n"));
    return NULL;
  }

  Desc = AllocateZeroPool ((UINTN) CtrlLen);
  if (Desc == NULL) {
    return NULL;
  }

  CopyMem (Desc, Head, (UINTN) DescLen);

  *Consumed = Offset + Head->Len;

  return Desc;
}
Example #21
0
/**
  Measure PE image into TPM log based on the authenticode image hashing in
  PE/COFF Specification 8.0 Appendix A.

  Caution: This function may receive untrusted input.
  PE/COFF image is external input, so this function will validate its data structure
  within this image buffer before use.

  @param[in]  PCRIndex       TPM PCR index
  @param[in]  ImageAddress   Start address of image buffer.
  @param[in]  ImageSize      Image size
  @param[out] DigestList     Digeest list of this image.

  @retval EFI_SUCCESS            Successfully measure image.
  @retval EFI_OUT_OF_RESOURCES   No enough resource to measure image.
  @retval other error value
**/
EFI_STATUS
MeasurePeImageAndExtend (
  IN  UINT32                    PCRIndex,
  IN  EFI_PHYSICAL_ADDRESS      ImageAddress,
  IN  UINTN                     ImageSize,
  OUT TPML_DIGEST_VALUES        *DigestList
  )
{
  EFI_STATUS                           Status;
  EFI_IMAGE_DOS_HEADER                 *DosHdr;
  UINT32                               PeCoffHeaderOffset;
  EFI_IMAGE_SECTION_HEADER             *Section;
  UINT8                                *HashBase;
  UINTN                                HashSize;
  UINTN                                SumOfBytesHashed;
  EFI_IMAGE_SECTION_HEADER             *SectionHeader;
  UINTN                                Index;
  UINTN                                Pos;
  UINT16                               Magic;
  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  Hdr;
  UINT32                               NumberOfRvaAndSizes;
  UINT32                               CertSize;
  HASH_HANDLE                          HashHandle;

  HashHandle = 0xFFFFFFFF; // Know bad value

  Status        = EFI_UNSUPPORTED;
  SectionHeader = NULL;

  //
  // Check PE/COFF image
  //
  DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress;
  PeCoffHeaderOffset = 0;
  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
    PeCoffHeaderOffset = DosHdr->e_lfanew;
  }

  Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset);
  if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
    Status = EFI_UNSUPPORTED;
    goto Finish;
  }

  //
  // PE/COFF Image Measurement
  //
  //    NOTE: The following codes/steps are based upon the authenticode image hashing in
  //      PE/COFF Specification 8.0 Appendix A.
  //
  //

  // 1.  Load the image header into memory.

  // 2.  Initialize a SHA hash context.

  Status = HashStart (&HashHandle);
  if (EFI_ERROR (Status)) {
    goto Finish;
  }

  //
  // Measuring PE/COFF Image Header;
  // But CheckSum field and SECURITY data directory (certificate) are excluded
  //
  if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    //
    // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
    //       in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
    //       Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
    //       then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
    //
    Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
  } else {
    //
    // Get the magic value from the PE/COFF Optional Header
    //
    Magic = Hdr.Pe32->OptionalHeader.Magic;
  }

  //
  // 3.  Calculate the distance from the base of the image header to the image checksum address.
  // 4.  Hash the image header from its base to beginning of the image checksum.
  //
  HashBase = (UINT8 *) (UINTN) ImageAddress;
  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    //
    // Use PE32 offset
    //
    NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.CheckSum) - HashBase);
  } else {
    //
    // Use PE32+ offset
    //
    NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
    HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - HashBase);
  }

  Status = HashUpdate (HashHandle, HashBase, HashSize);
  if (EFI_ERROR (Status)) {
    goto Finish;
  }

  //
  // 5.  Skip over the image checksum (it occupies a single ULONG).
  //
  if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
    //
    // 6.  Since there is no Cert Directory in optional header, hash everything
    //     from the end of the checksum to the end of image header.
    //
    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      //
      // Use PE32 offset.
      //
      HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
    } else {
      //
      // Use PE32+ offset.
      //
      HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
    }

    if (HashSize != 0) {
      Status  = HashUpdate (HashHandle, HashBase, HashSize);
      if (EFI_ERROR (Status)) {
        goto Finish;
      }
    }
  } else {
    //
    // 7.  Hash everything from the end of the checksum to the start of the Cert Directory.
    //
    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      //
      // Use PE32 offset
      //
      HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
    } else {
      //
      // Use PE32+ offset
      //
      HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = (UINTN) ((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
    }

    if (HashSize != 0) {
      Status  = HashUpdate (HashHandle, HashBase, HashSize);
      if (EFI_ERROR (Status)) {
        goto Finish;
      }
    }

    //
    // 8.  Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
    // 9.  Hash everything from the end of the Cert Directory to the end of image header.
    //
    if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      //
      // Use PE32 offset
      //
      HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
      HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
    } else {
      //
      // Use PE32+ offset
      //
      HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
      HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);
    }

    if (HashSize != 0) {
      Status  = HashUpdate (HashHandle, HashBase, HashSize);
      if (EFI_ERROR (Status)) {
        goto Finish;
      }
    }
  }

  //
  // 10. Set the SUM_OF_BYTES_HASHED to the size of the header
  //
  if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    //
    // Use PE32 offset
    //
    SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
  } else {
    //
    // Use PE32+ offset
    //
    SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;
  }

  //
  // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
  //     structures in the image. The 'NumberOfSections' field of the image
  //     header indicates how big the table should be. Do not include any
  //     IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
  //
  SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections);
  if (SectionHeader == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Finish;
  }

  //
  // 12.  Using the 'PointerToRawData' in the referenced section headers as
  //      a key, arrange the elements in the table in ascending order. In other
  //      words, sort the section headers according to the disk-file offset of
  //      the section.
  //
  Section = (EFI_IMAGE_SECTION_HEADER *) (
               (UINT8 *) (UINTN) ImageAddress +
               PeCoffHeaderOffset +
               sizeof(UINT32) +
               sizeof(EFI_IMAGE_FILE_HEADER) +
               Hdr.Pe32->FileHeader.SizeOfOptionalHeader
               );
  for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
    Pos = Index;
    while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {
      CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof(EFI_IMAGE_SECTION_HEADER));
      Pos--;
    }
    CopyMem (&SectionHeader[Pos], Section, sizeof(EFI_IMAGE_SECTION_HEADER));
    Section += 1;
  }

  //
  // 13.  Walk through the sorted table, bring the corresponding section
  //      into memory, and hash the entire section (using the 'SizeOfRawData'
  //      field in the section header to determine the amount of data to hash).
  // 14.  Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
  // 15.  Repeat steps 13 and 14 for all the sections in the sorted table.
  //
  for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
    Section  = (EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];
    if (Section->SizeOfRawData == 0) {
      continue;
    }
    HashBase = (UINT8 *) (UINTN) ImageAddress + Section->PointerToRawData;
    HashSize = (UINTN) Section->SizeOfRawData;

    Status = HashUpdate (HashHandle, HashBase, HashSize);
    if (EFI_ERROR (Status)) {
      goto Finish;
    }

    SumOfBytesHashed += HashSize;
  }

  //
  // 16.  If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
  //      data in the file that needs to be added to the hash. This data begins
  //      at file offset SUM_OF_BYTES_HASHED and its length is:
  //             FileSize  -  (CertDirectory->Size)
  //
  if (ImageSize > SumOfBytesHashed) {
    HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;

    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
      CertSize = 0;
    } else {
      if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
        //
        // Use PE32 offset.
        //
        CertSize = Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
      } else {
        //
        // Use PE32+ offset.
        //
        CertSize = Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
      }
    }

    if (ImageSize > CertSize + SumOfBytesHashed) {
      HashSize = (UINTN) (ImageSize - CertSize - SumOfBytesHashed);

      Status = HashUpdate (HashHandle, HashBase, HashSize);
      if (EFI_ERROR (Status)) {
        goto Finish;
      }
    } else if (ImageSize < CertSize + SumOfBytesHashed) {
      Status = EFI_UNSUPPORTED;
      goto Finish;
    }
  }

  //
  // 17.  Finalize the SHA hash.
  //
  Status = HashCompleteAndExtend (HashHandle, PCRIndex, NULL, 0, DigestList);
  if (EFI_ERROR (Status)) {
    goto Finish;
  }

Finish:
  if (SectionHeader != NULL) {
    FreePool (SectionHeader);
  }

  return Status;
}
Example #22
0
EFI_STATUS
AcpiPlatformEntryPoint (
  IN EFI_HANDLE     ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                    Status;
  EFI_ACPI_TABLE_PROTOCOL       *AcpiTable;
  EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  INTN                          Instance;
  EFI_ACPI_COMMON_HEADER        *CurrentTable;
  UINTN                         TableHandle;
  UINT32                        FvStatus;
  UINTN                         Size;
  EFI_ACPI_TABLE_VERSION        Version;
  EFI_HANDLE                    Handle;
  UINTN                         Index;
  PCI_DEVICE_INFO               *PciDeviceInfo;
  EFI_ACPI_HANDLE               PciRootHandle;
  BOOLEAN                       UpdatePRT;
  BOOLEAN                       UpdatePRW;
  PCI_DEVICE_SETTING            *mConfigData;

  DEBUG((DEBUG_INFO, "ACPI Platform start...\n"));

  Instance = 0;
  TableHandle = 0;
  CurrentTable = NULL;
  mConfigData  = NULL;

  //
  // Initialize the EFI Driver Library
  //

  ASSERT (sizeof (EFI_GLOBAL_NVS_AREA) == 512);

  Status = gBS->AllocatePool (
                   EfiACPIMemoryNVS,
                   sizeof (EFI_GLOBAL_NVS_AREA),
                   (VOID**)&mGlobalNvsArea.Area
                   );

  Handle = NULL;
  Status = gBS->InstallProtocolInterface (
                  &Handle,
                  &gEfiGlobalNvsAreaProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mGlobalNvsArea
                  );

  ASSERT_EFI_ERROR (Status);
  if (!EFI_ERROR (Status)) {
    SetMem (
      mGlobalNvsArea.Area,
      sizeof (EFI_GLOBAL_NVS_AREA),
      0
      );
  }

  //
  // Initialize the data.  Eventually, this will be controlled by setup options.
  //
  mGlobalNvsArea.Area->HpetEnable           =  PcdGetBool (PcdHpetEnable);
  mGlobalNvsArea.Area->Pm1blkIoBaseAddress  =  PcdGet16(PcdPm1blkIoBaseAddress);
  mGlobalNvsArea.Area->PmbaIoBaseAddress    =  PcdGet16(PcdPmbaIoBaseAddress);
  mGlobalNvsArea.Area->Gpe0blkIoBaseAddress =  PcdGet16(PcdGpe0blkIoBaseAddress);
  mGlobalNvsArea.Area->GbaIoBaseAddress     =  PcdGet16(PcdGbaIoBaseAddress);
  mGlobalNvsArea.Area->SmbaIoBaseAddress    =  PcdGet16(PcdSmbaIoBaseAddress);
  mGlobalNvsArea.Area->WdtbaIoBaseAddress   =  PcdGet16(PcdWdtbaIoBaseAddress);
  mGlobalNvsArea.Area->HpetBaseAddress      =  (UINT32)PcdGet64(PcdHpetBaseAddress);
  mGlobalNvsArea.Area->HpetSize             =  (UINT32)PcdGet64(PcdHpetSize);
  mGlobalNvsArea.Area->PciExpressBaseAddress=  (UINT32)PcdGet64(PcdPciExpressBaseAddress);
  mGlobalNvsArea.Area->PciExpressSize       =  (UINT32)PcdGet64(PcdPciExpressSize);
  mGlobalNvsArea.Area->RcbaMmioBaseAddress  =  (UINT32)PcdGet64(PcdRcbaMmioBaseAddress);
  mGlobalNvsArea.Area->RcbaMmioSize         =  (UINT32)PcdGet64(PcdRcbaMmioSize);
  mGlobalNvsArea.Area->IoApicBaseAddress    =  (UINT32)PcdGet64(PcdIoApicBaseAddress);
  mGlobalNvsArea.Area->IoApicSize           =  (UINT32)PcdGet64(PcdIoApicSize);
  mGlobalNvsArea.Area->TpmPresent           =  (UINT32)(FALSE);
  mGlobalNvsArea.Area->DBG2Present          =  (UINT32)(FALSE);
  mGlobalNvsArea.Area->PlatformType         =  (UINT32)PcdGet16 (PcdPlatformType);

  //
  // Configure platform IO expander I2C Slave Address.
  //
  if (mGlobalNvsArea.Area->PlatformType == Galileo) {
    if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
      mGlobalNvsArea.Area->AlternateSla = FALSE;
    } else {
      mGlobalNvsArea.Area->AlternateSla = TRUE;
    }
  }

  //
  // Find the AcpiTable protocol
  //
  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }

  //
  // Initialize MADT table
  //
  Status = MadtTableInitialize (&CurrentTable, &Size);
  ASSERT_EFI_ERROR (Status);
  //
  // Perform any table specific updates.
  //
  AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);

  //
  // Update the check sum
  // It needs to be zeroed before the checksum calculation
  //
  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
  ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
    CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);

  //
  // Add the table
  //
  TableHandle = 0;
  Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                            CurrentTable,
                            CurrentTable->Length,
                          &TableHandle
                          );
  ASSERT_EFI_ERROR (Status);
  CurrentTable = NULL;

  //
  // Init Pci Device PRT PRW information structure from PCD
  //
  mConfigData = (PCI_DEVICE_SETTING *)AllocateZeroPool (sizeof (PCI_DEVICE_SETTING));
  ASSERT (mConfigData != NULL);
  InitPciDeviceInfoStructure (mConfigData);
  //
  // Get the Acpi SDT protocol for manipulation on acpi table
  //
  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&mAcpiSdt);
  ASSERT_EFI_ERROR (Status);
  //
  // Locate the firmware volume protocol
  //
  Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, (VOID**)&FwVol, 1);
  if (EFI_ERROR (Status)) {
    return EFI_ABORTED;
  }
  //
  // Read tables from the storage file.
  //

  while (Status == EFI_SUCCESS) {

    Status = FwVol->ReadSection (
                      FwVol,
                      (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
                      EFI_SECTION_RAW,
                      Instance,
                      (VOID**)&CurrentTable,
                      &Size,
                      &FvStatus
                      );

    if (!EFI_ERROR(Status)) {
      //
      // Perform any table specific updates.
      //
      AcpiUpdateTable ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable, &Version);

      //
      // Update the check sum
      // It needs to be zeroed before the checksum calculation
      //
      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum = 0;
      ((EFI_ACPI_SDT_HEADER *)CurrentTable)->Checksum =
        CalculateCheckSum8 ((VOID *)CurrentTable, CurrentTable->Length);

      //
      // Add the table
      //
      TableHandle = 0;
      Status = AcpiTable->InstallAcpiTable (
                            AcpiTable,
                              CurrentTable,
                            ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length,
                              &TableHandle
                              );
      if (EFI_ERROR(Status)) {
        return EFI_ABORTED;
      }
      //
      // If this table is the DSDT table, then update the _PRT and _PRW based on
      // the settings from pcds
      //
      if (CurrentTable->Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
        //
        // Create the root handle for DSDT table
        //
        Status = mAcpiSdt->OpenSdt (TableHandle, &mDsdtHandle);
        ASSERT_EFI_ERROR (Status);

        PciRootHandle = NULL;
        PciRootHandle = SdtGetRootBridgeHandle (mAcpiSdt, mDsdtHandle);
        ASSERT (PciRootHandle != NULL);

        PciDeviceInfo = NULL;
        for (Index = 0; Index < mConfigData->PciDeviceInfoNumber; Index++) {
          PciDeviceInfo = &(mConfigData->PciDeviceInfo[Index]);

          //
          // Check whether this is a valid item
          //
          if ((PciDeviceInfo->BridgeAddress != 0xFFFFFFFF) && (PciDeviceInfo->DeviceAddress != 0xFFFFFFFF)) {

            //DEBUG ((EFI_D_ERROR, "Valid pci info structure: bridge address:0x%x, device address:0x%x\n", PciDeviceInfo->BridgeAddress, PciDeviceInfo->DeviceAddress));

            UpdatePRT = FALSE;
            UpdatePRW = FALSE;

            SdtCheckPciDeviceInfoChanged (PciDeviceInfo, &UpdatePRT, &UpdatePRW);
            //
            // Check whether there is any valid pci routing item
            //
            if (UpdatePRT) {
              //
              // Update the pci routing information
              //
              //DEBUG ((EFI_D_ERROR, "Update _PRT\n"));
              SdtUpdatePciRouting (mAcpiSdt, PciRootHandle, PciDeviceInfo);
            }
            //
            // Check whether there is any valid pci routing item
            //
            if (UpdatePRW) {
              //
              // Update the pci wakeup information
              //
              //DEBUG ((EFI_D_ERROR, "Update _PRW\n"));
              SdtUpdatePowerWake (mAcpiSdt, PciRootHandle, PciDeviceInfo);
            }
          }
        }
        Status = mAcpiSdt->Close (PciRootHandle);
        ASSERT_EFI_ERROR (Status);
        //
        // Mark the root handle as modified , let SDT protocol recaculate the checksum
        //
        ((EFI_AML_HANDLE *)mDsdtHandle)->Modified = TRUE;
        Status = mAcpiSdt->Close (mDsdtHandle);
        ASSERT_EFI_ERROR (Status);
      }
      //
      // Increment the instance
      //
      Instance++;
      CurrentTable = NULL;
    }
  }

  gBS->FreePool (mConfigData);
  return EFI_SUCCESS;
}
Example #23
0
/**
  Update the string associated with an existing SMBIOS record.

  @param  This                  The EFI_SMBIOS_PROTOCOL instance.
  @param  SmbiosHandle          SMBIOS Handle of structure that will have its string updated.
  @param  StringNumber          The non-zero string number of the string to update
  @param  String                Update the StringNumber string with String.

  @retval EFI_SUCCESS           SmbiosHandle had its StringNumber String updated.
  @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist.
  @retval EFI_UNSUPPORTED       String was not added because it is longer than the SMBIOS Table supports.
  @retval EFI_NOT_FOUND         The StringNumber.is not valid for this SMBIOS record.

**/
EFI_STATUS
EFIAPI
SmbiosUpdateString (
  IN CONST EFI_SMBIOS_PROTOCOL      *This,
  IN EFI_SMBIOS_HANDLE              *SmbiosHandle,
  IN UINTN                          *StringNumber,
  IN CHAR8                          *String
  )
{
  UINTN                     InputStrLen;
  UINTN                     TargetStrLen;
  UINTN                     StrIndex;
  UINTN                     TargetStrOffset;
  UINTN                     NewEntrySize;
  CHAR8                     *StrStart;
  VOID                      *Raw;
  LIST_ENTRY                *Link;
  LIST_ENTRY                *Head;
  EFI_STATUS                Status;
  SMBIOS_INSTANCE           *Private;
  EFI_SMBIOS_ENTRY          *SmbiosEntry;
  EFI_SMBIOS_ENTRY          *ResizedSmbiosEntry;
  EFI_SMBIOS_HANDLE         MaxSmbiosHandle;
  EFI_SMBIOS_TABLE_HEADER   *Record;
  EFI_SMBIOS_RECORD_HEADER  *InternalRecord;
  
  //
  // Check args validity
  //
  GetMaxSmbiosHandle(This, &MaxSmbiosHandle);

  if (*SmbiosHandle > MaxSmbiosHandle) {
    return EFI_INVALID_PARAMETER;
  }

  if (String == NULL) {
    return EFI_ABORTED;
  }

  if (*StringNumber == 0) {
    return EFI_NOT_FOUND;
  }

  InputStrLen = AsciiStrLen(String);

  if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) {
    if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {
      return EFI_UNSUPPORTED;
    }
  } else if (This->MajorVersion < 3) {
    //
    // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.
    // However, the length of the entire structure table (including all strings) must be reported 
    // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
    // which is a WORD field limited to 65,535 bytes.
    //
    if (InputStrLen > SMBIOS_TABLE_MAX_LENGTH) {
      return EFI_UNSUPPORTED;
    }
  } else {
    if (InputStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH) {
      //
      // SMBIOS 3.0 defines the Structure table maximum size as DWORD field limited to 0xFFFFFFFF bytes.
      // The input string length should not exceed 0xFFFFFFFF bytes.
      // 
      return EFI_UNSUPPORTED;
    }
  }

  Private = SMBIOS_INSTANCE_FROM_THIS (This);
  //
  // Enter into critical section
  //  
  Status = EfiAcquireLockOrFail (&Private->DataLock);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Head = &Private->DataListHead;
  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
    SmbiosEntry = SMBIOS_ENTRY_FROM_LINK(Link);
    Record = (EFI_SMBIOS_TABLE_HEADER*)(SmbiosEntry->RecordHeader + 1);

    if (Record->Handle == *SmbiosHandle) {
      //
      // Find out the specified SMBIOS record
      //
      if (*StringNumber > SmbiosEntry->RecordHeader->NumberOfStrings) {
        EfiReleaseLock (&Private->DataLock);
        return EFI_NOT_FOUND;
      }
      //
      // Point to unformed string section
      //
      StrStart = (CHAR8 *) Record + Record->Length;
     
      for (StrIndex = 1, TargetStrOffset = 0; StrIndex < *StringNumber; StrStart++, TargetStrOffset++) {
        //
        // A string ends in 00h
        //
        if (*StrStart == 0) {
          StrIndex++;
        }
        
        //
        // String section ends in double-null (0000h)
        //
        if (*StrStart == 0 && *(StrStart + 1) == 0) {
          EfiReleaseLock (&Private->DataLock);
          return EFI_NOT_FOUND;
        } 
      }

      if (*StrStart == 0) {
        StrStart++;
        TargetStrOffset++;
      }
      
      //
      // Now we get the string target
      //
      TargetStrLen = AsciiStrLen(StrStart);
      if (InputStrLen == TargetStrLen) {
        AsciiStrCpyS(StrStart, TargetStrLen + 1, String);
        //
        // Some UEFI drivers (such as network) need some information in SMBIOS table.
        // Here we create SMBIOS table and publish it in
        // configuration table, so other UEFI drivers can get SMBIOS table from
        // configuration table without depending on PI SMBIOS protocol.
        //
        SmbiosTableConstruction (SmbiosEntry->Smbios32BitTable, SmbiosEntry->Smbios64BitTable);
        EfiReleaseLock (&Private->DataLock);
        return EFI_SUCCESS;
      }
      
      SmbiosEntry->Smbios32BitTable = FALSE;
      SmbiosEntry->Smbios64BitTable = FALSE;
      if ((This->MajorVersion < 0x3) || 
          ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT0) == BIT0))) {
        //
        // 32-bit table is produced, check the valid length.
        //
        if ((EntryPointStructure != NULL) && 
            (EntryPointStructure->TableLength + InputStrLen - TargetStrLen > SMBIOS_TABLE_MAX_LENGTH)) {
          //
          // The length of the entire structure table (including all strings) must be reported
          // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,
          // which is a WORD field limited to 65,535 bytes.
          //
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 32-bit table length\n"));
        } else {
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 32-bit table\n"));
          SmbiosEntry->Smbios32BitTable = TRUE;
        }
      } 

      if ((This->MajorVersion >= 0x3) && ((PcdGet32 (PcdSmbiosEntryPointProvideMethod) & BIT1) == BIT1)) {
        //
        // 64-bit table is produced, check the valid length.
        //
        if ((Smbios30EntryPointStructure != NULL) && 
            (Smbios30EntryPointStructure->TableMaximumSize + InputStrLen - TargetStrLen > SMBIOS_3_0_TABLE_MAX_LENGTH)) {
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: Total length exceeds max 64-bit table length\n"));
        } else {
          DEBUG ((EFI_D_INFO, "SmbiosUpdateString: New smbios record add to 64-bit table\n"));
          SmbiosEntry->Smbios64BitTable = TRUE;
        }
      }

      if ((!SmbiosEntry->Smbios32BitTable) && (!SmbiosEntry->Smbios64BitTable)) {
        EfiReleaseLock (&Private->DataLock);
        return EFI_UNSUPPORTED;
      }

      //
      // Original string buffer size is not exactly match input string length.
      // Re-allocate buffer is needed.
      //
      NewEntrySize = SmbiosEntry->RecordSize + InputStrLen - TargetStrLen;
      ResizedSmbiosEntry = AllocateZeroPool (NewEntrySize);

      if (ResizedSmbiosEntry == NULL) {
        EfiReleaseLock (&Private->DataLock);
        return EFI_OUT_OF_RESOURCES;
      }

      InternalRecord  = (EFI_SMBIOS_RECORD_HEADER *) (ResizedSmbiosEntry + 1);
      Raw     = (VOID *) (InternalRecord + 1);

      //
      // Build internal record Header
      //
      InternalRecord->Version     = EFI_SMBIOS_RECORD_HEADER_VERSION;
      InternalRecord->HeaderSize  = (UINT16) sizeof (EFI_SMBIOS_RECORD_HEADER);
      InternalRecord->RecordSize  = SmbiosEntry->RecordHeader->RecordSize + InputStrLen - TargetStrLen;
      InternalRecord->ProducerHandle = SmbiosEntry->RecordHeader->ProducerHandle;
      InternalRecord->NumberOfStrings = SmbiosEntry->RecordHeader->NumberOfStrings;

      //
      // Copy SMBIOS structure and optional strings.
      //
      CopyMem (Raw, SmbiosEntry->RecordHeader + 1, Record->Length + TargetStrOffset);
      CopyMem ((VOID*)((UINTN)Raw + Record->Length + TargetStrOffset), String, InputStrLen + 1);
      CopyMem ((CHAR8*)((UINTN)Raw + Record->Length + TargetStrOffset + InputStrLen + 1),
               (CHAR8*)Record + Record->Length + TargetStrOffset + TargetStrLen + 1,
               SmbiosEntry->RecordHeader->RecordSize - sizeof (EFI_SMBIOS_RECORD_HEADER) - Record->Length - TargetStrOffset - TargetStrLen - 1);

      //
      // Insert new record
      //
      ResizedSmbiosEntry->Signature    = EFI_SMBIOS_ENTRY_SIGNATURE;
      ResizedSmbiosEntry->RecordHeader = InternalRecord;
      ResizedSmbiosEntry->RecordSize   = NewEntrySize;
      ResizedSmbiosEntry->Smbios32BitTable = SmbiosEntry->Smbios32BitTable;
      ResizedSmbiosEntry->Smbios64BitTable = SmbiosEntry->Smbios64BitTable;
      InsertTailList (Link->ForwardLink, &ResizedSmbiosEntry->Link);

      //
      // Remove old record
      //
      RemoveEntryList(Link);
      FreePool(SmbiosEntry);
      //
      // Some UEFI drivers (such as network) need some information in SMBIOS table.
      // Here we create SMBIOS table and publish it in
      // configuration table, so other UEFI drivers can get SMBIOS table from
      // configuration table without depending on PI SMBIOS protocol.
      //
      SmbiosTableConstruction (ResizedSmbiosEntry->Smbios32BitTable, ResizedSmbiosEntry->Smbios64BitTable);
      EfiReleaseLock (&Private->DataLock);
      return EFI_SUCCESS;
    }
  }

  EfiReleaseLock (&Private->DataLock);
  return EFI_INVALID_PARAMETER;
}
Example #24
0
/**
  Initialize the state information for the CPU Architectural Protocol

  @param  ImageHandle   of the loaded driver
  @param  SystemTable   Pointer to the System Table

  @retval EFI_SUCCESS           Protocol registered
  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
  @retval EFI_DEVICE_ERROR      Hardware problems

**/
EFI_STATUS
InterruptDxeInitialize (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS              Status;
  UINTN                   Index;
  UINT32                  RegOffset;
  UINTN                   RegShift;
  EFI_CPU_ARCH_PROTOCOL   *Cpu;
  UINT32                  CpuTarget;
  
  // Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0
  DEBUG_CODE_BEGIN();
  if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) {
    DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n"));
  }
  DEBUG_CODE_END();

  // Make sure the Interrupt Controller Protocol is not already installed in the system.
  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
  
  mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase));

 
  mGicNumInterrupts /=8;
  
  for (Index = 0; Index < mGicNumInterrupts; Index++) {
    (VOID)DisableInterruptSource (&gHardwareInterruptProtocol, Index);
    
    // Set Priority 
    RegOffset = Index / 4;
    RegShift = (Index % 4) * 8;
    MmioAndThenOr32 (
      PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset),
      ~(UINT32)(0xff << RegShift), 
      ARM_GIC_DEFAULT_PRIORITY << RegShift
      );
  }
  // Configure interrupts for Primary Cpu
  CpuTarget = (1 << PcdGet32 (PcdGicPrimaryCoreId));
  CpuTarget |= CpuTarget << 16;
  for (Index = 0; Index < (mGicNumInterrupts / 2); Index++) {
    MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), CpuTarget);
  }
  //end_d00183345, 2012-11-17

  // Set binary point reg to 0x7 (no preemption)
  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x3);

  // Set priority mask reg to 0xff to allow all priorities through
  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff);
  
  // Enable gic cpu interface
  MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1);

  // Enable gic distributor
  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x7);

  
  MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISR, ~0);
  
  //MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISR, ~0);
  
  // Initialize the array for the Interrupt Handlers
  gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
  
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &gHardwareInterruptHandle,
                  &gHardwareInterruptProtocolGuid,   &gHardwareInterruptProtocol,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status))
  {
        //for fortify
        return Status;
  }
  //
  // Get the CPU protocol that this driver requires.
  //
  Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
  ASSERT_EFI_ERROR(Status);
  if (EFI_ERROR (Status))
  {
        //for fortify
        return Status;
  }
  //
  // Unregister the default exception handler.
  //
  Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_AARCH64_IRQ, NULL);
  ASSERT_EFI_ERROR(Status);
  if (EFI_ERROR (Status))
  {
        //for fortify
        return Status;
  }
  //
  // Register to receive interrupts
  //
  Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_AARCH64_IRQ, IrqInterruptHandler);
  ASSERT_EFI_ERROR(Status);
  if (EFI_ERROR (Status))
  {
        //for fortify
        return Status;
  }
  // Register for an ExitBootServicesEvent
  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status))
  {
        //for fortify
        return Status;
  }
  return Status;
}
Example #25
0
/**
  Parse an interface descriptor and its endpoints.

  @param  DescBuf               The buffer of raw descriptor.
  @param  Len                   The length of the raw descriptor buffer.
  @param  Consumed              The number of raw descriptor consumed.

  @return The create interface setting or NULL if failed.

**/
USB_INTERFACE_SETTING *
UsbParseInterfaceDesc (
  IN  UINT8               *DescBuf,
  IN  UINTN               Len,
  OUT UINTN               *Consumed
  )
{
  USB_INTERFACE_SETTING   *Setting;
  USB_ENDPOINT_DESC       *Ep;
  UINTN                   Index;
  UINTN                   NumEp;
  UINTN                   Used;
  UINTN                   Offset;

  *Consumed = 0;
  Setting   = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);

  if (Setting == NULL) {
    DEBUG (( EFI_D_ERROR, "UsbParseInterfaceDesc: failed to create interface descriptor\n"));
    return NULL;
  }

  Offset = Used;

  //
  // Create an array to hold the interface's endpoints
  //
  NumEp  = Setting->Desc.NumEndpoints;

  DEBUG (( EFI_D_INFO, "UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",
              Setting->Desc.InterfaceNumber, Setting->Desc.AlternateSetting, (UINT32)NumEp));

  if (NumEp == 0) {
    goto ON_EXIT;
  }

  Setting->Endpoints  = AllocateZeroPool (sizeof (USB_ENDPOINT_DESC *) * NumEp);

  if (Setting->Endpoints == NULL) {
    goto ON_ERROR;
  }

  //
  // Create the endpoints for this interface
  //
  for (Index = 0; (Index < NumEp) && (Offset < Len); Index++) {
    Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);

    if (Ep == NULL) {
      DEBUG (( EFI_D_ERROR, "UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", (UINT32)Index));
      goto ON_ERROR;
    }

    Setting->Endpoints[Index]  = Ep;
    Offset                    += Used;
  }


ON_EXIT:
  *Consumed = Offset;
  return Setting;

ON_ERROR:
  UsbFreeInterfaceDesc (Setting);
  return NULL;
}
Example #26
0
/**
  Iterates all variables found with RuntimeServices GetNextVariableName

  @param[in]   CallbackFunction - Function called for each variable instance
  @param[in]   Context - Passed to each call of CallbackFunction

  @retval      RETURN_SUCCESS - All variables were iterated without the
                 CallbackFunction returning an error
  @retval      RETURN_OUT_OF_RESOURCES - There we not enough resources to
                 iterate through the variables
  @return      Any of RETURN_ERROR indicates an error reading the variable
                 or an error was returned from CallbackFunction

**/
RETURN_STATUS
EFIAPI
SerializeVariablesIterateSystemVariables (
  IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
  IN VOID                                      *Context
  )
{
  RETURN_STATUS               Status;
  UINTN                       VariableNameBufferSize;
  UINTN                       VariableNameSize;
  CHAR16                      *VariableName;
  EFI_GUID                    VendorGuid;
  UINTN                       VariableDataBufferSize;
  UINTN                       VariableDataSize;
  VOID                        *VariableData;
  UINT32                      VariableAttributes;
  VOID                        *NewBuffer;

  //
  // Initialize the variable name and data buffer variables.
  //
  VariableNameBufferSize = sizeof (CHAR16);
  VariableName = AllocateZeroPool (VariableNameBufferSize);

  VariableDataBufferSize = 0;
  VariableData = NULL;

  for (;;) {
    //
    // Get the next variable name and guid
    //
    VariableNameSize = VariableNameBufferSize;
    Status = gRT->GetNextVariableName (
                    &VariableNameSize,
                    VariableName,
                    &VendorGuid
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      //
      // The currently allocated VariableName buffer is too small,
      // so we allocate a larger buffer, and copy the old buffer
      // to it.
      //
      NewBuffer = AllocatePool (VariableNameSize);
      if (NewBuffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }
      CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
      if (VariableName != NULL) {
        FreePool (VariableName);
      }
      VariableName = NewBuffer;
      VariableNameBufferSize = VariableNameSize;

      //
      // Try to get the next variable name again with the larger buffer.
      //
      Status = gRT->GetNextVariableName (
                      &VariableNameSize,
                      VariableName,
                      &VendorGuid
                      );
    }

    if (EFI_ERROR (Status)) {
      if (Status == EFI_NOT_FOUND) {
        Status = EFI_SUCCESS;
      }
      break;
    }

    //
    // Get the variable data and attributes
    //
    VariableDataSize = VariableDataBufferSize;
    Status = gRT->GetVariable (
                    VariableName,
                    &VendorGuid,
                    &VariableAttributes,
                    &VariableDataSize,
                    VariableData
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      //
      // The currently allocated VariableData buffer is too small,
      // so we allocate a larger buffer.
      //
      if (VariableDataBufferSize != 0) {
        FreePool (VariableData);
        VariableData = NULL;
        VariableDataBufferSize = 0;
      }
      VariableData = AllocatePool (VariableDataSize);
      if (VariableData == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }
      VariableDataBufferSize = VariableDataSize;

      //
      // Try to read the variable again with the larger buffer.
      //
      Status = gRT->GetVariable (
                      VariableName,
                      &VendorGuid,
                      &VariableAttributes,
                      &VariableDataSize,
                      VariableData
                      );
    }
    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // Run the callback function
    //
    Status = (*CallbackFunction) (
               Context,
               VariableName,
               &VendorGuid,
               VariableAttributes,
               VariableDataSize,
               VariableData
               );
    if (EFI_ERROR (Status)) {
      break;
    }

  }

  if (VariableName != NULL) {
    FreePool (VariableName);
  }

  if (VariableData != NULL) {
    FreePool (VariableData);
  }

  return Status;
}
Example #27
0
/**
  Build the whole array of descriptors. This function must
  be called after UsbGetMaxPacketSize0 returns the max packet
  size correctly for endpoint 0.

  @param  UsbDev                The Usb device.

  @retval EFI_SUCCESS           The descriptor table is build.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate resource for the descriptor.

**/
EFI_STATUS
UsbBuildDescTable (
  IN USB_DEVICE           *UsbDev
  )
{
  EFI_USB_CONFIG_DESCRIPTOR *Config;
  USB_DEVICE_DESC           *DevDesc;
  USB_CONFIG_DESC           *ConfigDesc;
  UINT8                     NumConfig;
  EFI_STATUS                Status;
  UINT8                     Index;

  //
  // Get the device descriptor, then allocate the configure
  // descriptor pointer array to hold configurations.
  //
  Status = UsbGetDevDesc (UsbDev);

  if (EFI_ERROR (Status)) {
    DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get device descriptor - %r\n", Status));
    return Status;
  }

  DevDesc   = UsbDev->DevDesc;
  NumConfig = DevDesc->Desc.NumConfigurations;
  if (NumConfig == 0) {
    return EFI_DEVICE_ERROR;
  }

  DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));
  if (DevDesc->Configs == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DEBUG (( EFI_D_INFO, "UsbBuildDescTable: device has %d configures\n", NumConfig));

  //
  // Read each configurations, then parse them
  //
  for (Index = 0; Index < NumConfig; Index++) {
    Config = UsbGetOneConfig (UsbDev, Index);

    if (Config == NULL) {
      DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to get configure (index %d)\n", Index));

      //
      // If we can get the default descriptor, it is likely that the
      // device is still operational.
      //
      if (Index == 0) {
        return EFI_DEVICE_ERROR;
      }

      break;
    }

    ConfigDesc = UsbParseConfigDesc ((UINT8 *) Config, Config->TotalLength);

    FreePool (Config);

    if (ConfigDesc == NULL) {
      DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: failed to parse configure (index %d)\n", Index));

      //
      // If we can get the default descriptor, it is likely that the
      // device is still operational.
      //
      if (Index == 0) {
        return EFI_DEVICE_ERROR;
      }

      break;
    }

    DevDesc->Configs[Index] = ConfigDesc;
  }

  //
  // Don't return error even this function failed because
  // it is possible for the device to not support strings.
  //
  Status = UsbBuildLangTable (UsbDev);

  if (EFI_ERROR (Status)) {
    DEBUG (( EFI_D_INFO, "UsbBuildDescTable: get language ID table %r\n", Status));
  }

  return EFI_SUCCESS;
}
Example #28
0
/**
  Function for 'drvcfg' 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
ShellCommandRunDrvCfg (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  LIST_ENTRY          *Package;
  CHAR16              *ProblemParam;
  SHELL_STATUS        ShellStatus;
  CHAR8               *Language;
  CONST CHAR16        *Lang;
  CONST CHAR16        *HandleIndex1;
  CONST CHAR16        *HandleIndex2;
  CONST CHAR16        *HandleIndex3;
  CONST CHAR16        *ForceTypeString;
  BOOLEAN             Force;
  BOOLEAN             Set;
  BOOLEAN             Validate;
  BOOLEAN             InFromFile;
  BOOLEAN             OutToFile;
  BOOLEAN             AllChildren;
  BOOLEAN             UseHii;
  UINT32              ForceType;
  UINT64              Intermediate;
  EFI_HANDLE          Handle1;
  EFI_HANDLE          Handle2;
  EFI_HANDLE          Handle3;
  CONST CHAR16        *FileName;

  ShellStatus         = SHELL_SUCCESS;
  Status              = EFI_SUCCESS;
  Language            = NULL;
  UseHii              = TRUE;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  Status = CommandInit();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamListHii, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status) || ShellCommandLineGetCount(Package) > 2) {
    UseHii = FALSE;
    if (Package != NULL) {
      ShellCommandLineFreeVarList (Package);
    }
    SHELL_FREE_NON_NULL(ProblemParam);
    Status = ShellCommandLineParse (ParamListPreHii, &Package, &ProblemParam, TRUE);
    if (EFI_ERROR(Status)) {
      if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);
        FreePool(ProblemParam);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      } else {
        ASSERT(FALSE);
      }
    }
  } 
  if (ShellStatus == SHELL_SUCCESS) {
    Lang = ShellCommandLineGetValue(Package, L"-l");
    if (Lang != NULL) {
      Language = AllocateZeroPool(StrSize(Lang));
      AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
    } else if (ShellCommandLineGetFlag(Package, L"-l")){
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }
    Set                 = ShellCommandLineGetFlag (Package, L"-s");
    Validate            = ShellCommandLineGetFlag (Package, L"-v");
    InFromFile          = ShellCommandLineGetFlag (Package, L"-i");
    OutToFile           = ShellCommandLineGetFlag (Package, L"-o");
    AllChildren         = ShellCommandLineGetFlag (Package, L"-c");
    Force               = ShellCommandLineGetFlag (Package, L"-f");
    ForceTypeString     = ShellCommandLineGetValue(Package, L"-f");

    if (OutToFile) {
      FileName = ShellCommandLineGetValue(Package, L"-o");
    } else if (InFromFile) {
      FileName = ShellCommandLineGetValue(Package, L"-i");
    } else {
      FileName = NULL;
    }

    if (InFromFile && EFI_ERROR(ShellFileExists(FileName))) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FIND_FAIL), gShellDriver1HiiHandle, FileName);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;      
    }
    if (OutToFile && !EFI_ERROR(ShellFileExists(FileName))) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_EXIST), gShellDriver1HiiHandle, FileName);
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;      
    }
    if (Force && ForceTypeString == NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-f");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } 
    if (Force) {
      Status = ShellConvertStringToUint64(ForceTypeString, &Intermediate, FALSE, FALSE);
      if (EFI_ERROR(Status)) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDriver1HiiHandle, L"-f");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
      ForceType = (UINT32)Intermediate;
    } else {
      ForceType = 0;
    }
    HandleIndex1        = ShellCommandLineGetRawValue(Package, 1);
    Handle1             = NULL;
    if (HandleIndex1 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex1, &Intermediate, TRUE, FALSE))) {
      Handle1 = ConvertHandleIndexToHandle((UINTN)Intermediate);
      if (Handle1 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, HandleIndex1);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }
    HandleIndex2        = ShellCommandLineGetRawValue(Package, 2);
    Handle2             = NULL;
    if (HandleIndex2 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex2, &Intermediate, TRUE, FALSE))) {
      Handle2 = ConvertHandleIndexToHandle((UINTN)Intermediate);
      if (Handle2 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, HandleIndex2);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }
    HandleIndex3        = ShellCommandLineGetRawValue(Package, 3);
    Handle3             = NULL;
    if (HandleIndex3 != NULL && !EFI_ERROR(ShellConvertStringToUint64(HandleIndex3, &Intermediate, TRUE, FALSE))) {
      Handle3 = ConvertHandleIndexToHandle((UINTN)Intermediate);
      if (Handle3 == NULL || (UINT64)(UINTN)Intermediate != Intermediate) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_INV_HANDLE), gShellDriver1HiiHandle, HandleIndex3);
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }

    if ((InFromFile || OutToFile) && (FileName == NULL)) {
      if (FileName == NULL) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, InFromFile?L"-i":L"-o");
      } else {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_HANDLE_REQ), gShellDriver1HiiHandle);
      }
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }
    if (!UseHii && (InFromFile || OutToFile)) {
      if (InFromFile) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"-i");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      } 
      if (OutToFile) {
        ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"-o");
        ShellStatus = SHELL_INVALID_PARAMETER;
        goto Done;
      }
    }
    if (Validate && Force) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONF), gShellDriver1HiiHandle, L"-v", L"-f");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } 
    if (Validate && Set) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONF), gShellDriver1HiiHandle, L"-v", L"-s");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    } 
    if (Set && Force) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONF), gShellDriver1HiiHandle, L"-s", L"-f");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }
    if (OutToFile && InFromFile) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CONF), gShellDriver1HiiHandle, L"-i", L"-o");
      ShellStatus = SHELL_INVALID_PARAMETER;
      goto Done;
    }

    //
    // We do HII first.
    //
    if (UseHii) {
      if (Handle1 != NULL && EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
        //
        // no HII on this handle.
        //
        ShellStatus = SHELL_UNSUPPORTED;
      } else if (Validate) {
      } else if (Force) {
      } else if (Set) {
      } else if (InFromFile) {
        ShellStatus = ConfigFromFile(Handle1, FileName);
        if (Handle1 != NULL && ShellStatus == SHELL_SUCCESS) {
          goto Done;
        }
      } else if (OutToFile) {
        ShellStatus = ConfigToFile(Handle1, FileName);
        if (Handle1 != NULL && ShellStatus == SHELL_SUCCESS) {
          goto Done;
        }
      } else if (HandleIndex1 == NULL) {
        //
        // display all that are configurable
        //
        ShellStatus = PrintConfigInfoOnAll(AllChildren, Language, UseHii);
        goto Done;
      } else {
        if (!EFI_ERROR(gBS->OpenProtocol(Handle1, &gEfiHiiConfigAccessProtocolGuid, NULL, gImageHandle, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL))) {
          ShellPrintHiiEx(
            -1, 
            -1, 
            NULL, 
            STRING_TOKEN (STR_DRVCFG_LINE_HII), 
            gShellDriver1HiiHandle, 
            ConvertHandleToHandleIndex(Handle1)
            );
          goto Done;
        }
      }
    }

    //
    // We allways need to do this one since it does both by default.
    //
    if (!InFromFile && !OutToFile) {
      ShellStatus = PreHiiDrvCfg (
        Language,
        Force,
        ForceType,
        AllChildren,
        Validate,
        Set,
        Handle1,
        Handle2,
        Handle3);
    }

    if (ShellStatus == SHELL_UNSUPPORTED) {
      ShellPrintHiiEx(
        -1,
        -1,
        NULL,
        STRING_TOKEN (STR_DRVCFG_NOT_SUPPORT),
        gShellDriver1HiiHandle, 
        ConvertHandleToHandleIndex(Handle1)
        );
    }
  }

Done:
  ShellCommandLineFreeVarList (Package);
  SHELL_FREE_NON_NULL(Language);
  return (ShellStatus);
}
Example #29
0
/**
  Initialize debug agent.

  This function is used to set up debug environment for SEC and PEI phase.

  If InitFlag is DEBUG_AGENT_INIT_PREMEM_SEC, it will overirde IDT table entries
  and initialize debug port. It will enable interrupt to support break-in feature.
  It will set up debug agent Mailbox in cache-as-ramfrom. It will be called before
  physical memory is ready.
  If InitFlag is DEBUG_AGENT_INIT_POSTMEM_SEC, debug agent will build one GUIDed
  HOB to copy debug agent Mailbox. It will be called after physical memory is ready.

  This function is used to set up debug environment to support source level debugging.
  If certain Debug Agent Library instance has to save some private data in the stack,
  this function must work on the mode that doesn't return to the caller, then
  the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one
  function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is
  responsible to invoke the passing-in function at the end of InitializeDebugAgent().

  If the parameter Function is not NULL, Debug Agent Libary instance will invoke it by
  passing in the Context to be its parameter.

  If Function() is NULL, Debug Agent Library instance will return after setup debug
  environment.

  @param[in] InitFlag     Init flag is used to decide the initialize process.
  @param[in] Context      Context needed according to InitFlag; it was optional.
  @param[in] Function     Continue function called by debug agent library; it was
                          optional.

**/
VOID
EFIAPI
InitializeDebugAgent (
  IN UINT32                InitFlag,
  IN VOID                  *Context, OPTIONAL
  IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL
  )
{
  DEBUG_AGENT_MAILBOX              *Mailbox;
  DEBUG_AGENT_MAILBOX              *NewMailbox;
  DEBUG_AGENT_MAILBOX              MailboxInStack;
  DEBUG_AGENT_PHASE2_CONTEXT       Phase2Context;
  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  *DebugAgentContext;
  EFI_STATUS                       Status;
  IA32_DESCRIPTOR                  *Ia32Idtr;
  IA32_IDT_ENTRY                   *Ia32IdtEntry;
  UINT64                           DebugPortHandle;
  UINT64                           MailboxLocation;
  UINT64                           *MailboxLocationPointer;
  EFI_PHYSICAL_ADDRESS             Address;
  UINT32                           DebugTimerFrequency;

  DisableInterrupts ();

  switch (InitFlag) {

  case DEBUG_AGENT_INIT_PREMEM_SEC:

    InitializeDebugIdt ();

    MailboxLocation = (UINT64)(UINTN)&MailboxInStack;
    Mailbox = &MailboxInStack;
    ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
    //
    // Get and save debug port handle and set the length of memory block.
    //
    SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation);
    //
    // Force error message could be printed during the first shakehand between Target/HOST.
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR);
    //
    // Save init arch type when debug agent initialized
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);
    //
    // Initialize Debug Timer hardware and save its frequency
    //
    InitializeDebugTimer (&DebugTimerFrequency);
    UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);

    Phase2Context.InitFlag = InitFlag;
    Phase2Context.Context  = Context;
    Phase2Context.Function = Function;
    DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);
    //
    // If reaches here, it means Debug Port initialization failed.
    //
    DEBUG ((EFI_D_ERROR, "Debug Agent: Debug port initialization failed.\n"));

    break;

  case DEBUG_AGENT_INIT_POSTMEM_SEC:
    Mailbox = GetMailboxPointer ();
    //
    // Memory has been ready
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
    if (IsHostAttached ()) {
      //
      // Trigger one software interrupt to inform HOST
      //
      TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
    }
    //
    // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
    //
    Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
      CpuDeadLoop ();
    }
    //
    // Fix up Debug Port handle address and mailbox address
    //
    DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;
    if (DebugAgentContext != NULL) {
      DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
      Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset);
      MailboxLocation = (UINT64)(UINTN)Mailbox;
      //
      // Build mailbox location in HOB and fix-up its address
      //
      MailboxLocationPointer = BuildGuidDataHob (
                                 &gEfiDebugAgentGuid,
                                 &MailboxLocation,
                                 sizeof (UINT64)
                                 );
      MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);
    } else {
      //
      // DebugAgentContext is NULL. Then, Mailbox can directly be copied into memory.
      // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer
      //
      Status = PeiServicesAllocatePages (
                 EfiACPIMemoryNVS,
                 EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),
                 &Address
                 );
      if (EFI_ERROR (Status)) {
        DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to allocate pages!\n"));
        CpuDeadLoop ();
      }
      NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
      //
      // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox
      // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core
      // reallocates the HOB.
      //
      CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
      CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize));
      UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));
      MailboxLocation = (UINT64)(UINTN)NewMailbox;
      //
      // Build mailbox location in HOB
      //
      MailboxLocationPointer = BuildGuidDataHob (
                                 &gEfiDebugAgentGuid,
                                 &MailboxLocation,
                                 sizeof (UINT64)
                                 );
    }
    //
    // Update IDT entry to save the location saved mailbox pointer
    //
    SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
    break;

  case DEBUG_AGENT_INIT_PEI:
    if (Context == NULL) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
      CpuDeadLoop ();
    }
    //
    // Check if Debug Agent has initialized before
    //
    if (IsDebugAgentInitialzed()) {
      DEBUG ((EFI_D_WARN, "Debug Agent: It has already initialized in SEC Core!\n"));
      break;
    }
    //
    // Install Vector Handoff Info PPI to persist vectors used by Debug Agent
    //
    Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n"));
      CpuDeadLoop ();
    }
    //
    // Set up IDT entries
    //
    InitializeDebugIdt ();
    //
    // Build mailbox in HOB and setup Mailbox Set In Pei flag
    //
    Mailbox = AllocateZeroPool (sizeof (DEBUG_AGENT_MAILBOX));
    MailboxLocation = (UINT64)(UINTN)Mailbox;
    MailboxLocationPointer = BuildGuidDataHob (
                               &gEfiDebugAgentGuid,
                               &MailboxLocation,
                               sizeof (UINT64)
                               );
    //
    // Initialize Debug Timer hardware and save its frequency
    //
    InitializeDebugTimer (&DebugTimerFrequency);
    UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
    //
    // Update IDT entry to save the location pointer saved mailbox pointer
    //
    SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
    //
    // Save init arch type when debug agent initialized
    //
    SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);
    //
    // Register for a callback once memory has been initialized.
    // If memery has been ready, the callback funtion will be invoked immediately
    //
    Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to register memory discovered callback function!\n"));
      CpuDeadLoop ();
    }
    //
    // Set HOB check flag if memory has not been ready yet
    //
    if (GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY) == 0) {
      SetDebugFlag (DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB, 1);
    }

    Phase2Context.InitFlag = InitFlag;
    Phase2Context.Context  = Context;
    Phase2Context.Function = Function;
    DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);

    FindAndReportModuleImageInfo (4);

    break;

  case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
    if (Context == NULL) {
      DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
      CpuDeadLoop ();
    } else {
      Ia32Idtr =  (IA32_DESCRIPTOR *) Context;
      Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
      MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
                                                (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
      Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer);
      //
      // Mailbox should valid and setup before executing thunk code
      //
      VerifyMailboxChecksum (Mailbox);

      DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL);
      UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
      //
      // Set up IDT entries
      //
      InitializeDebugIdt ();
      //
      // Update IDT entry to save location pointer saved the mailbox pointer
      //
      SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);

      FindAndReportModuleImageInfo (4);
    }
    break;

  default:
    //
    // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
    // Debug Agent library instance.
    //
    DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
    CpuDeadLoop ();
    break;
  }

  //
  // Enable CPU interrupts so debug timer interrupts can be delivered
  //
  EnableInterrupts ();

  //
  // If Function is not NULL, invoke it always whatever debug agent was initialized sucesssfully or not.
  //
  if (Function != NULL) {
    Function (Context);
  }
  //
  // Set return status for DEBUG_AGENT_INIT_PEI
  //
  if (InitFlag == DEBUG_AGENT_INIT_PEI && Context != NULL) {
    *(EFI_STATUS *)Context = EFI_SUCCESS;
  }
}
Example #30
0
/**
  Function for 'setvar' 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
ShellCommandRunSetVar (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  LIST_ENTRY          *Package;
  CHAR16              *ProblemParam;
  SHELL_STATUS        ShellStatus;
  CONST CHAR16        *VariableName;
  CONST CHAR16        *Data;
  EFI_GUID            Guid;
  CONST CHAR16        *StringGuid;
  UINT32              Attributes;
  VOID                *Buffer;
  UINTN               Size;
  UINTN               LoopVar;
  EFI_DEVICE_PATH_PROTOCOL           *DevPath;

  ShellStatus         = SHELL_SUCCESS;
  Status              = EFI_SUCCESS;
  Buffer              = NULL;
  Size                = 0;
  Attributes          = 0;
  DevPath             = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  Status = CommandInit();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  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;
    } else {
      ASSERT(FALSE);
    }
  } else {
    if (ShellCommandLineGetCount(Package) < 2) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else if (ShellCommandLineGetCount(Package) > 3) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      VariableName  = ShellCommandLineGetRawValue(Package, 1);
      Data          = ShellCommandLineGetRawValue(Package, 2);
      if (!ShellCommandLineGetFlag(Package, L"-guid")){
        CopyGuid(&Guid, &gEfiGlobalVariableGuid);
      } else {
        StringGuid = ShellCommandLineGetValue(Package, L"-guid");
        Status = ConvertStringToGuid(StringGuid, &Guid);
        if (EFI_ERROR(Status)) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, StringGuid);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      }
      if (Data == NULL || Data[0] !=  L'=') {
        //
        // Display what's there
        //
        Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          Buffer = AllocateZeroPool(Size);
          Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        }
        if (!EFI_ERROR(Status)&& Buffer != NULL) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);
          for (LoopVar = 0 ; LoopVar < Size ; LoopVar++) {
            ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);
          }
          ShellPrintEx(-1, -1, L"\r\n");
        } else {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
          ShellStatus = SHELL_ACCESS_DENIED;
        }
      } else if (StrCmp(Data, L"=") == 0) {
        //
        // Delete what's there!
        //
        Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, 0, NULL);
        if (EFI_ERROR(Status)) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
          ShellStatus = SHELL_ACCESS_DENIED;
        } else {
          ASSERT(ShellStatus == SHELL_SUCCESS);
        }
      } else {
        //
        // Change what's there or create a new one.
        //

        ASSERT(Data[0] == L'=');
        Data++;

        //
        // Determine if the variable exists and get the attributes
        //
        Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          Buffer = AllocateZeroPool(Size);
          Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        }

        if (EFI_ERROR(Status) || Buffer == NULL) {
          //
          // Creating a new variable.  determine attributes from command line.
          //
          Attributes = 0;
          if (ShellCommandLineGetFlag(Package, L"-bs")) {
            Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
          }
          if (ShellCommandLineGetFlag(Package, L"-rt")) {
            Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
                          EFI_VARIABLE_BOOTSERVICE_ACCESS;
          }
          if (ShellCommandLineGetFlag(Package, L"-nv")) {
            Attributes |= EFI_VARIABLE_NON_VOLATILE;
          }
        }
        SHELL_FREE_NON_NULL(Buffer);

        //
        // What type is the new data.
        //
        if (ShellIsHexOrDecimalNumber(Data, TRUE, FALSE)) {
          if (StrLen(Data) % 2 != 0) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, Data);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            //
            // arbitrary buffer
            //
            Buffer = AllocateZeroPool((StrLen(Data) / 2));
            if (Buffer == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
            } else {
              for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) {
                ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16);
                ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1]));
              }
              Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer);
            }
            if (EFI_ERROR(Status)) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
              ShellStatus = SHELL_ACCESS_DENIED;
            } else {
              ASSERT(ShellStatus == SHELL_SUCCESS);
            }
          }
        } else if (StrnCmp(Data, L"\"", 1) == 0) {
          //
          // ascii text
          //
          Data++;
          Buffer = AllocateZeroPool(StrSize(Data) / 2);
          if (Buffer == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
          } else {
            AsciiSPrint(Buffer, StrSize(Data) / 2, "%s", Data);
            ((CHAR8*)Buffer)[AsciiStrLen(Buffer)-1] = CHAR_NULL;
            Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, AsciiStrSize(Buffer)-sizeof(CHAR8), Buffer);
          }
          if (EFI_ERROR(Status)) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
            ShellStatus = SHELL_ACCESS_DENIED;
          } else {
            ASSERT(ShellStatus == SHELL_SUCCESS);
          }
        } else if (StrnCmp(Data, L"L\"", 2) == 0) {
          //
          // ucs2 text
          //
          Data++;
          Data++;
          Buffer = AllocateZeroPool(StrSize(Data));
          if (Buffer == NULL) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
            ShellStatus = SHELL_OUT_OF_RESOURCES;
          } else {
            UnicodeSPrint(Buffer, StrSize(Data), L"%s", Data);
            ((CHAR16*)Buffer)[StrLen(Buffer)-1] = CHAR_NULL;

            Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrSize(Buffer)-sizeof(CHAR16), Buffer);
            if (EFI_ERROR(Status)) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
              ShellStatus = SHELL_ACCESS_DENIED;
            } else {
              ASSERT(ShellStatus == SHELL_SUCCESS);
            }
          }
        } else if (StrnCmp(Data, L"--", 2) == 0) {
          //
          // device path in text format
          //
          Data++;
          Data++;
          DevPath = ConvertTextToDevicePath(Data);
          if (DevPath == NULL) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, Status);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, GetDevicePathSize(DevPath), DevPath);
            if (EFI_ERROR(Status)) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
              ShellStatus = SHELL_ACCESS_DENIED;
            } else {
              ASSERT(ShellStatus == SHELL_SUCCESS);
            }
          }
        } else {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Data);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      }
    }
    ShellCommandLineFreeVarList (Package);
  }

  if (Buffer != NULL) {
    FreePool(Buffer);
  }

  if (DevPath != NULL) {
    FreePool(DevPath);
  }

  return (ShellStatus);
}