/** @file Main file for SerMode shell Debug1 function. (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "UefiShellDebug1CommandsLib.h" #include #include // // Name translation for the Parity Bit // STATIC CONST CHAR8 ParityBitName[] = { [DefaultParity] = 'D', [NoParity] = 'N', [EvenParity] = 'E', [OddParity] = 'O', [MarkParity] = 'M', [SpaceParity] = 'S', }; // // Name translation for the Stop Bits // STATIC CONST CHAR16 *StopBitsName[] = { [DefaultStopBits] = L"Default", [OneStopBit] = L"1", [OneFiveStopBits] = L"1.5", [TwoStopBits] = L"2", }; /** Display information about a serial device by it's handle. If HandleValid is FALSE, do all devices. @param[in] HandleIdx The handle index for the device. @param[in] HandleValid TRUE if HandleIdx is valid. @retval SHELL_INVALID_PARAMETER A parameter was invalid. @retval SHELL_SUCCESS The operation was successful. **/ SHELL_STATUS DisplaySettings ( IN UINTN HandleIdx, IN BOOLEAN HandleValid ) { EFI_SERIAL_IO_PROTOCOL *SerialIo; UINTN NoHandles; EFI_HANDLE *Handles; EFI_STATUS Status; UINTN Index; CONST CHAR16 *StopBits; CHAR16 Parity; SHELL_STATUS ShellStatus; Handles = NULL; ShellStatus = SHELL_SUCCESS; Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles); if (EFI_ERROR (Status)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); return SHELL_INVALID_PARAMETER; } for (Index = 0; Index < NoHandles; Index++) { if (HandleValid) { if (ConvertHandleIndexToHandle (HandleIdx) != Handles[Index]) { continue; } } Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID **)&SerialIo); if (EFI_ERROR (Status)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); ShellStatus = SHELL_NOT_FOUND; break; } if (SerialIo->Mode->Parity <= SpaceParity) { Parity = ParityBitName[SerialIo->Mode->Parity]; } else { Parity = 'U'; } if (SerialIo->Mode->StopBits <= TwoStopBits) { StopBits = StopBitsName[SerialIo->Mode->StopBits]; } else { StopBits = L"Unknown"; } ShellPrintHiiDefaultEx ( STRING_TOKEN (STR_SERMODE_DISPLAY), gShellDebug1HiiHandle, ConvertHandleToHandleIndex (Handles[Index]), Handles[Index], SerialIo->Mode->BaudRate, Parity, SerialIo->Mode->DataBits, StopBits ); if (HandleValid) { break; } } if (Index == NoHandles) { if (((NoHandles != 0) && HandleValid) || (0 == NoHandles)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_NOT_FOUND), gShellDebug1HiiHandle, L"sermode"); ShellStatus = SHELL_NOT_FOUND; } } return ShellStatus; } /** Get the Parity Type. @param[in] ParityChar Parity Type character. @param[out] ParityType If success, contains the converted Parity type. @retval SHELL_INVALID_PARAMETER A parameter was invalid. @retval SHELL_SUCCESS The operation was successful. **/ STATIC EFI_STATUS GetParityType ( IN CHAR16 ParityChar, OUT EFI_PARITY_TYPE *ParityType ) { EFI_STATUS Status; EFI_PARITY_TYPE Parity; ASSERT (ParityType != NULL); Status = EFI_SUCCESS; switch (ParityChar) { case 'd': case 'D': Parity = DefaultParity; break; case 'n': case 'N': Parity = NoParity; break; case 'e': case 'E': Parity = EvenParity; break; case 'o': case 'O': Parity = OddParity; break; case 'm': case 'M': Parity = MarkParity; break; case 's': case 'S': Parity = SpaceParity; break; default: Parity = DefaultParity; Status = EFI_INVALID_PARAMETER; break; } *ParityType = Parity; return Status; } /** Get the Stop Bits. @param[in] StopBitsInt Stop Bits integer. @param[out] StopBitsType If success, contains the converted StopBits type. @retval SHELL_INVALID_PARAMETER A parameter was invalid. @retval SHELL_SUCCESS The operation was successful. **/ STATIC EFI_STATUS GetStopBits ( IN UINTN StopBitsInt, OUT EFI_STOP_BITS_TYPE *StopBitsType ) { EFI_STATUS Status; EFI_STOP_BITS_TYPE StopBits; ASSERT (StopBitsType != NULL); Status = EFI_SUCCESS; switch (StopBitsInt) { case 0: StopBits = DefaultStopBits; break; case 1: StopBits = OneStopBit; break; case 2: StopBits = TwoStopBits; break; case 15: StopBits = OneFiveStopBits; break; default: StopBits = DefaultStopBits; Status = EFI_INVALID_PARAMETER; break; } *StopBitsType = StopBits; return Status; } /** Check whether the Data Bits are valid. @param[in] DataBitsInt Data Bits integer. @return TRUE if the Data Bits are valid. **/ STATIC BOOLEAN ValidDataBits ( IN UINTN DataBits ) { return (DataBits == 4) || (DataBits == 7) || (DataBits == 8); } /** Main function of the 'SerMode' command. @param[in] Package List of input parameter for the command. **/ STATIC SHELL_STATUS MainCmdSerMode ( LIST_ENTRY *Package ) { EFI_STATUS Status; SHELL_STATUS ShellStatus; UINTN Index; UINTN NoHandles; EFI_HANDLE *Handles; EFI_PARITY_TYPE Parity; EFI_STOP_BITS_TYPE StopBits; UINTN HandleIdx; UINTN BaudRate; UINTN DataBits; EFI_SERIAL_IO_PROTOCOL *SerialIo; CONST CHAR16 *Temp; UINT64 Intermediate; ShellStatus = SHELL_SUCCESS; HandleIdx = 0; Parity = DefaultParity; Handles = NULL; NoHandles = 0; Index = 0; if ((ShellCommandLineGetCount (Package) < 6) && (ShellCommandLineGetCount (Package) > 2)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"sermode"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount (Package) > 6) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"sermode"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Temp = ShellCommandLineGetRawValue (Package, 1); if (Temp != NULL) { Status = ShellConvertStringToUint64 (Temp, &Intermediate, TRUE, FALSE); HandleIdx = (UINTN)Intermediate; Temp = ShellCommandLineGetRawValue (Package, 2); if (Temp == NULL) { ShellStatus = DisplaySettings (HandleIdx, TRUE); goto Done; } } else { ShellStatus = DisplaySettings (0, FALSE); goto Done; } Temp = ShellCommandLineGetRawValue (Package, 2); if (Temp != NULL) { BaudRate = ShellStrToUintn (Temp); } else { ASSERT (FALSE); BaudRate = 0; } Temp = ShellCommandLineGetRawValue (Package, 3); if ((Temp == NULL) || (StrLen (Temp) > 1)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); ShellStatus = SHELL_INVALID_PARAMETER; } else { Status = GetParityType (Temp[0], &Parity); if (EFI_ERROR (Status)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } } Temp = ShellCommandLineGetRawValue (Package, 4); if (Temp != NULL) { DataBits = ShellStrToUintn (Temp); } else { // // make sure this is some number not in the list below. // DataBits = 0; } if (!ValidDataBits (DataBits)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } Temp = ShellCommandLineGetRawValue (Package, 5); if (Temp == NULL) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } Status = GetStopBits (ShellStrToUintn (Temp), &StopBits); if (EFI_ERROR (Status)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles); if (EFI_ERROR (Status)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); ShellStatus = SHELL_INVALID_PARAMETER; goto Done; } for (Index = 0; Index < NoHandles; Index++) { if (ConvertHandleIndexToHandle (HandleIdx) != Handles[Index]) { continue; } Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID **)&SerialIo); if (!EFI_ERROR (Status)) { Status = SerialIo->SetAttributes ( SerialIo, (UINT64)BaudRate, SerialIo->Mode->ReceiveFifoDepth, SerialIo->Mode->Timeout, Parity, (UINT8)DataBits, StopBits ); if (EFI_ERROR (Status)) { if (Status == EFI_INVALID_PARAMETER) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_SET_UNSUPPORTED), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex (Handles[Index])); ShellStatus = SHELL_UNSUPPORTED; } else if (Status == EFI_DEVICE_ERROR) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_SET_DEV_ERROR), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex (Handles[Index])); ShellStatus = SHELL_ACCESS_DENIED; } else { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_SET_FAIL), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex (Handles[Index])); ShellStatus = SHELL_ACCESS_DENIED; } } else { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_SET_HANDLE), gShellDebug1HiiHandle, ConvertHandleToHandleIndex (Handles[Index])); } break; } } } if ((ShellStatus == SHELL_SUCCESS) && (Index == NoHandles)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_SERMODE_BAD_HANDLE), gShellDebug1HiiHandle, L"sermode", HandleIdx); ShellStatus = SHELL_INVALID_PARAMETER; } Done: if (Handles != NULL) { FreePool (Handles); } return ShellStatus; } /** Function for 'sermode' 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 ShellCommandRunSerMode ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; SHELL_STATUS ShellStatus; LIST_ENTRY *Package; CHAR16 *ProblemParam; ShellStatus = SHELL_SUCCESS; Package = NULL; Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR (Status)) { if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { ShellPrintHiiDefaultEx (STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"sermode", ProblemParam); FreePool (ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT (FALSE); } return ShellStatus; } ShellStatus = MainCmdSerMode (Package); ShellCommandLineFreeVarList (Package); return ShellStatus; }