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