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