]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/GenericBdsLib/BdsConsole.c
Clean up GenericBdsLib library Instance.
[mirror_edk2.git] / MdeModulePkg / Library / GenericBdsLib / BdsConsole.c
CommitLineData
897f0eee 1/** @file\r
2 BDS Lib functions which contain all the code to connect console device\r
3\r
4Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "InternalBdsLib.h"\r
16\r
11ef23f9 17/**\r
18 Check if we need to save the EFI variable with "ConVarName" as name\r
19 as NV type\r
20\r
21 @param ConVarName The name of the EFI variable.\r
22\r
23 @retval TRUE Set the EFI variabel as NV type.\r
24 @retval FALSE EFI variabel as NV type can be set NonNV.\r
25**/\r
897f0eee 26BOOLEAN\r
27IsNvNeed (\r
28 IN CHAR16 *ConVarName\r
29 )\r
30{\r
31 CHAR16 *Ptr;\r
32\r
33 Ptr = ConVarName;\r
34\r
35 //\r
36 // If the variable includes "Dev" at last, we consider\r
37 // it does not support NV attribute.\r
38 //\r
11ef23f9 39 while (*Ptr != L'\0') {\r
897f0eee 40 Ptr++;\r
41 }\r
42\r
43 if ((*(Ptr-3) == 'D') && (*(Ptr-2) == 'e') && (*(Ptr-1) == 'v')) {\r
44 return FALSE;\r
45 } else {\r
46 return TRUE;\r
47 }\r
48}\r
49\r
50\r
51/**\r
52 This function update console variable based on ConVarName, it can\r
53 add or remove one specific console device path from the variable\r
54\r
55 @param ConVarName Console related variable name, ConIn, ConOut,\r
56 ErrOut.\r
57 @param CustomizedConDevicePath The console device path which will be added to\r
58 the console variable ConVarName, this parameter\r
59 can not be multi-instance.\r
60 @param ExclusiveDevicePath The console device path which will be removed\r
61 from the console variable ConVarName, this\r
62 parameter can not be multi-instance.\r
63\r
64 @retval EFI_UNSUPPORTED Add or remove the same device path.\r
65 @retval EFI_SUCCESS Success add or remove the device path from the\r
66 console variable.\r
67\r
68**/\r
69EFI_STATUS\r
70EFIAPI\r
71BdsLibUpdateConsoleVariable (\r
72 IN CHAR16 *ConVarName,\r
73 IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,\r
74 IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath\r
75 )\r
76{\r
77 EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
78 UINTN DevicePathSize;\r
79 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
80 EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
81 UINT32 Attributes;\r
82\r
83 VarConsole = NULL;\r
84 DevicePathSize = 0;\r
85\r
86 //\r
87 // Notes: check the device path point, here should check\r
88 // with compare memory\r
89 //\r
90 if (CustomizedConDevicePath == ExclusiveDevicePath) {\r
91 return EFI_UNSUPPORTED;\r
92 }\r
93 //\r
94 // Delete the ExclusiveDevicePath from current default console\r
95 //\r
96 VarConsole = BdsLibGetVariableAndSize (\r
97 ConVarName,\r
98 &gEfiGlobalVariableGuid,\r
99 &DevicePathSize\r
100 );\r
101\r
102 //\r
103 // Initialize NewDevicePath\r
104 //\r
105 NewDevicePath = VarConsole;\r
106\r
107 //\r
108 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.\r
109 // In the end, NewDevicePath is the final device path.\r
110 //\r
111 if (ExclusiveDevicePath != NULL && VarConsole != NULL) {\r
112 NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
113 }\r
114 //\r
115 // Try to append customized device path to NewDevicePath.\r
116 //\r
117 if (CustomizedConDevicePath != NULL) {\r
118 if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
119 //\r
120 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
121 //\r
122 NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);\r
123 //\r
124 // In the first check, the default console variable will be _ModuleEntryPoint,\r
125 // just append current customized device path\r
126 //\r
127 TempNewDevicePath = NewDevicePath;\r
128 NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);\r
129 SafeFreePool(TempNewDevicePath);\r
130 }\r
131 }\r
132\r
133 //\r
134 // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.\r
135 //\r
136 if (IsNvNeed(ConVarName)) {\r
137 //\r
138 // ConVarName has NV attribute.\r
139 //\r
140 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
141 } else {\r
142 //\r
143 // ConVarName does not have NV attribute.\r
144 //\r
145 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
146 }\r
147\r
148 //\r
149 // Finally, Update the variable of the default console by NewDevicePath\r
150 //\r
151 gRT->SetVariable (\r
152 ConVarName,\r
153 &gEfiGlobalVariableGuid,\r
154 Attributes,\r
155 GetDevicePathSize (NewDevicePath),\r
156 NewDevicePath\r
157 );\r
158\r
159 if (VarConsole == NewDevicePath) {\r
160 SafeFreePool(VarConsole);\r
161 } else {\r
162 SafeFreePool(VarConsole);\r
163 SafeFreePool(NewDevicePath);\r
164 }\r
165\r
166 return EFI_SUCCESS;\r
167\r
168}\r
169\r
170\r
171/**\r
172 Connect the console device base on the variable ConVarName, if\r
173 device path of the ConVarName is multi-instance device path, if\r
174 anyone of the instances is connected success, then this function\r
175 will return success.\r
176\r
177 @param ConVarName Console related variable name, ConIn, ConOut,\r
178 ErrOut.\r
179\r
180 @retval EFI_NOT_FOUND There is not any console devices connected\r
181 success\r
182 @retval EFI_SUCCESS Success connect any one instance of the console\r
183 device path base on the variable ConVarName.\r
184\r
185**/\r
186EFI_STATUS\r
187EFIAPI\r
188BdsLibConnectConsoleVariable (\r
189 IN CHAR16 *ConVarName\r
190 )\r
191{\r
192 EFI_STATUS Status;\r
193 EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;\r
194 UINTN VariableSize;\r
195 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
196 EFI_DEVICE_PATH_PROTOCOL *Next;\r
197 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;\r
198 UINTN Size;\r
199 BOOLEAN DeviceExist;\r
200\r
201 Status = EFI_SUCCESS;\r
202 DeviceExist = FALSE;\r
203\r
204 //\r
205 // Check if the console variable exist\r
206 //\r
207 StartDevicePath = BdsLibGetVariableAndSize (\r
208 ConVarName,\r
209 &gEfiGlobalVariableGuid,\r
210 &VariableSize\r
211 );\r
212 if (StartDevicePath == NULL) {\r
213 return EFI_UNSUPPORTED;\r
214 }\r
215\r
216 CopyOfDevicePath = StartDevicePath;\r
217 do {\r
218 //\r
219 // Check every instance of the console variable\r
220 //\r
221 Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);\r
222 Next = Instance;\r
223 while (!IsDevicePathEndType (Next)) {\r
224 Next = NextDevicePathNode (Next);\r
225 }\r
226\r
227 SetDevicePathEndNode (Next);\r
228 //\r
229 // Check USB1.1 console\r
230 //\r
231 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&\r
232 ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)\r
233 || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)\r
234 )) {\r
235 //\r
236 // Check the Usb console in Usb2.0 bus firstly, then Usb1.1 bus\r
237 //\r
238 Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_EHCI, Instance);\r
239 if (!EFI_ERROR (Status)) {\r
240 DeviceExist = TRUE;\r
241 }\r
242\r
243 Status = BdsLibConnectUsbDevByShortFormDP (PCI_CLASSC_PI_UHCI, Instance);\r
244 if (!EFI_ERROR (Status)) {\r
245 DeviceExist = TRUE;\r
246 }\r
247 } else {\r
248 //\r
249 // Connect the instance device path\r
250 //\r
251 Status = BdsLibConnectDevicePath (Instance);\r
252 if (EFI_ERROR (Status)) {\r
253 //\r
254 // Delete the instance from the console varialbe\r
255 //\r
256 BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);\r
257 } else {\r
258 DeviceExist = TRUE;\r
259 }\r
260 }\r
261 SafeFreePool(Instance);\r
262 } while (CopyOfDevicePath != NULL);\r
263\r
264 gBS->FreePool (StartDevicePath);\r
265\r
7471b8cd 266 if (!DeviceExist) {\r
897f0eee 267 return EFI_NOT_FOUND;\r
268 }\r
269\r
270 return EFI_SUCCESS;\r
271}\r
272\r
273\r
274/**\r
275 This function will search every simpletxt devive in current system,\r
276 and make every simpletxt device as pertantial console device.\r
277\r
278**/\r
279VOID\r
280EFIAPI\r
281BdsLibConnectAllConsoles (\r
282 VOID\r
283 )\r
284{\r
285 UINTN Index;\r
286 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
287 UINTN HandleCount;\r
288 EFI_HANDLE *HandleBuffer;\r
289\r
290 Index = 0;\r
291 HandleCount = 0;\r
292 HandleBuffer = NULL;\r
293 ConDevicePath = NULL;\r
294\r
295 //\r
296 // Update all the console varables\r
297 //\r
298 gBS->LocateHandleBuffer (\r
299 ByProtocol,\r
300 &gEfiSimpleTextInProtocolGuid,\r
301 NULL,\r
302 &HandleCount,\r
303 &HandleBuffer\r
304 );\r
305 \r
306 for (Index = 0; Index < HandleCount; Index++) {\r
307 gBS->HandleProtocol (\r
308 HandleBuffer[Index],\r
309 &gEfiDevicePathProtocolGuid,\r
310 (VOID **) &ConDevicePath\r
311 );\r
312 BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);\r
313 }\r
314\r
315 SafeFreePool(HandleBuffer);\r
316\r
317 gBS->LocateHandleBuffer (\r
318 ByProtocol,\r
319 &gEfiSimpleTextOutProtocolGuid,\r
320 NULL,\r
321 &HandleCount,\r
322 &HandleBuffer\r
323 );\r
324 for (Index = 0; Index < HandleCount; Index++) {\r
325 gBS->HandleProtocol (\r
326 HandleBuffer[Index],\r
327 &gEfiDevicePathProtocolGuid,\r
328 (VOID **) &ConDevicePath\r
329 );\r
330 BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);\r
331 BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);\r
332 }\r
333\r
334 SafeFreePool(HandleBuffer);\r
335\r
336 //\r
337 // Connect all console variables\r
338 //\r
339 BdsLibConnectAllDefaultConsoles ();\r
340\r
341}\r
342\r
343\r
344/**\r
345 This function will connect console device base on the console\r
346 device variable ConIn, ConOut and ErrOut.\r
347\r
348 @retval EFI_SUCCESS At least one of the ConIn and ConOut device have\r
349 been connected success.\r
350 @retval EFI_STATUS Return the status of\r
351 BdsLibConnectConsoleVariable ().\r
352\r
353**/\r
354EFI_STATUS\r
355EFIAPI\r
356BdsLibConnectAllDefaultConsoles (\r
357 VOID\r
358 )\r
359{\r
360 EFI_STATUS Status;\r
361\r
362 //\r
363 // Connect all default console variables\r
364 //\r
365\r
366 //\r
367 // It seems impossible not to have any ConOut device on platform,\r
368 // so we check the status here.\r
369 //\r
370 Status = BdsLibConnectConsoleVariable (L"ConOut");\r
371 if (EFI_ERROR (Status)) {\r
372 return Status;\r
373 }\r
374\r
375 //\r
376 // Insert the performance probe for Console Out\r
377 //\r
378 PERF_START (NULL, "ConOut", "BDS", 1);\r
379 PERF_END (NULL, "ConOut", "BDS", 0);\r
380\r
381 //\r
382 // Because possibly the platform is legacy free, in such case,\r
383 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,\r
384 // so we need not check the status.\r
385 //\r
386 BdsLibConnectConsoleVariable (L"ConIn");\r
387\r
388 //\r
389 // The _ModuleEntryPoint err out var is legal.\r
390 //\r
391 BdsLibConnectConsoleVariable (L"ErrOut");\r
392\r
393 return EFI_SUCCESS;\r
394\r
395}\r