VOID CopyMem ( IN VOID *Destination, IN VOID *Source, IN UINTN Length ) /*++ Routine Description: Copy Length bytes from Source to Destination. Arguments: Destination - Target of copy Source - Place to copy from Length - Number of bytes to copy Returns: None --*/ { EfiCommonLibCopyMem (Destination, Source, Length); }
EFI_STATUS EFIAPI MemoryDiscoveredPpiCallback ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, IN VOID *InvokePpi ) { PSP_MBOX *PspMbox; EFI_HOB_GUID_TYPE *GuidHob; EFI_STATUS Status; PSP_DEBUG ("Psp.PspPei.MemoryDiscoveredPpiCallback\n"); GetPspMboxLocation (&PspMbox); PspMboxBiosCmdDramInfo (); //The Recovery Flag may be set if PSP FW authenticate PSP OS & truslet //Fail during Service DramInfo command //Check PSP Recovery required Flag, if set publish GUID Hob if (PspMbox->MboxSts.Recovery) { PSP_DEBUG ("Recovery Flag Detected\n"); //Publish GUID HOB Status = (*PeiServices)->CreateHob (PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, sizeof (EFI_GUID) + sizeof (BOOLEAN), &GuidHob); ASSERT (Status == EFI_SUCCESS); EfiCommonLibCopyMem (&GuidHob->Name, &gPspCorruptDetectGuid, sizeof (EFI_GUID)); GuidHob++; //Set Recovery Flag to 1 *(BOOLEAN *)GuidHob = 1; } return (EFI_SUCCESS); }
VOID * EfiConstructStatusCodeData ( IN UINT16 DataSize, IN EFI_GUID *TypeGuid, IN OUT EFI_STATUS_CODE_DATA *Data ) /*++ Routine Description: Construct stanader header for optional data passed into ReportStatusCode Arguments: DataSize - Size of optional data. Does not include EFI_STATUS_CODE_DATA header TypeGuid - GUID to place in EFI_STATUS_CODE_DATA Data - Buffer to use. Returns: Return pointer to Data buffer pointing past the end of EFI_STATUS_CODE_DATA --*/ { Data->HeaderSize = (UINT16) sizeof (EFI_STATUS_CODE_DATA); Data->Size = (UINT16)(DataSize - sizeof (EFI_STATUS_CODE_DATA)); EfiCommonLibCopyMem (&Data->Type, TypeGuid, sizeof (EFI_GUID)); return (VOID *)(Data + 1); }
EFI_STATUS GetNextFirmwareVolume2Hob ( IN OUT VOID **HobStart, OUT EFI_PHYSICAL_ADDRESS *BaseAddress, OUT UINT64 *Length, OUT EFI_GUID *FileName ) /*++ Routine Description: Get next firmware volume2 hob from HobStart Arguments: HobStart - Start pointer of hob list BaseAddress - Start address of next firmware volume Length - Length of next firmware volume Returns: EFI_NOT_FOUND - Next firmware volume not found EFI_SUCCESS - Next firmware volume found with address information --*/ { EFI_PEI_HOB_POINTERS FirmwareVolumeHob; FirmwareVolumeHob.Raw = *HobStart; if (END_OF_HOB_LIST (FirmwareVolumeHob)) { return EFI_NOT_FOUND; } FirmwareVolumeHob.Raw = GetHob (EFI_HOB_TYPE_FV2, *HobStart); if (FirmwareVolumeHob.Header->HobType != EFI_HOB_TYPE_FV2) { return EFI_NOT_FOUND; } *BaseAddress = FirmwareVolumeHob.FirmwareVolume2->BaseAddress; *Length = FirmwareVolumeHob.FirmwareVolume2->Length; EfiCommonLibCopyMem(FileName,&FirmwareVolumeHob.FirmwareVolume2->FileName,sizeof(EFI_GUID)); *HobStart = GET_NEXT_HOB (FirmwareVolumeHob); return EFI_SUCCESS; }
/** * Send a TPM command * * @param[in] CommandBuffer Point to the TPM command buffer * @param[in] CommandSize Size of the TPM command buffer * * @return EFI_SUCCESS Command executed successfully * @return EFI_UNSUPPORTED Device unsupported * @return EFI_TIMEOUT Command fail due the time out * @return EFI_DEVICE_ERROR Command fail due the error status set * @return EFI_BUFFER_TOO_SMALL Response buffer too small to hold the response * */ EFI_STATUS iTpmSendCommand ( IN VOID *CommandBuffer, IN UINT32 CommandSize ) { TPM2_CONTROL_AREA *iTpmControlArea; EFI_PHYSICAL_ADDRESS PspBar1Addr; PSP_DEBUG ("PSP.fTPM.SendCmd\n"); //Validate Input parameters if ((CommandBuffer == NULL) || (CommandSize == 0)) { PSP_DEBUG ("\tInvalid parameters (PSP.fTPM.SendCmd)\n"); return EFI_INVALID_PARAMETER; } if (EFI_ERROR (CheckITPMSupported ())) { PSP_DEBUG ("\tfTPM Unsupported (PSP.fTPM.SendCmd)\n"); return EFI_UNSUPPORTED; } if (EFI_ERROR ( GetPspBar1Addr (&PspBar1Addr) ) ) { PSP_DEBUG ("\tfTPM Bar Error (PSP.fTPM.SendCmd)\n"); return EFI_UNSUPPORTED; } iTpmControlArea = (TPM2_CONTROL_AREA *) (UINTN) PspBar1Addr; ASSERT (iTpmControlArea->CommandAddress); ASSERT (iTpmControlArea->CommandSize); EfiCommonLibCopyMem ((VOID *) (UINTN) iTpmControlArea->CommandAddress, CommandBuffer, CommandSize); //Alway use the pre-allocated buffer to hold the response ASSERT (iTpmControlArea->ResponseAddress); iTpmControlArea->ResponseSize = iTPM_RESPONSE_BUFFER_SIZE; DEBUG_CODE ( DumpfTPMCommandBuffer (iTpmControlArea); )
EFI_STATUS EFIAPI FwVolBlockReadBlock ( IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, IN EFI_LBA Lba, IN UINTN Offset, IN OUT UINTN *NumBytes, IN UINT8 *Buffer ) /*++ Routine Description: Read the specified number of bytes from the block to the input buffer. Arguments: This - Indicates the calling context. Lba - The starting logical block index to read. Offset - Offset into the block at which to begin reading. NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the total size of the buffer. At exit, *NumBytes contains the total number of bytes actually read. Buffer - Pinter to a caller-allocated buffer that contains the destine for the read. Returns: EFI_SUCCESS - The firmware volume was read successfully. EFI_BAD_BUFFER_SIZE - The read was attempted across an LBA boundary. EFI_ACCESS_DENIED - Access denied. EFI_DEVICE_ERROR - The block device is malfunctioning and could not be read. --*/ { EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; UINT8 *LbaOffset; UINTN LbaStart; UINTN NumOfBytesRead; UINTN LbaIndex; FvbDevice = FVB_DEVICE_FROM_THIS (This); // // Check if This FW can be read // if ((FvbDevice->FvbAttributes & EFI_FVB_READ_STATUS) == 0) { return EFI_ACCESS_DENIED; } LbaIndex = (UINTN)Lba; if (LbaIndex >= FvbDevice->NumBlocks) { // // Invalid Lba, read nothing. // *NumBytes = 0; return EFI_BAD_BUFFER_SIZE; } if (Offset > FvbDevice->LbaCache[LbaIndex].Length) { // // all exceed boundry, read nothing. // *NumBytes = 0; return EFI_BAD_BUFFER_SIZE; } NumOfBytesRead = *NumBytes; if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) { // // partial exceed boundry, read data from current postion to end. // NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset; } LbaStart = FvbDevice->LbaCache[LbaIndex].Base; FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress); LbaOffset = (UINT8 *)FwVolHeader + LbaStart + Offset; // // Perform read operation // EfiCommonLibCopyMem (Buffer, LbaOffset, NumOfBytesRead); if (NumOfBytesRead == *NumBytes) { return EFI_SUCCESS; } *NumBytes = NumOfBytesRead; return EFI_BAD_BUFFER_SIZE; }
EFI_BOOTSERVICE EFI_STATUS EFIAPI CoreInstallConfigurationTable ( IN EFI_GUID *Guid, IN VOID *Table ) /*++ Routine Description: Boot Service called to add, modify, or remove a system configuration table from the EFI System Table. Arguments: Guid - Pointer to the GUID for the entry to add, update, or remove Table - Pointer to the configuration table for the entry to add, update, or remove, may be NULL. Returns: EFI_SUCCESS Guid, Table pair added, updated, or removed. EFI_INVALID_PARAMETER Input GUID not valid. EFI_NOT_FOUND Attempted to delete non-existant entry EFI_OUT_OF_RESOURCES Not enough memory available --*/ { UINTN Index; EFI_CONFIGURATION_TABLE *EfiConfigurationTable; // // If Guid is NULL, then this operation cannot be performed // if (Guid == NULL) { return EFI_INVALID_PARAMETER; } EfiConfigurationTable = gST->ConfigurationTable; // // Search all the table for an entry that matches Guid // for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { if (EfiCompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) { break; } } if (Index < gST->NumberOfTableEntries) { // // A match was found, so this is either a modify or a delete operation // if (Table != NULL) { // // If Table is not NULL, then this is a modify operation. // Modify the table enty and return. // gST->ConfigurationTable[Index].VendorTable = Table; #if (EFI_SPECIFICATION_VERSION >= 0x0002000A) // // Signal Configuration Table change // CoreNotifySignalList (Guid); #endif return EFI_SUCCESS; } // // A match was found and Table is NULL, so this is a delete operation. // gST->NumberOfTableEntries--; // // Copy over deleted entry // EfiCommonLibCopyMem ( &(EfiConfigurationTable[Index]), &(gST->ConfigurationTable[Index + 1]), (gST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE) ); } else { // // No matching GUIDs were found, so this is an add operation. // if (Table == NULL) { // // If Table is NULL on an add operation, then return an error. // return EFI_NOT_FOUND; } // // Assume that Index == gST->NumberOfTableEntries // if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) { // // Allocate a table with one additional entry. // mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE)); EfiConfigurationTable = CoreAllocateRuntimePool (mSystemTableAllocateSize); if (EfiConfigurationTable == NULL) { // // If a new table could not be allocated, then return an error. // return EFI_OUT_OF_RESOURCES; } if (gST->ConfigurationTable != NULL) { // // Copy the old table to the new table. // EfiCommonLibCopyMem ( EfiConfigurationTable, gST->ConfigurationTable, Index * sizeof (EFI_CONFIGURATION_TABLE) ); // // Free Old Table // CoreFreePool (gST->ConfigurationTable); } // // Update System Table // gST->ConfigurationTable = EfiConfigurationTable; } // // Fill in the new entry // EfiConfigurationTable[Index].VendorGuid = *Guid; EfiConfigurationTable[Index].VendorTable = Table; // // This is an add operation, so increment the number of table entries // gST->NumberOfTableEntries++; } // // Fix up the CRC-32 in the EFI System Table // CalculateEfiHdrCrc (&gST->Hdr); #if (EFI_SPECIFICATION_VERSION >= 0x0002000A) // // Signal Configuration Table change // CoreNotifySignalList (Guid); #endif return EFI_SUCCESS; }
EFI_BOOTSERVICE EFI_STATUS EFIAPI CoreCreateEventEx ( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext, IN CONST EFI_GUID *EventGroup, OPTIONAL OUT EFI_EVENT *Event ) /*++ Routine Description: Creates a general-purpose event structure Arguments: Type - The type of event to create and its mode and attributes NotifyTpl - The task priority level of event notifications NotifyFunction - Pointer to the events notification function NotifyContext - Pointer to the notification functions context; corresponds to parameter "Context" in the notification function EventGroup - GUID for EventGroup if NULL act the same as gBS->CreateEvent(). Event - Pointer to the newly created event if the call succeeds; undefined otherwise Returns: EFI_SUCCESS - The event structure was created EFI_INVALID_PARAMETER - One of the parameters has an invalid value EFI_OUT_OF_RESOURCES - The event could not be allocated --*/ { EFI_STATUS Status; IEVENT *IEvent; INTN Index; if ((Event == NULL) || (NotifyTpl == EFI_TPL_APPLICATION)) { return EFI_INVALID_PARAMETER; } // // For event group, type EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES and EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE // are not valid // if (EventGroup != NULL) { if ((Type == EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES) || (Type == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)) { return EFI_INVALID_PARAMETER; } } // // Check to make sure no reserved flags are set // Status = EFI_INVALID_PARAMETER; for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) { if (Type == mEventTable[Index]) { Status = EFI_SUCCESS; break; } } if(EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } // // Convert Event type for pre-defined Event groups // if (EventGroup != NULL) { if (EfiCompareGuid ((VOID *) EventGroup, &gEfiEventExitBootServicesGuid)) { Type = EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES; } else if (EfiCompareGuid ((VOID *) EventGroup, &gEfiEventVirtualAddressChangeGuid)) { Type = EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE; } } // // If it's a notify type of event, check its parameters // if ((Type & (EFI_EVENT_NOTIFY_WAIT | EFI_EVENT_NOTIFY_SIGNAL))) { // // Check for an invalid NotifyFunction or NotifyTpl // if ((NotifyFunction == NULL) || (NotifyTpl < EFI_TPL_APPLICATION) || (NotifyTpl >= EFI_TPL_HIGH_LEVEL)) { return EFI_INVALID_PARAMETER; } } else { // // No notification needed, zero ignored values // NotifyTpl = 0; NotifyFunction = NULL; NotifyContext = NULL; } // // Allcoate and initialize a new event structure. // Status = CoreAllocatePool ( (Type & EFI_EVENT_RUNTIME) ? EfiRuntimeServicesData: EfiBootServicesData, sizeof (IEVENT), (VOID **)&IEvent ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } EfiCommonLibSetMem (IEvent, sizeof (IEVENT), 0); IEvent->Signature = EVENT_SIGNATURE; IEvent->Type = Type; IEvent->NotifyTpl = NotifyTpl; IEvent->NotifyFunction = NotifyFunction; IEvent->NotifyContext = (VOID *)NotifyContext; if (EventGroup != NULL) { EfiCommonLibCopyMem (&IEvent->EventGroup, (VOID*)EventGroup, sizeof (EFI_GUID)); IEvent->ExFlag = TRUE; } *Event = IEvent; if (Type & EFI_EVENT_RUNTIME) { // // Keep a list of all RT events so we can tell the RT AP. // IEvent->RuntimeData.Type = Type; IEvent->RuntimeData.NotifyTpl = NotifyTpl; IEvent->RuntimeData.NotifyFunction = NotifyFunction; IEvent->RuntimeData.NotifyContext = NotifyContext; IEvent->RuntimeData.Event = (EFI_EVENT *) IEvent; InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link); } CoreAcquireEventLock (); if ((Type & EFI_EVENT_NOTIFY_SIGNAL) != 0x00000000) { // // The Event's NotifyFunction must be queued whenever the event is signaled // InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink); } CoreReleaseEventLock (); // // Done // return EFI_SUCCESS; }
VOID EfiLoader ( UINT32 BiosMemoryMapBaseAddress ) { BIOS_MEMORY_MAP *BiosMemoryMap; EFILDR_HEADER *EFILDRHeader; EFILDR_IMAGE *EFILDRImage; EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor[EFI_MAX_MEMORY_DESCRIPTORS]; EFI_STATUS Status; UINTN NumberOfMemoryMapEntries; UINT32 DestinationSize; UINT32 ScratchSize; UINTN BfvPageNumber; UINTN BfvBase; EFI_MAIN_ENTRYPOINT EfiMainEntrypoint; static EFILDRHANDOFF Handoff; PrintHeader ('A'); ClearScreen(); PrintString("EFI Loader\n"); // PrintString("&BiosMemoryMapBaseAddress = "); // PrintValue64 ((UINT64)(&BiosMemoryMapBaseAddress)); // PrintString(" BiosMemoryMapBaseAddress = "); // PrintValue(BiosMemoryMapBaseAddress); // PrintString("\n"); // // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then // round the start address up to the next page, and round the length down to a page boundry. // BiosMemoryMap = (BIOS_MEMORY_MAP *)(UINTN)(BiosMemoryMapBaseAddress); NumberOfMemoryMapEntries = 0; GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap); // // Get information on where the image is in memory // EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS); EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER)); PrintHeader ('D'); // // Point to the 4th image (Bfv) // EFILDRImage += 3; // // Decompress the image // Status = TianoGetInfo ( NULL, (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), EFILDRImage->Length, &DestinationSize, &ScratchSize ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } Status = TianoDecompress ( NULL, (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), EFILDRImage->Length, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize, (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000), ScratchSize ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize); BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB); if (BfvBase == 0) { EFI_DEADLOOP(); } EfiCommonLibZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE); EfiCommonLibCopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize); PrintHeader ('B'); // // Point to the 2nd image (DxeIpl) // EFILDRImage -= 2; // // Decompress the image // Status = TianoGetInfo ( NULL, (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), EFILDRImage->Length, &DestinationSize, &ScratchSize ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } Status = TianoDecompress ( NULL, (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), EFILDRImage->Length, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize, (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000), ScratchSize ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } // // Load and relocate the EFI PE/COFF Firmware Image // Status = EfiLdrPeCoffLoadPeImage ( (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), &DxeIplImage, &NumberOfMemoryMapEntries, EfiMemoryDescriptor ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } // PrintString("Image.NoPages = "); // PrintValue(Image.NoPages); // PrintString("\n"); PrintHeader ('C'); // // Point to the 3rd image (DxeMain) // EFILDRImage++; // // Decompress the image // Status = TianoGetInfo ( NULL, (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), EFILDRImage->Length, &DestinationSize, &ScratchSize ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } Status = TianoDecompress ( NULL, (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset), EFILDRImage->Length, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize, (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000), ScratchSize ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } // // Load and relocate the EFI PE/COFF Firmware Image // Status = EfiLdrPeCoffLoadPeImage ( (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), &DxeCoreImage, &NumberOfMemoryMapEntries, EfiMemoryDescriptor ); if (EFI_ERROR (Status)) { EFI_DEADLOOP(); } PrintHeader ('E'); // // Display the table of memory descriptors. // // PrintString("\nEFI Memory Descriptors\n"); /* { UINTN Index; for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) { PrintString("Type = "); PrintValue(EfiMemoryDescriptor[Index].Type); PrintString(" Start = "); PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart)); PrintString(" NumberOfPages = "); PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages)); PrintString("\n"); } } */ // // Jump to EFI Firmware // if (DxeIplImage.EntryPoint != NULL) { Handoff.MemDescCount = NumberOfMemoryMapEntries; Handoff.MemDesc = EfiMemoryDescriptor; Handoff.BfvBase = (VOID *)(UINTN)BfvBase; Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE; Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage; Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE; Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage; Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE; Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint; EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint; EfiMainEntrypoint (&Handoff); } PrintHeader ('F'); // // There was a problem loading the image, so HALT the system. // EFI_DEADLOOP(); }
EFI_STATUS EfiDebugVPrintWorker ( IN UINTN ErrorLevel, IN CHAR8 *Format, IN VA_LIST Marker, IN UINTN BufferSize, IN OUT VOID *Buffer ) /*++ Routine Description: Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT information. If Error Logging hub is not loaded do nothing. The Format string might be truncated to fit into the status code struture which has the max size of EFI_STATUS_CODE_DATA_MAX_SIZE. We use UINT64 buffers due to IPF alignment concerns. Arguments: ErrorLevel - If error level is set do the debug print. Format - String to use for the print, followed by Print arguments. Marker - VarArgs BufferSize - Size of Buffer. Buffer - Caller allocated buffer, contains ReportStatusCode extended data Returns: Status code EFI_SUCCESS - Successfully printed --*/ { UINTN Index; UINTN FormatStrLen; UINTN RemainingStrLen; UINT64 *Ptr; EFI_DEBUG_INFO *EfiDebug; // // Build the type specific EFI_STATUS_CODE_DATA in order // // // Fill in EFI_STATUS_CODE_DATA to Buffer. // EfiDebug = (EFI_DEBUG_INFO *)EfiConstructStatusCodeData ( (UINT16)BufferSize, &gEfiStatusCodeDataTypeDebugGuid, Buffer ); // // Then EFI_DEBUG_INFO // EfiDebug->ErrorLevel = (UINT32)ErrorLevel; // // 12 * sizeof (UINT64) byte mini Var Arg stack. // That is followed by the format string. // for (Index = 0, Ptr = (UINT64 *)(EfiDebug + 1); Index < 12; Index++, Ptr++) { *Ptr = VA_ARG (Marker, UINT64); } // // Place Ascii Format string at the end // Truncate it to fit into the status code structure // FormatStrLen = EfiAsciiStrLen (Format); RemainingStrLen = EFI_STATUS_CODE_DATA_MAX_SIZE - sizeof (EFI_STATUS_CODE_DATA) - sizeof (EFI_DEBUG_INFO) - 12 * sizeof (UINT64) - 1; if (FormatStrLen > RemainingStrLen) { FormatStrLen = RemainingStrLen; } EfiCommonLibCopyMem (Ptr, Format, FormatStrLen); *((CHAR8 *) Ptr + FormatStrLen) = '\0'; return EFI_SUCCESS; }