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