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