1/** @file 2 Main file for SerMode shell Debug1 function. 3 4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> 5 Copyright (c) 2005 - 2011, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14**/ 15 16#include "UefiShellDebug1CommandsLib.h" 17#include <Library/ShellLib.h> 18#include <Protocol/SerialIo.h> 19 20/** 21 Display information about a serial device by it's handle. 22 23 If HandleValid is FALSE, do all devices. 24 25 @param[in] HandleIdx The handle index for the device. 26 @param[in] HandleValid TRUE if HandleIdx is valid. 27 28 @retval SHELL_INVALID_PARAMETER A parameter was invalid. 29 @retval SHELL_SUCCESS The operation was successful. 30**/ 31SHELL_STATUS 32DisplaySettings ( 33 IN UINTN HandleIdx, 34 IN BOOLEAN HandleValid 35 ) 36{ 37 EFI_SERIAL_IO_PROTOCOL *SerialIo; 38 UINTN NoHandles; 39 EFI_HANDLE *Handles; 40 EFI_STATUS Status; 41 UINTN Index; 42 CHAR16 *StopBits; 43 CHAR16 Parity; 44 SHELL_STATUS ShellStatus; 45 46 Handles = NULL; 47 StopBits = NULL; 48 49 ShellStatus = SHELL_SUCCESS; 50 51 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles); 52 if (EFI_ERROR (Status)) { 53 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); 54 return SHELL_INVALID_PARAMETER; 55 } 56 57 for (Index = 0; Index < NoHandles; Index++) { 58 if (HandleValid) { 59 if (ConvertHandleIndexToHandle(HandleIdx) != Handles[Index]) { 60 continue; 61 } 62 } 63 64 Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID**)&SerialIo); 65 if (!EFI_ERROR (Status)) { 66 switch (SerialIo->Mode->Parity) { 67 case DefaultParity: 68 69 Parity = 'D'; 70 break; 71 72 case NoParity: 73 74 Parity = 'N'; 75 break; 76 77 case EvenParity: 78 79 Parity = 'E'; 80 break; 81 82 case OddParity: 83 84 Parity = 'O'; 85 break; 86 87 case MarkParity: 88 89 Parity = 'M'; 90 break; 91 92 case SpaceParity: 93 94 Parity = 'S'; 95 break; 96 97 default: 98 99 Parity = 'U'; 100 } 101 102 switch (SerialIo->Mode->StopBits) { 103 case DefaultStopBits: 104 105 StopBits = L"Default"; 106 break; 107 108 case OneStopBit: 109 110 StopBits = L"1"; 111 break; 112 113 case TwoStopBits: 114 115 StopBits = L"2"; 116 break; 117 118 case OneFiveStopBits: 119 120 StopBits = L"1.5"; 121 break; 122 123 default: 124 125 StopBits = L"Unknown"; 126 } 127 ShellPrintHiiEx( 128 -1, 129 -1, 130 NULL, 131 STRING_TOKEN (STR_SERMODE_DISPLAY), 132 gShellDebug1HiiHandle, 133 ConvertHandleToHandleIndex (Handles[Index]), 134 Handles[Index], 135 SerialIo->Mode->BaudRate, 136 Parity, 137 SerialIo->Mode->DataBits, 138 StopBits 139 ); 140 } else { 141 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); 142 ShellStatus = SHELL_NOT_FOUND; 143 break; 144 } 145 146 if (HandleValid) { 147 break; 148 } 149 } 150 151 if (Index == NoHandles) { 152 if ((NoHandles != 0 && HandleValid) || 0 == NoHandles) { 153 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NOT_FOUND), gShellDebug1HiiHandle, L"sermode"); 154 ShellStatus = SHELL_NOT_FOUND; 155 } 156 } 157 158 return ShellStatus; 159} 160 161/** 162 Function for 'sermode' command. 163 164 @param[in] ImageHandle Handle to the Image (NULL if Internal). 165 @param[in] SystemTable Pointer to the System Table (NULL if Internal). 166**/ 167SHELL_STATUS 168EFIAPI 169ShellCommandRunSerMode ( 170 IN EFI_HANDLE ImageHandle, 171 IN EFI_SYSTEM_TABLE *SystemTable 172 ) 173{ 174 EFI_STATUS Status; 175 SHELL_STATUS ShellStatus; 176 UINTN Index; 177 UINTN NoHandles; 178 EFI_HANDLE *Handles; 179 EFI_PARITY_TYPE Parity; 180 EFI_STOP_BITS_TYPE StopBits; 181 UINTN HandleIdx; 182 UINTN BaudRate; 183 UINTN DataBits; 184 UINTN Value; 185 EFI_SERIAL_IO_PROTOCOL *SerialIo; 186 LIST_ENTRY *Package; 187 CHAR16 *ProblemParam; 188 CONST CHAR16 *Temp; 189 UINT64 Intermediate; 190 191 ShellStatus = SHELL_SUCCESS; 192 HandleIdx = 0; 193 Parity = DefaultParity; 194 Handles = NULL; 195 NoHandles = 0; 196 Index = 0; 197 Package = NULL; 198 199 Status = ShellCommandLineParse (EmptyParamList, &Package, &ProblemParam, TRUE); 200 if (EFI_ERROR(Status)) { 201 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { 202 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"sermode", ProblemParam); 203 FreePool(ProblemParam); 204 ShellStatus = SHELL_INVALID_PARAMETER; 205 } else { 206 ASSERT(FALSE); 207 } 208 } else { 209 if (ShellCommandLineGetCount(Package) < 6 && ShellCommandLineGetCount(Package) > 2) { 210 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"sermode"); 211 ShellStatus = SHELL_INVALID_PARAMETER; 212 } else if (ShellCommandLineGetCount(Package) > 6) { 213 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"sermode"); 214 ShellStatus = SHELL_INVALID_PARAMETER; 215 } else { 216 Temp = ShellCommandLineGetRawValue(Package, 1); 217 if (Temp != NULL) { 218 Status = ShellConvertStringToUint64(Temp, &Intermediate, TRUE, FALSE); 219 HandleIdx = (UINTN)Intermediate; 220 Temp = ShellCommandLineGetRawValue(Package, 2); 221 if (Temp == NULL) { 222 ShellStatus = DisplaySettings (HandleIdx, TRUE); 223 goto Done; 224 } 225 } else { 226 ShellStatus = DisplaySettings (0, FALSE); 227 goto Done; 228 } 229 Temp = ShellCommandLineGetRawValue(Package, 2); 230 if (Temp != NULL) { 231 BaudRate = ShellStrToUintn(Temp); 232 } else { 233 ASSERT(FALSE); 234 BaudRate = 0; 235 } 236 Temp = ShellCommandLineGetRawValue(Package, 3); 237 if (Temp == NULL || StrLen(Temp)>1) { 238 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); 239 ShellStatus = SHELL_INVALID_PARAMETER; 240 } else { 241 switch(Temp[0]){ 242 case 'd': 243 case 'D': 244 Parity = DefaultParity; 245 break; 246 case 'n': 247 case 'N': 248 Parity = NoParity; 249 break; 250 case 'e': 251 case 'E': 252 Parity = EvenParity; 253 break; 254 case 'o': 255 case 'O': 256 Parity = OddParity; 257 break; 258 case 'm': 259 case 'M': 260 Parity = MarkParity; 261 break; 262 case 's': 263 case 'S': 264 Parity = SpaceParity; 265 break; 266 default: 267 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); 268 ShellStatus = SHELL_INVALID_PARAMETER; 269 goto Done; 270 } 271 } 272 Temp = ShellCommandLineGetRawValue(Package, 4); 273 if (Temp != NULL) { 274 DataBits = ShellStrToUintn(Temp); 275 } else { 276 // 277 // make sure this is some number not in the list below. 278 // 279 DataBits = 0; 280 } 281 switch (DataBits) { 282 case 4: 283 case 7: 284 case 8: 285 break; 286 default: 287 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); 288 ShellStatus = SHELL_INVALID_PARAMETER; 289 goto Done; 290 } 291 Temp = ShellCommandLineGetRawValue(Package, 5); 292 Value = ShellStrToUintn(Temp); 293 switch (Value) { 294 case 0: 295 StopBits = DefaultStopBits; 296 break; 297 298 case 1: 299 StopBits = OneStopBit; 300 break; 301 302 case 2: 303 StopBits = TwoStopBits; 304 break; 305 306 case 15: 307 StopBits = OneFiveStopBits; 308 break; 309 310 default: 311 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"sermode", Temp); 312 ShellStatus = SHELL_INVALID_PARAMETER; 313 goto Done; 314 } 315 Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles); 316 if (EFI_ERROR (Status)) { 317 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_NO_FOUND), gShellDebug1HiiHandle, L"sermode"); 318 ShellStatus = SHELL_INVALID_PARAMETER; 319 goto Done; 320 } 321 322 for (Index = 0; Index < NoHandles; Index++) { 323 if (ConvertHandleIndexToHandle (HandleIdx) != Handles[Index]) { 324 continue; 325 } 326 327 Status = gBS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, (VOID**)&SerialIo); 328 if (!EFI_ERROR (Status)) { 329 Status = SerialIo->SetAttributes ( 330 SerialIo, 331 (UINT64) BaudRate, 332 SerialIo->Mode->ReceiveFifoDepth, 333 SerialIo->Mode->Timeout, 334 Parity, 335 (UINT8) DataBits, 336 StopBits 337 ); 338 if (EFI_ERROR (Status)) { 339 if (Status == EFI_INVALID_PARAMETER) { 340 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_UNSUPPORTED), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index])); 341 ShellStatus = SHELL_UNSUPPORTED; 342 } else if (Status == EFI_DEVICE_ERROR) { 343 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_DEV_ERROR), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index])); 344 ShellStatus = SHELL_ACCESS_DENIED; 345 } else { 346 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_FAIL), gShellDebug1HiiHandle, L"sermode", ConvertHandleToHandleIndex(Handles[Index])); 347 ShellStatus = SHELL_ACCESS_DENIED; 348 } 349 } else { 350 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_SET_HANDLE), gShellDebug1HiiHandle, ConvertHandleToHandleIndex(Handles[Index])); 351 } 352 break; 353 } 354 } 355 } 356 } 357 358 if (ShellStatus == SHELL_SUCCESS && Index == NoHandles) { 359 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SERMODE_BAD_HANDLE), gShellDebug1HiiHandle, L"sermode", HandleIdx); 360 ShellStatus = SHELL_INVALID_PARAMETER; 361 } 362 363Done: 364 if (Package != NULL) { 365 ShellCommandLineFreeVarList (Package); 366 } 367 if (Handles != NULL) { 368 FreePool (Handles); 369 } 370 return ShellStatus; 371} 372