/** Prints an assert message containing a filename, line number, and description. This may be followed by a breakpoint or a dead loop. Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n" to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then CpuDeadLoop() is called. If neither of these bits are set, then this function returns immediately after the message is printed to the debug output device. DebugAssert() must actively prevent recusrsion. If DebugAssert() is called while processing another DebugAssert(), then DebugAssert() must return immediately. If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. If Description is NULL, then a <Description> string of "(NULL) Description" is printed. @param FileName Pointer to the name of the source file that generated the assert condition. @param LineNumber The line number in the source file that generated the assert condition @param Description Pointer to the description of the assert condition. **/ VOID EFIAPI DebugAssert ( IN CONST CHAR8 *FileName, IN UINTN LineNumber, IN CONST CHAR8 *Description ) { UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof(UINT64)]; EFI_DEBUG_ASSERT_DATA *AssertData; UINTN TotalSize; CHAR8 *Temp; UINTN FileNameLength; UINTN DescriptionLength; // // Make sure it will all fit in the passed in buffer // FileNameLength = AsciiStrLen (FileName); DescriptionLength = AsciiStrLen (Description); TotalSize = sizeof (EFI_DEBUG_ASSERT_DATA) + FileNameLength + 1 + DescriptionLength + 1; if (TotalSize <= EFI_STATUS_CODE_DATA_MAX_SIZE) { // // Fill in EFI_DEBUG_ASSERT_DATA // AssertData = (EFI_DEBUG_ASSERT_DATA *)Buffer; AssertData->LineNumber = (UINT32)LineNumber; // // Copy Ascii FileName including NULL. // Temp = AsciiStrCpy ((CHAR8 *)(AssertData + 1), FileName); // // Copy Ascii Description // AsciiStrCpy (Temp + AsciiStrLen (FileName) + 1, Description); REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED), (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE), AssertData, TotalSize ); } // // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings // if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { CpuBreakpoint (); } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { CpuDeadLoop (); } }
EFI_STATUS FileDelete ( IN EFI_FILE *File ) { SEMIHOST_FCB *Fcb = NULL; EFI_STATUS Status; CHAR8 *FileName; UINTN NameSize; Fcb = SEMIHOST_FCB_FROM_THIS(File); if (!Fcb->IsRoot) { // Get the filename from the Fcb NameSize = AsciiStrLen (Fcb->FileName); FileName = AllocatePool (NameSize + 1); AsciiStrCpy (FileName, Fcb->FileName); // Close the file if it's open. Disregard return status, // since it might give an error if the file isn't open. File->Close (File); // Call the semihost interface to delete the file. Status = SemihostFileRemove (FileName); } else { Status = EFI_UNSUPPORTED; } return Status; }
/** ‘G XX...’ Writes the new values received into the input buffer to the general registers @param SystemContext Register content at time of the exception @param InBuffer Pointer to the input buffer received from gdb server **/ VOID EFIAPI WriteGeneralRegisters ( IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *InBuffer ) { UINTN i; CHAR8 *InBufPtr; /// pointer to the input buffer // check to see if the buffer is the right size which is // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129 if (AsciiStrLen(InBuffer) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq) //Bad message. Message is not the right length SendError (GDB_EBADBUFSIZE); return; } InBufPtr = &InBuffer[1]; // Read the new values for the registers from the input buffer to an array, NewValueArray. // The values in the array are in the gdb ordering for(i=0; i < sizeof (gRegisterOffsets)/sizeof (UINTN); i++) { // there are only 16 registers to write InBufPtr = BasicWriteRegister(SystemContext, i, InBufPtr); } SendSuccess(); }
/** Prints a debug message to the debug output device if the specified error level is enabled. If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function GetDebugPrintErrorLevel (), then print the message specified by Format and the associated variable argument list to the debug output device. If Format is NULL, then ASSERT(). @param ErrorLevel The error level of the debug message. @param Format Format string for the debug message to print. @param ... A variable argument list whose contents are accessed based on the format string specified by Format. **/ VOID EFIAPI DebugPrint ( IN UINTN ErrorLevel, IN CONST CHAR8 *Format, ... ) { CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; VA_LIST Marker; // // If Format is NULL, then ASSERT(). // ASSERT (Format != NULL); // // Check driver debug mask value and global mask // if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) { return; } // // Convert the DEBUG() message to an ASCII String // VA_START (Marker, Format); AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker); VA_END (Marker); // // Send the print string to EFI_DEBUGPORT_PROTOCOL.Write. // UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer)); }
/** Extracts ASSERT() information from a status code structure. Converts the status code specified by CodeType, Value, and Data to the ASSERT() arguments specified by Filename, Description, and LineNumber. If CodeType is an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract Filename, Description, and LineNumber from the optional data area of the status code buffer specified by Data. The optional data area of Data contains a Null-terminated ASCII string for the FileName, followed by a Null-terminated ASCII string for the Description, followed by a 32-bit LineNumber. If the ASSERT() information could be extracted from Data, then return TRUE. Otherwise, FALSE is returned. If Data is NULL, then ASSERT(). If Filename is NULL, then ASSERT(). If Description is NULL, then ASSERT(). If LineNumber is NULL, then ASSERT(). @param CodeType The type of status code being converted. @param Value The status code value being converted. @param Data Pointer to status code data buffer. @param Filename Pointer to the source file name that generated the ASSERT(). @param Description Pointer to the description of the ASSERT(). @param LineNumber Pointer to source line number that generated the ASSERT(). @retval TRUE The status code specified by CodeType, Value, and Data was converted ASSERT() arguments specified by Filename, Description, and LineNumber. @retval FALSE The status code specified by CodeType, Value, and Data could not be converted to ASSERT() arguments. **/ BOOLEAN EFIAPI ReportStatusCodeExtractAssertInfo ( IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, IN CONST EFI_STATUS_CODE_DATA *Data, OUT CHAR8 **Filename, OUT CHAR8 **Description, OUT UINT32 *LineNumber ) { EFI_DEBUG_ASSERT_DATA *AssertData; ASSERT (Data != NULL); ASSERT (Filename != NULL); ASSERT (Description != NULL); ASSERT (LineNumber != NULL); if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) && ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) && ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) { AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1); *Filename = (CHAR8 *)(AssertData + 1); *Description = *Filename + AsciiStrLen (*Filename) + 1; *LineNumber = AssertData->LineNumber; return TRUE; } return FALSE; }
VOID EFIAPI WriteGeneralRegisters ( IN EFI_SYSTEM_CONTEXT SystemContext, IN CHAR8 *InBuffer ) { UINTN i; CHAR8 *InBufPtr; /// pointer to the input buffer UINTN MinLength; UINTN RegisterCount = (sizeof (gRegisterOffsets)/sizeof (UINTN)); MinLength = (RegisterCount * 8) + 1; // 'G' plus the registers in ASCII format if (AsciiStrLen(InBuffer) < MinLength) { //Bad message. Message is not the right length SendError (GDB_EBADBUFSIZE); return; } InBufPtr = &InBuffer[1]; // Read the new values for the registers from the input buffer to an array, NewValueArray. // The values in the array are in the gdb ordering for(i = 0; i < RegisterCount; i++) { InBufPtr = BasicWriteRegister (SystemContext, i, InBufPtr); } SendSuccess (); }
STATIC VOID SetupCmdlineTag ( IN CONST CHAR8 *CmdLine ) { UINT32 LineLength; // Increment the line length by 1 to account for the null string terminator character LineLength = AsciiStrLen(CmdLine) + 1; /* Check for NULL strings. * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer. * Remember, you have at least one null string terminator character. */ if(LineLength > 1) { mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof(LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2; mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE; /* place CommandLine into tag */ AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine); // move pointer to next tag mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag); }
RETURN_STATUS SemihostFileOpen ( IN CHAR8 *FileName, IN UINT32 Mode, OUT UINT32 *FileHandle ) { SEMIHOST_FILE_OPEN_BLOCK OpenBlock; INT32 Result; if (FileHandle == NULL) { return RETURN_INVALID_PARAMETER; } OpenBlock.FileName = FileName; OpenBlock.Mode = Mode; OpenBlock.NameLength = AsciiStrLen(FileName); Result = Semihost_SYS_OPEN(&OpenBlock); if (Result == -1) { return RETURN_NOT_FOUND; } else { *FileHandle = Result; return RETURN_SUCCESS; } }
/** Get section entry GUID value. @param[in] Context INI Config file context. @param[in] SectionName Section name. @param[in] EntryName Section entry name. @param[out] Guid Point to the got GUID value. @retval EFI_SUCCESS Section entry GUID value is got. @retval EFI_NOT_FOUND Section is not found. **/ EFI_STATUS EFIAPI GetGuidFromDataFile ( IN VOID *Context, IN CHAR8 *SectionName, IN CHAR8 *EntryName, OUT EFI_GUID *Guid ) { CHAR8 *Value; EFI_STATUS Status; if (Context == NULL || SectionName == NULL || EntryName == NULL || Guid == NULL) { return EFI_INVALID_PARAMETER; } Status = GetStringFromDataFile( Context, SectionName, EntryName, &Value ); if (EFI_ERROR(Status)) { return EFI_NOT_FOUND; } ASSERT (Value != NULL); if (!IsValidGuid(Value, AsciiStrLen(Value))) { return EFI_NOT_FOUND; } Status = AsciiStrToGuid(Value, Guid); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } return EFI_SUCCESS; }
/** The initator checks the CHAP response replied by target against its own calculation of the expected hash value. @param[in] AuthData iSCSI CHAP authentication data. @param[in] TargetResponse The response from target. @retval EFI_SUCCESS The response from target passed authentication. @retval EFI_SECURITY_VIOLATION The response from target was not expected value. @retval Others Other errors as indicated. **/ EFI_STATUS IScsiCHAPAuthTarget ( IN ISCSI_CHAP_AUTH_DATA *AuthData, IN UINT8 *TargetResponse ) { EFI_STATUS Status; UINT32 SecretSize; UINT8 VerifyRsp[ISCSI_CHAP_RSP_LEN]; Status = EFI_SUCCESS; SecretSize = (UINT32) AsciiStrLen (AuthData->AuthConfig->ReverseCHAPSecret); Status = IScsiCHAPCalculateResponse ( AuthData->OutIdentifier, AuthData->AuthConfig->ReverseCHAPSecret, SecretSize, AuthData->OutChallenge, AuthData->OutChallengeLength, VerifyRsp ); if (CompareMem (VerifyRsp, TargetResponse, ISCSI_CHAP_RSP_LEN) != 0) { Status = EFI_SECURITY_VIOLATION; } return Status; }
CHAR8* NewSymbol(CHAR8* string) { SymbolPtr lastGuy = 0; SymbolPtr symbol; // Look for string in the list of symbols. symbol = FindSymbol(string, 0); // Add the new symbol. if (symbol == NULL) { symbol = (SymbolPtr)AllocateZeroPool(sizeof(Symbol) + 1 + AsciiStrLen(string)); if (symbol == NULL) return NULL; // Set the symbol's data. symbol->refCount = 0; AsciiStrCpy(symbol->string, string); // Add the symbol to the list. symbol->next = gSymbolsHead; gSymbolsHead = symbol; } // Update the refCount and return the string. symbol->refCount++; if (lastGuy && lastGuy->next != 0) return NULL; return symbol->string; }
/** Prints an assert message containing a filename, line number, and description. This may be followed by a breakpoint or a dead loop. Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n" to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then CpuDeadLoop() is called. If neither of these bits are set, then this function returns immediately after the message is printed to the debug output device. DebugAssert() must actively prevent recursion. If DebugAssert() is called while processing another DebugAssert(), then DebugAssert() must return immediately. If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. If Description is NULL, then a <Description> string of "(NULL) Description" is printed. @param FileName The pointer to the name of the source file that generated the assert condition. @param LineNumber The line number in the source file that generated the assert condition @param Description The pointer to the description of the assert condition. **/ VOID EFIAPI DebugAssert ( IN CONST CHAR8 *FileName, IN UINTN LineNumber, IN CONST CHAR8 *Description ) { CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; // // Generate the ASSERT() message in Ascii format // AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT %a(%d): %a\n", FileName, LineNumber, Description); // // Send the print string to the Console Output device // AcquireSpinLock (&mInternalDebugLock); SerialPortWrite ((UINT8 *) Buffer, AsciiStrLen(Buffer)); ReleaseSpinLock (&mInternalDebugLock); // // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings // if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { CpuBreakpoint (); } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { CpuDeadLoop (); } }
/** Get section entry heximal UINT64 value. @param[in] Context INI Config file context. @param[in] SectionName Section name. @param[in] EntryName Section entry name. @param[out] Data Point to the got heximal UINT64 value. @retval EFI_SUCCESS Section entry heximal UINT64 value is got. @retval EFI_NOT_FOUND Section is not found. **/ EFI_STATUS EFIAPI GetHexUint64FromDataFile ( IN VOID *Context, IN CHAR8 *SectionName, IN CHAR8 *EntryName, OUT UINT64 *Data ) { CHAR8 *Value; EFI_STATUS Status; if (Context == NULL || SectionName == NULL || EntryName == NULL || Data == NULL) { return EFI_INVALID_PARAMETER; } Status = GetStringFromDataFile( Context, SectionName, EntryName, &Value ); if (EFI_ERROR(Status)) { return EFI_NOT_FOUND; } ASSERT (Value != NULL); if (!IsValidHexString(Value, AsciiStrLen(Value))) { return EFI_NOT_FOUND; } *Data = AsciiStrHexToUint64(Value); return EFI_SUCCESS; }
/** Save this command in the circular history buffer. Older commands are overwritten with newer commands. @param Cmd Command line to archive the history of. @return None **/ VOID SetCmdHistory ( IN CHAR8 *Cmd ) { // Don't bother adding empty commands to the list if (AsciiStrLen(Cmd) != 0) { // First entry if (mCmdHistoryStart == -1) { mCmdHistoryStart = 0; mCmdHistoryEnd = 0; } else { // Record the new command at the next index RingBufferIncrement(&mCmdHistoryStart); // If the next index runs into the end index, shuffle end back by one if (mCmdHistoryStart == mCmdHistoryEnd) { RingBufferIncrement(&mCmdHistoryEnd); } } // Copy the new command line into the ring buffer AsciiStrnCpyS (&mCmdHistory[mCmdHistoryStart][0], MAX_CMD_LINE, Cmd, MAX_CMD_LINE); } // Reset the command history for the next up arrow press mCmdHistoryCurrent = mCmdHistoryStart; }
/** Prints a debug message to the debug output device if the specified error level is enabled. If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print the message specified by Format and the associated variable argument list to the debug output device. If Format is NULL, then ASSERT(). @param ErrorLevel The error level of the debug message. @param Format Format string for the debug message to print. **/ VOID EFIAPI DebugPrint ( IN UINTN ErrorLevel, IN CONST CHAR8 *Format, ... ) { UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)]; EFI_DEBUG_INFO *DebugInfo; UINTN TotalSize; UINTN Index; VA_LIST Marker; UINT64 *ArgumentPointer; // // If Format is NULL, then ASSERT(). // ASSERT (Format != NULL); // // Check driver Debug Level value and global debug level // if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) { return; } TotalSize = sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64) + AsciiStrLen (Format) + 1; if (TotalSize > EFI_STATUS_CODE_DATA_MAX_SIZE) { return; } // // Then EFI_DEBUG_INFO // DebugInfo = (EFI_DEBUG_INFO *)Buffer; DebugInfo->ErrorLevel = (UINT32)ErrorLevel; // // 256 byte mini Var Arg stack. That is followed by the format string. // VA_START (Marker, Format); for (Index = 0, ArgumentPointer = (UINT64 *)(DebugInfo + 1); Index < 12; Index++, ArgumentPointer++) { WriteUnaligned64(ArgumentPointer, VA_ARG (Marker, UINT64)); } VA_END (Marker); AsciiStrCpy ((CHAR8 *)ArgumentPointer, Format); REPORT_STATUS_CODE_EX ( EFI_DEBUG_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED), 0, NULL, &gEfiStatusCodeDataTypeDebugGuid, DebugInfo, TotalSize ); }
STATIC EFI_STATUS GetFileInfo ( IN SEMIHOST_FCB *Fcb, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { EFI_FILE_INFO *Info = NULL; UINTN NameSize = 0; UINTN ResultSize; UINTN Index; UINTN Length; EFI_STATUS Status; if (Fcb->IsRoot == TRUE) { ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16); } else { NameSize = AsciiStrLen (Fcb->FileName) + 1; ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16); } if (*BufferSize < ResultSize) { *BufferSize = ResultSize; return EFI_BUFFER_TOO_SMALL; } Info = Buffer; // Zero out the structure ZeroMem (Info, SIZE_OF_EFI_FILE_INFO); // Fill in the structure Info->Size = ResultSize; if (Fcb->IsRoot == TRUE) { Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; Info->FileName[0] = L'\0'; } else { Status = SemihostFileLength (Fcb->SemihostHandle, &Length); if (EFI_ERROR(Status)) { return Status; } Info->FileSize = Length; Info->PhysicalSize = Length; for (Index = 0; Index < NameSize; Index++) { Info->FileName[Index] = Fcb->FileName[Index]; } } *BufferSize = ResultSize; return EFI_SUCCESS; }
/** Collect the keyboard input for a cmd line. Carriage Return, New Line, or ESC terminates the command line. You can edit the command line via left arrow, delete and backspace and they all back up and erase the command line. No edit of command line is possible without deletion at this time! The up arrow and down arrow fill Cmd with information from the history buffer. @param Cmd Command line to return @param CmdMaxSize Maximum size of Cmd @return The Status of EblGetCharKey() **/ EFI_STATUS GetCmd ( IN OUT CHAR8 *Cmd, IN UINTN CmdMaxSize ) { EFI_STATUS Status; UINTN Index; UINTN Index2; CHAR8 Char; CHAR8 *History; EFI_INPUT_KEY Key; for (Index = 0; Index < CmdMaxSize - 1;) { Status = EblGetCharKey (&Key, 0, NULL); if (EFI_ERROR (Status)) { Cmd[Index] = '\0'; AsciiPrint ("\n"); return Status; } Char = (CHAR8)Key.UnicodeChar; if ((Char == '\n') || (Char == '\r') || (Char == 0x7f)) { Cmd[Index] = '\0'; if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) { AsciiPrint ("\n\r"); } return EFI_SUCCESS; } else if ((Char == '\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){ if (Index != 0) { Index--; // // Update the display // AsciiPrint ("\b \b"); } } else if ((Key.ScanCode == SCAN_UP) || Key.ScanCode == SCAN_DOWN) { History = GetCmdHistory (Key.ScanCode); // // Clear display line // for (Index2 = 0; Index2 < Index; Index2++) { AsciiPrint ("\b \b"); } AsciiPrint (History); Index = AsciiStrLen (History); AsciiStrnCpyS (Cmd, CmdMaxSize, History, CmdMaxSize); } else { Cmd[Index++] = Char; if (FixedPcdGetBool(PcdEmbeddedShellCharacterEcho) == TRUE) { AsciiPrint ("%c", Char); } } } return EFI_SUCCESS; }
/** Notification function of the event defined as belonging to the EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in the entry point of the driver. This function is called when an event belonging to the EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an event is signalled once at the end of the dispatching of all drivers (end of the so called DXE phase). @param[in] Event Event declared in the entry point of the driver whose notification function is being invoked. @param[in] Context NULL **/ STATIC VOID OnEndOfDxe ( IN EFI_EVENT Event, IN VOID *Context ) { UINT32 BootMode; VOID *RecoveryStr; VOID *SwitchStr; BootMode = MmioRead32 (SCTRL_BAK_DATA0) & BOOT_MODE_MASK; if (BootMode == BOOT_MODE_RECOVERY) { RecoveryStr = "WARNING: CAN NOT BOOT KERNEL IN RECOVERY MODE!\r\n"; SwitchStr = "Switch to normal boot mode, then reboot to boot kernel.\r\n"; SerialPortWrite (RecoveryStr, AsciiStrLen (RecoveryStr)); SerialPortWrite (SwitchStr, AsciiStrLen (SwitchStr)); } }
CHAR8* XMLDecode(const CHAR8* src) { typedef const struct XMLEntity { const CHAR8* name; UINTN nameLen; CHAR8 value; } XMLEntity; /* This is ugly, but better than specifying the lengths by hand */ #define _e(str,c) {str,sizeof(str)-1,c} const XMLEntity ents[] = { _e("quot;",'"'), _e("apos;",'\''), _e("lt;", '<'), _e("gt;", '>'), _e("amp;", '&') }; UINTN len; const CHAR8 *s; CHAR8 *out, *o; if ( !src || !(len = AsciiStrLen(src)) || !(out = AllocateZeroPool(len+1)) ) return 0; o = out; s = src; while (s <= src+len) /* Make sure the terminator is also copied */ { if ( *s == '&' ) { BOOLEAN entFound = FALSE; UINTN i; s++; for ( i = 0; i < sizeof(ents); i++) { if ( AsciiStrnCmp(s, ents[i].name, ents[i].nameLen) == 0 ) { entFound = TRUE; break; } } if ( entFound ) { *o++ = ents[i].value; s += ents[i].nameLen; continue; } } *o++ = *s++; } return out; }
EFIAPI EFI_STATUS BootMonFsReadDirectory ( IN EFI_FILE_PROTOCOL *This, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { BOOTMON_FS_INSTANCE *Instance; BOOTMON_FS_FILE *RootFile; BOOTMON_FS_FILE *File; EFI_FILE_INFO *Info; UINTN NameSize; UINTN ResultSize; EFI_STATUS Status; UINTN Index; RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This); if (RootFile == NULL) { return EFI_INVALID_PARAMETER; } Instance = RootFile->Instance; Status = BootMonGetFileFromPosition (Instance, RootFile->Position, &File); if (EFI_ERROR (Status)) { // No more file *BufferSize = 0; return EFI_SUCCESS; } NameSize = AsciiStrLen (File->HwDescription.Footer.Filename) + 1; ResultSize = SIZE_OF_EFI_FILE_INFO + (NameSize * sizeof (CHAR16)); if (*BufferSize < ResultSize) { *BufferSize = ResultSize; return EFI_BUFFER_TOO_SMALL; } // Zero out the structure Info = Buffer; ZeroMem (Info, ResultSize); // Fill in the structure Info->Size = ResultSize; Info->FileSize = BootMonFsGetImageLength (File); Info->PhysicalSize = BootMonFsGetPhysicalSize (File); for (Index = 0; Index < NameSize; Index++) { Info->FileName[Index] = File->HwDescription.Footer.Filename[Index]; } *BufferSize = ResultSize; RootFile->Position++; return EFI_SUCCESS; }
/** Transmit the HTTP mssage by processing the associated HTTP token. @param[in] Map The container of TxToken. @param[in] Item Current item to check against. @param[in] Context The Token to check againist. @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. @retval EFI_SUCCESS The HTTP message is queued into TCP transmit queue. **/ EFI_STATUS EFIAPI HttpTcpTransmit ( IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context ) { HTTP_TOKEN_WRAP *ValueInItem; EFI_STATUS Status; CHAR8 *RequestStr; CHAR8 *Url; ValueInItem = (HTTP_TOKEN_WRAP *) Item->Value; if (ValueInItem->TcpWrap.IsTxDone) { return EFI_SUCCESS; } // // Parse the URI of the remote host. // Url = AllocatePool (StrLen (ValueInItem->HttpToken->Message->Data.Request->Url) + 1); if (Url == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStr (ValueInItem->HttpToken->Message->Data.Request->Url, Url); // // Create request message. // RequestStr = HttpGenRequestString ( ValueInItem->HttpInstance, ValueInItem->HttpToken->Message, Url ); FreePool (Url); if (RequestStr == NULL) { return EFI_OUT_OF_RESOURCES; } // // Transmit the request message. // Status = HttpTransmitTcp4 ( ValueInItem->HttpInstance, ValueInItem, (UINT8*) RequestStr, AsciiStrLen (RequestStr) ); FreePool (RequestStr); return Status; }
UINT32 SemihostSystem ( IN CHAR8 *CommandLine ) { SEMIHOST_SYSTEM_BLOCK SystemBlock; SystemBlock.CommandLine = CommandLine; SystemBlock.CommandLength = AsciiStrLen(CommandLine); return Semihost_SYS_SYSTEM(&SystemBlock); }
CHAR16* Ascii2Unicode ( CONST CHAR8* AsciiStr ) { CHAR16* UnicodeStr = AllocatePool((AsciiStrLen (AsciiStr) + 1) * sizeof (CHAR16)); if (UnicodeStr == NULL) { return NULL; } AsciiStrToUnicodeStr(AsciiStr, UnicodeStr); return UnicodeStr; }
EFI_STATUS GetFileInfo ( IN BOOTMON_FS_INSTANCE *Instance, IN BOOTMON_FS_FILE *File, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { EFI_FILE_INFO *Info; UINTN ResultSize; UINTN NameSize; UINTN Index; if (File == Instance->RootFile) { NameSize = 0; ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof (CHAR16); } else { NameSize = AsciiStrLen (File->HwDescription.Footer.Filename) + 1; ResultSize = SIZE_OF_EFI_FILE_INFO + (NameSize * sizeof (CHAR16)); } if (*BufferSize < ResultSize) { *BufferSize = ResultSize; return EFI_BUFFER_TOO_SMALL; } Info = Buffer; // Zero out the structure ZeroMem (Info, ResultSize); // Fill in the structure Info->Size = ResultSize; if (File == Instance->RootFile) { Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; Info->FileName[0] = L'\0'; } else { Info->FileSize = BootMonFsGetImageLength (File); Info->PhysicalSize = BootMonFsGetPhysicalSize (File); for (Index = 0; Index < NameSize; Index++) { Info->FileName[Index] = File->HwDescription.Footer.Filename[Index]; } } *BufferSize = ResultSize; return EFI_SUCCESS; }
/** Check if lang is in supported language codes according to language string. This code is used to check if lang is in in supported language codes. It can handle RFC4646 and ISO639 language tags. In ISO639 language tags, take 3-characters as a delimitation to find matched string. In RFC4646 language tags, take semicolon as a delimitation to find matched string. For example: SupportedLang = "engfraengfra" Iso639Language = TRUE Lang = "eng", the return value is "TRUE", or Lang = "chs", the return value is "FALSE". Another example: SupportedLang = "en;fr;en-US;fr-FR" Iso639Language = FALSE Lang = "en", the return value is "TRUE", or Lang = "zh", the return value is "FALSE". @param SupportedLang Platform supported language codes. @param Lang Configured language. @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646. @retval TRUE lang is in supported language codes. @retval FALSE lang is not in supported language codes. **/ BOOLEAN IsLangInSupportedLangCodes( IN CHAR8 *SupportedLang, IN CHAR8 *Lang, IN BOOLEAN Iso639Language ) { UINTN Index; UINTN CompareLength; UINTN LanguageLength; if (Iso639Language) { CompareLength = ISO_639_2_ENTRY_SIZE; for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) { if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) { // // Successfully find the Lang string in SupportedLang string. // return TRUE; } } return FALSE; } else { // // Compare RFC4646 language code // for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++); for (; *SupportedLang != '\0'; SupportedLang += CompareLength) { // // Skip ';' characters in SupportedLang // for (; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++); // // Determine the length of the next language code in SupportedLang // for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++); if ((CompareLength == LanguageLength) && (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0)) { // // Successfully find the Lang string in SupportedLang string. // return TRUE; } } return FALSE; } }
/** Return information about a file. @param[in] Fcb A pointer to the description of an open file. @param[in out] BufferSize The size, in bytes, of Buffer. @param[out] Buffer A pointer to the data buffer to return. Not NULL if "*BufferSize" is greater than 0. @retval EFI_SUCCESS The information was returned. @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to return the information. BufferSize has been updated with the size needed to complete the request. **/ STATIC EFI_STATUS GetFileInfo ( IN SEMIHOST_FCB *Fcb, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { EFI_FILE_INFO *Info = NULL; UINTN NameSize = 0; UINTN ResultSize; UINTN Index; if (Fcb->IsRoot == TRUE) { ResultSize = SIZE_OF_EFI_FILE_INFO + sizeof(CHAR16); } else { NameSize = AsciiStrLen (Fcb->FileName) + 1; ResultSize = SIZE_OF_EFI_FILE_INFO + NameSize * sizeof (CHAR16); } if (*BufferSize < ResultSize) { *BufferSize = ResultSize; return EFI_BUFFER_TOO_SMALL; } Info = Buffer; // Copy the current file info CopyMem (Info, &Fcb->Info, SIZE_OF_EFI_FILE_INFO); // Fill in the structure Info->Size = ResultSize; if (Fcb->IsRoot == TRUE) { Info->FileName[0] = L'\0'; } else { for (Index = 0; Index < NameSize; Index++) { Info->FileName[Index] = Fcb->FileName[Index]; } } *BufferSize = ResultSize; return EFI_SUCCESS; }
EFI_STATUS ParseXML(const CHAR8* buffer, TagPtr * dict) { EFI_STATUS Status; UINT32 length=0; UINT32 pos=0; TagPtr tag=NULL; CHAR8* configBuffer=NULL; UINT32 bufferSize=(UINT32)AsciiStrLen(buffer)+1; if(dict==NULL) return EFI_UNSUPPORTED; *dict=NULL; configBuffer=AllocateZeroPool(bufferSize); if(configBuffer==NULL) return EFI_UNSUPPORTED; CopyMem(configBuffer,buffer,bufferSize); buffer_start = configBuffer; while (TRUE) { Status = XMLParseNextTag(configBuffer + pos, &tag, &length); if (EFI_ERROR(Status)) break; pos += length; if (tag == NULL) continue; if (tag->type == kTagTypeDict) break; FreeTag(tag); } FreePool(configBuffer); if (EFI_ERROR(Status)) return Status; *dict = tag; return EFI_SUCCESS; }
/** Measure and log an action string, and extend the measurement result into PCR[5]. @param[in] String A specific string that indicates an Action event. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_DEVICE_ERROR The operation was unsuccessful. **/ EFI_STATUS EFIAPI TcgMeasureAction ( IN CHAR8 *String ) { TCG_PCR_EVENT_HDR TcgEvent; TcgEvent.PCRIndex = 5; TcgEvent.EventType = EV_EFI_ACTION; TcgEvent.EventSize = (UINT32)AsciiStrLen (String); return TcgDxeHashLogExtendEventI ( &mTcgDxeData, (UINT8*)String, TcgEvent.EventSize, &TcgEvent, (UINT8 *) String ); }
RETURN_STATUS SemihostFileRemove ( IN CHAR8 *FileName ) { SEMIHOST_FILE_REMOVE_BLOCK RemoveBlock; UINT32 Result; RemoveBlock.FileName = FileName; RemoveBlock.NameLength = AsciiStrLen(FileName); Result = Semihost_SYS_REMOVE(&RemoveBlock); if (Result == 0) { return RETURN_SUCCESS; } else { return RETURN_ABORTED; } }
/** Internal work function to extract a device number from a string skipping text. Easy way to extract numbers from strings like blk7:. @param Str String to extract device number form @return -1 Device string is not valid @return Device # **/ UINTN EblConvertDevStringToNumber ( IN CHAR8 *Str ) { UINTN Max; UINTN Index; // Find the first digit Max = AsciiStrLen (Str); for (Index = 0; !((*Str >= '0') && (*Str <= '9')) && (Index < Max); Index++) { Str++; } if (Index == Max) { return (UINTN)-1; } return AsciiStrDecimalToUintn (Str); }