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