/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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); }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
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; }
/** 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); }
/** 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; }
/** 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); }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
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; }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
/** 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); }
/** 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; } }
/** 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); }