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