From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../Universal/EbcDxe/EbcDebugger/EdbSupportUI.c | 754 +++++++++++++++++++++ 1 file changed, 754 insertions(+) create mode 100644 roms/edk2/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c (limited to 'roms/edk2/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c') diff --git a/roms/edk2/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c b/roms/edk2/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c new file mode 100644 index 000000000..dd881a021 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c @@ -0,0 +1,754 @@ +/** @file + +Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "Edb.h" + +/** + Set the current coordinates of the cursor position. + + @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. + @param Column The position to set the cursor to. + @param Row The position to set the cursor to. + @param LineLength Length of a line. + @param TotalRow Total row of a screen. + @param Str Point to the string. + @param StrPos The position of the string. + @param Len The length of the string. + +**/ +VOID +EFIAPI +SetCursorPosition ( + IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut, + IN UINTN Column, + IN INTN Row, + IN UINTN LineLength, + IN UINTN TotalRow, + IN CHAR16 *Str, + IN UINTN StrPos, + IN UINTN Len + ); + +/** + + Function waits for a given event to fire, or for an optional timeout to expire. + + @param Event - The event to wait for + @param Timeout - An optional timeout value in 100 ns units. + + @retval EFI_SUCCESS - Event fired before Timeout expired. + @retval EFI_TIME_OUT - Timout expired before Event fired.. + +**/ +EFI_STATUS +EFIAPI +WaitForSingleEvent ( + IN EFI_EVENT Event, + IN UINT64 Timeout OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_EVENT TimerEvent; + EFI_EVENT WaitList[2]; + + if (Timeout != 0) { + // + // Create a timer event + // + Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent); + if (!EFI_ERROR (Status)) { + // + // Set the timer event + // + gBS->SetTimer ( + TimerEvent, + TimerRelative, + Timeout + ); + + // + // Wait for the original event or the timer + // + WaitList[0] = Event; + WaitList[1] = TimerEvent; + Status = gBS->WaitForEvent (2, WaitList, &Index); + gBS->CloseEvent (TimerEvent); + + // + // If the timer expired, change the return to timed out + // + if (!EFI_ERROR (Status) && Index == 1) { + Status = EFI_TIMEOUT; + } + } + } else { + // + // No timeout... just wait on the event + // + Status = gBS->WaitForEvent (1, &Event, &Index); + ASSERT (!EFI_ERROR (Status)); + ASSERT (Index == 0); + } + + return Status; +} + +/** + + Move the cursor position one character backward. + + @param LineLength Length of a line. Get it by calling QueryMode + @param Column Current column of the cursor position + @param Row Current row of the cursor position + +**/ +VOID +EFIAPI +ConMoveCursorBackward ( + IN UINTN LineLength, + IN OUT UINTN *Column, + IN OUT UINTN *Row + ) +{ + ASSERT (Column != NULL); + ASSERT (Row != NULL); + // + // If current column is 0, move to the last column of the previous line, + // otherwise, just decrement column. + // + if (*Column == 0) { + (*Column) = LineLength - 1; + // + // if (*Row > 0) { + // + (*Row)--; + // + // } + // + } else { + (*Column)--; + } +} + +/** + + Move the cursor position one character backward. + + @param LineLength Length of a line. Get it by calling QueryMode + @param TotalRow Total row of a screen, get by calling QueryMode + @param Column Current column of the cursor position + @param Row Current row of the cursor position + +**/ +VOID +EFIAPI +ConMoveCursorForward ( + IN UINTN LineLength, + IN UINTN TotalRow, + IN OUT UINTN *Column, + IN OUT UINTN *Row + ) +{ + ASSERT (Column != NULL); + ASSERT (Row != NULL); + // + // If current column is at line end, move to the first column of the nest + // line, otherwise, just increment column. + // + (*Column)++; + if (*Column >= LineLength) { + (*Column) = 0; + if ((*Row) < TotalRow - 1) { + (*Row)++; + } + } +} + +CHAR16 mBackupSpace[EFI_DEBUG_INPUS_BUFFER_SIZE]; +CHAR16 mInputBufferHistory[EFI_DEBUG_INPUS_BUFFER_SIZE]; + +/** + + Get user input. + + @param Prompt The prompt string. + @param InStr Point to the input string. + @param StrLength The max length of string user can input. + +**/ +VOID +EFIAPI +Input ( + IN CHAR16 *Prompt OPTIONAL, + OUT CHAR16 *InStr, + IN UINTN StrLength + ) +{ + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; + BOOLEAN Done; + UINTN Column; + UINTN Row; + UINTN StartColumn; + UINTN Update; + UINTN Delete; + UINTN Len; + UINTN StrPos; + UINTN Index; + UINTN LineLength; + UINTN TotalRow; + UINTN SkipLength; + UINTN OutputLength; + UINTN TailRow; + UINTN TailColumn; + EFI_INPUT_KEY Key; + BOOLEAN InsertMode; + BOOLEAN NeedAdjust; + UINTN SubIndex; + CHAR16 *CommandStr; + + ConOut = gST->ConOut; + ConIn = gST->ConIn; + + ASSERT (ConOut != NULL); + ASSERT (ConIn != NULL); + ASSERT (InStr != NULL); + + if (Prompt != NULL) { + ConOut->OutputString (ConOut, Prompt); + } + // + // Read a line from the console + // + Len = 0; + StrPos = 0; + OutputLength = 0; + Update = 0; + Delete = 0; + InsertMode = TRUE; + NeedAdjust = FALSE; + + // + // If buffer is not large enough to hold a CHAR16, do nothing. + // + if (StrLength < 1) { + return ; + } + // + // Get the screen setting and the current cursor location + // + StartColumn = ConOut->Mode->CursorColumn; + Column = StartColumn; + Row = ConOut->Mode->CursorRow; + ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &LineLength, &TotalRow); + if (LineLength == 0) { + return ; + } + + SetMem (InStr, StrLength * sizeof (CHAR16), 0); + Done = FALSE; + do { + // + // Read a key + // + WaitForSingleEvent (ConIn->WaitForKey, 0); + ConIn->ReadKeyStroke (ConIn, &Key); + + switch (Key.UnicodeChar) { + case CHAR_CARRIAGE_RETURN: + // + // All done, print a newline at the end of the string + // + TailRow = Row + (Len - StrPos + Column) / LineLength; + TailColumn = (Len - StrPos + Column) % LineLength; + Done = TRUE; + break; + + case CHAR_BACKSPACE: + if (StrPos != 0) { + // + // If not move back beyond string beginning, move all characters behind + // the current position one character forward + // + StrPos -= 1; + Update = StrPos; + Delete = 1; + CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos)); + + // + // Adjust the current column and row + // + ConMoveCursorBackward (LineLength, &Column, &Row); + + NeedAdjust = TRUE; + } + break; + + default: + if (Key.UnicodeChar >= ' ') { + // + // If we are at the buffer's end, drop the key + // + if (Len == StrLength - 1 && (InsertMode || StrPos == Len)) { + break; + } + // + // If in insert mode, move all characters behind the current position + // one character backward to make space for this character. Then store + // the character. + // + if (InsertMode) { + for (Index = Len; Index > StrPos; Index -= 1) { + InStr[Index] = InStr[Index - 1]; + } + } + + InStr[StrPos] = Key.UnicodeChar; + Update = StrPos; + + StrPos += 1; + OutputLength = 1; + } + break; + + case 0: + switch (Key.ScanCode) { + case SCAN_DELETE: + // + // Move characters behind current position one character forward + // + if (Len != 0) { + Update = StrPos; + Delete = 1; + CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos)); + + NeedAdjust = TRUE; + } + break; + + case SCAN_LEFT: + // + // Adjust current cursor position + // + if (StrPos != 0) { + StrPos -= 1; + ConMoveCursorBackward (LineLength, &Column, &Row); + } + break; + + case SCAN_RIGHT: + // + // Adjust current cursor position + // + if (StrPos < Len) { + StrPos += 1; + ConMoveCursorForward (LineLength, TotalRow, &Column, &Row); + } + break; + + case SCAN_HOME: + // + // Move current cursor position to the beginning of the command line + // + Row -= (StrPos + StartColumn) / LineLength; + Column = StartColumn; + StrPos = 0; + break; + + case SCAN_END: + // + // Move current cursor position to the end of the command line + // + TailRow = Row + (Len - StrPos + Column) / LineLength; + TailColumn = (Len - StrPos + Column) % LineLength; + Row = TailRow; + Column = TailColumn; + StrPos = Len; + break; + + case SCAN_ESC: + // + // Prepare to clear the current command line + // + InStr[0] = 0; + Update = 0; + Delete = Len; + Row -= (StrPos + StartColumn) / LineLength; + Column = StartColumn; + OutputLength = 0; + + NeedAdjust = TRUE; + break; + + case SCAN_INSERT: + // + // Toggle the SEnvInsertMode flag + // + InsertMode = (BOOLEAN)!InsertMode; + break; + + case SCAN_UP: + case SCAN_DOWN: + // + // show history + // + CopyMem (InStr, mInputBufferHistory, StrLength * sizeof(CHAR16)); + StrPos = StrLen (mInputBufferHistory); + Update = 0; + Delete = 0; + OutputLength = 0; + + TailRow = Row + (StrPos + StartColumn) / LineLength; + TailColumn = (StrPos + StartColumn) % LineLength; + Row = TailRow; + Column = TailColumn; + NeedAdjust = FALSE; + + ConOut->SetCursorPosition (ConOut, StartColumn, Row); + for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) { + mBackupSpace[SubIndex] = L' '; + } + EDBPrint (mBackupSpace); + SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0); + + ConOut->SetCursorPosition (ConOut, StartColumn, Row); + Len = StrPos; + + break; + + case SCAN_F1: + case SCAN_F2: + case SCAN_F3: + case SCAN_F4: + case SCAN_F5: + case SCAN_F6: + case SCAN_F7: + case SCAN_F8: + case SCAN_F9: + case SCAN_F10: + case SCAN_F11: + case SCAN_F12: + CommandStr = GetCommandNameByKey (Key); + if (CommandStr != NULL) { + StrnCpyS (InStr, StrLength, CommandStr, StrLength - 1); + return ; + } + break; + } + } + + if (Done) { + break; + } + // + // If we need to update the output do so now + // + if (Update != -1) { + if (NeedAdjust) { + ConOut->SetCursorPosition (ConOut, Column, Row); + for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) { + mBackupSpace[SubIndex] = L' '; + } + EDBPrint (mBackupSpace); + SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0); + ConOut->SetCursorPosition (ConOut, Column, Row); + NeedAdjust = FALSE; + } + EDBPrint (InStr + Update); + Len = StrLen (InStr); + + if (Delete != 0) { + SetMem (InStr + Len, Delete * sizeof (CHAR16), 0x00); + } + + if (StrPos > Len) { + StrPos = Len; + } + + Update = (UINTN) -1; + + // + // After using print to reflect newly updates, if we're not using + // BACKSPACE and DELETE, we need to move the cursor position forward, + // so adjust row and column here. + // + if (Key.UnicodeChar != CHAR_BACKSPACE && !(Key.UnicodeChar == 0 && Key.ScanCode == SCAN_DELETE)) { + // + // Calulate row and column of the tail of current string + // + TailRow = Row + (Len - StrPos + Column + OutputLength) / LineLength; + TailColumn = (Len - StrPos + Column + OutputLength) % LineLength; + + // + // If the tail of string reaches screen end, screen rolls up, so if + // Row does not equal TailRow, Row should be decremented + // + // (if we are recalling commands using UPPER and DOWN key, and if the + // old command is too long to fit the screen, TailColumn must be 79. + // + if (TailColumn == 0 && TailRow >= TotalRow && (UINTN) Row != TailRow) { + Row--; + } + // + // Calculate the cursor position after current operation. If cursor + // reaches line end, update both row and column, otherwise, only + // column will be changed. + // + if (Column + OutputLength >= LineLength) { + SkipLength = OutputLength - (LineLength - Column); + + Row += SkipLength / LineLength + 1; + if ((UINTN) Row > TotalRow - 1) { + Row = TotalRow - 1; + } + + Column = SkipLength % LineLength; + } else { + Column += OutputLength; + } + } + + Delete = 0; + } + // + // Set the cursor position for this key + // + SetCursorPosition (ConOut, Column, Row, LineLength, TotalRow, InStr, StrPos, Len); + } while (!Done); + + CopyMem (mInputBufferHistory, InStr, StrLength * sizeof(CHAR16)); + + // + // Return the data to the caller + // + return ; +} + +/** + Set the current coordinates of the cursor position. + + @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL. + @param Column The position to set the cursor to. + @param Row The position to set the cursor to. + @param LineLength Length of a line. + @param TotalRow Total row of a screen. + @param Str Point to the string. + @param StrPos The position of the string. + @param Len The length of the string. + +**/ +VOID +EFIAPI +SetCursorPosition ( + IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut, + IN UINTN Column, + IN INTN Row, + IN UINTN LineLength, + IN UINTN TotalRow, + IN CHAR16 *Str, + IN UINTN StrPos, + IN UINTN Len + ) +{ + CHAR16 Backup; + + ASSERT (ConOut != NULL); + ASSERT (Str != NULL); + + Backup = 0; + if (Row >= 0) { + ConOut->SetCursorPosition (ConOut, Column, Row); + return ; + } + + if (Len - StrPos > Column * Row) { + Backup = *(Str + StrPos + Column * Row); + *(Str + StrPos + Column * Row) = 0; + } + + EDBPrint (L"%s", Str + StrPos); + if (Len - StrPos > Column * Row) { + *(Str + StrPos + Column * Row) = Backup; + } + + ConOut->SetCursorPosition (ConOut, 0, 0); +} + +/** + + SetPageBreak. + +**/ +BOOLEAN +EFIAPI +SetPageBreak ( + VOID + ) +{ + EFI_INPUT_KEY Key; + CHAR16 Str[3]; + BOOLEAN OmitPrint; + + // + // Check + // + if (!mDebuggerPrivate.EnablePageBreak) { + return FALSE; + } + + gST->ConOut->OutputString (gST->ConOut, L"Press ENTER to continue, 'q' to exit:"); + + OmitPrint = FALSE; + // + // Wait for user input + // + Str[0] = ' '; + Str[1] = 0; + Str[2] = 0; + for (;;) { + WaitForSingleEvent (gST->ConIn->WaitForKey, 0); + gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + + // + // handle control keys + // + if (Key.UnicodeChar == CHAR_NULL) { + if (Key.ScanCode == SCAN_ESC) { + gST->ConOut->OutputString (gST->ConOut, L"\r\n"); + OmitPrint = TRUE; + break; + } + + continue; + } + + if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + gST->ConOut->OutputString (gST->ConOut, L"\r\n"); + break; + } + // + // Echo input + // + Str[1] = Key.UnicodeChar; + if (Str[1] == CHAR_BACKSPACE) { + continue; + } + + gST->ConOut->OutputString (gST->ConOut, Str); + + if ((Str[1] == L'q') || (Str[1] == L'Q')) { + OmitPrint = TRUE; + } else { + OmitPrint = FALSE; + } + + Str[0] = CHAR_BACKSPACE; + } + + return OmitPrint; +} + +/** + Print a Unicode string to the output device. + + @param Format A Null-terminated Unicode format string. + @param ... The variable argument list that contains pointers to Null- + terminated Unicode strings to be printed + +**/ +UINTN +EFIAPI +EDBPrint ( + IN CONST CHAR16 *Format, + ... + ) +{ + UINTN Return; + VA_LIST Marker; + CHAR16 Buffer[EFI_DEBUG_MAX_PRINT_BUFFER]; + + VA_START (Marker, Format); + Return = UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker); + VA_END (Marker); + + if (gST->ConOut != NULL) { + // + // To be extra safe make sure ConOut has been initialized + // + gST->ConOut->OutputString (gST->ConOut, Buffer); + } + + return Return; +} + +/** + Print a Unicode string to the output buffer. + + @param Buffer A pointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param Format A Null-terminated Unicode format string. + @param ... The variable argument list that contains pointers to Null- + terminated Unicode strings to be printed + +**/ +UINTN +EFIAPI +EDBSPrint ( + OUT CHAR16 *Buffer, + IN INTN BufferSize, + IN CONST CHAR16 *Format, + ... + ) +{ + UINTN Return; + VA_LIST Marker; + + ASSERT (BufferSize > 0); + + VA_START (Marker, Format); + Return = UnicodeVSPrint (Buffer, (UINTN)BufferSize, Format, Marker); + VA_END (Marker); + + return Return; +} + +/** + Print a Unicode string to the output buffer with specified offset.. + + @param Buffer A pointer to the output buffer for the produced Null-terminated + Unicode string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param Offset The offset of the buffer. + @param Format A Null-terminated Unicode format string. + @param ... The variable argument list that contains pointers to Null- + terminated Unicode strings to be printed + +**/ +UINTN +EFIAPI +EDBSPrintWithOffset ( + OUT CHAR16 *Buffer, + IN INTN BufferSize, + IN UINTN Offset, + IN CONST CHAR16 *Format, + ... + ) +{ + UINTN Return; + VA_LIST Marker; + + ASSERT (BufferSize - (Offset * sizeof(CHAR16)) > 0); + + VA_START (Marker, Format); + Return = UnicodeVSPrint (Buffer + Offset, (UINTN)(BufferSize - (Offset * sizeof(CHAR16))), Format, Marker); + VA_END (Marker); + + return Return; +} -- cgit