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