1 | /** @file
|
---|
2 | This file also installs UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
|
---|
3 |
|
---|
4 | The main code offers a UI interface in device manager to let user configure
|
---|
5 | platform override protocol to override the default algorithm for matching
|
---|
6 | drivers to controllers.
|
---|
7 |
|
---|
8 | The main flow:
|
---|
9 | 1. It dynamicly locate all controller device path.
|
---|
10 | 2. It dynamicly locate all drivers which support binding protocol.
|
---|
11 | 3. It export and dynamicly update two menu to let user select the
|
---|
12 | mapping between drivers to controllers.
|
---|
13 | 4. It save all the mapping info in NV variables which will be consumed
|
---|
14 | by platform override protocol driver to publish the platform override protocol.
|
---|
15 |
|
---|
16 | Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
|
---|
17 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
18 |
|
---|
19 | **/
|
---|
20 |
|
---|
21 | #include "InternalPlatDriOverrideDxe.h"
|
---|
22 | #include "PlatOverMngr.h"
|
---|
23 |
|
---|
24 | #define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
|
---|
25 | #define EFI_CALLBACK_INFO_FROM_THIS(a) CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)
|
---|
26 |
|
---|
27 | typedef struct {
|
---|
28 | UINTN Signature;
|
---|
29 | EFI_HANDLE DriverHandle;
|
---|
30 | EFI_HII_HANDLE RegisteredHandle;
|
---|
31 | PLAT_OVER_MNGR_DATA FakeNvData;
|
---|
32 | EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
---|
33 | EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
|
---|
34 | EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL PlatformDriverOverride;
|
---|
35 | } EFI_CALLBACK_INFO;
|
---|
36 |
|
---|
37 | #pragma pack(1)
|
---|
38 |
|
---|
39 | ///
|
---|
40 | /// HII specific Vendor Device Path definition.
|
---|
41 | ///
|
---|
42 | typedef struct {
|
---|
43 | VENDOR_DEVICE_PATH VendorDevicePath;
|
---|
44 | EFI_DEVICE_PATH_PROTOCOL End;
|
---|
45 | } HII_VENDOR_DEVICE_PATH;
|
---|
46 |
|
---|
47 | #pragma pack()
|
---|
48 |
|
---|
49 | //
|
---|
50 | // uni string and Vfr Binary data.
|
---|
51 | //
|
---|
52 | extern UINT8 VfrBin[];
|
---|
53 | extern UINT8 PlatDriOverrideDxeStrings[];
|
---|
54 |
|
---|
55 | //
|
---|
56 | // module global data
|
---|
57 | //
|
---|
58 | CHAR16 mVariableName[] = L"Data";
|
---|
59 | LIST_ENTRY mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);
|
---|
60 | BOOLEAN mEnvironmentVariableRead = FALSE;
|
---|
61 | EFI_HANDLE mCallerImageHandle = NULL;
|
---|
62 |
|
---|
63 | EFI_HANDLE *mDevicePathHandleBuffer;
|
---|
64 | EFI_HANDLE *mDriverImageHandleBuffer;
|
---|
65 |
|
---|
66 | INTN mSelectedCtrIndex;
|
---|
67 | EFI_STRING_ID *mControllerToken;
|
---|
68 | UINTN mDriverImageHandleCount;
|
---|
69 | EFI_STRING_ID *mDriverImageToken;
|
---|
70 | EFI_DEVICE_PATH_PROTOCOL **mControllerDevicePathProtocol;
|
---|
71 | UINTN mSelectedDriverImageNum;
|
---|
72 | UINTN mLastSavedDriverImageNum;
|
---|
73 | UINT16 mCurrentPage;
|
---|
74 | EFI_CALLBACK_INFO *mCallbackInfo;
|
---|
75 | BOOLEAN *mDriSelection;
|
---|
76 | UINTN mMaxDeviceCount;
|
---|
77 |
|
---|
78 | HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
|
---|
79 | {
|
---|
80 | {
|
---|
81 | HARDWARE_DEVICE_PATH,
|
---|
82 | HW_VENDOR_DP,
|
---|
83 | {
|
---|
84 | (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
|
---|
85 | (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
|
---|
86 | }
|
---|
87 | },
|
---|
88 | PLAT_OVER_MNGR_GUID
|
---|
89 | },
|
---|
90 | {
|
---|
91 | END_DEVICE_PATH_TYPE,
|
---|
92 | END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
---|
93 | {
|
---|
94 | (UINT8)(END_DEVICE_PATH_LENGTH),
|
---|
95 | (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
|
---|
96 | }
|
---|
97 | }
|
---|
98 | };
|
---|
99 |
|
---|
100 | /**
|
---|
101 | Converting a given device to an unicode string.
|
---|
102 |
|
---|
103 | @param DevPath Given device path instance
|
---|
104 |
|
---|
105 | @return Converted string from given device path.
|
---|
106 | @retval L"?" Converting failed.
|
---|
107 | **/
|
---|
108 | CHAR16 *
|
---|
109 | DevicePathToStr (
|
---|
110 | IN EFI_DEVICE_PATH_PROTOCOL *DevPath
|
---|
111 | )
|
---|
112 | {
|
---|
113 | CHAR16 *Text;
|
---|
114 |
|
---|
115 | Text = ConvertDevicePathToText (
|
---|
116 | DevPath,
|
---|
117 | FALSE,
|
---|
118 | TRUE
|
---|
119 | );
|
---|
120 | if (Text == NULL) {
|
---|
121 | Text = AllocateCopyPool (sizeof (L"?"), L"?");
|
---|
122 | ASSERT (Text != NULL);
|
---|
123 | }
|
---|
124 |
|
---|
125 | return Text;
|
---|
126 | }
|
---|
127 |
|
---|
128 | /**
|
---|
129 | Worker function to get the driver name by ComponentName or ComponentName2 protocol
|
---|
130 | according to the driver binding handle.
|
---|
131 |
|
---|
132 | @param DriverBindingHandle The Handle of DriverBinding.
|
---|
133 | @param ProtocolGuid The pointer to Component Name (2) protocol GUID.
|
---|
134 | @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.
|
---|
135 |
|
---|
136 | @retval !NULL Pointer into the image name if the image name is found,
|
---|
137 | @retval NULL Pointer to NULL if the image name is not found.
|
---|
138 |
|
---|
139 | **/
|
---|
140 | CHAR16 *
|
---|
141 | GetComponentNameWorker (
|
---|
142 | IN EFI_HANDLE DriverBindingHandle,
|
---|
143 | IN EFI_GUID *ProtocolGuid,
|
---|
144 | IN CONST CHAR16 *VariableName
|
---|
145 | )
|
---|
146 | {
|
---|
147 | EFI_STATUS Status;
|
---|
148 | EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
|
---|
149 | CHAR16 *DriverName;
|
---|
150 | CHAR8 *Language;
|
---|
151 | CHAR8 *BestLanguage;
|
---|
152 |
|
---|
153 | Status = gBS->OpenProtocol (
|
---|
154 | DriverBindingHandle,
|
---|
155 | ProtocolGuid,
|
---|
156 | (VOID *)&ComponentName,
|
---|
157 | NULL,
|
---|
158 | NULL,
|
---|
159 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
160 | );
|
---|
161 | if (EFI_ERROR (Status)) {
|
---|
162 | return NULL;
|
---|
163 | }
|
---|
164 |
|
---|
165 | //
|
---|
166 | // Find the best matching language.
|
---|
167 | //
|
---|
168 | GetEfiGlobalVariable2 (VariableName, (VOID **)&Language, NULL);
|
---|
169 | BestLanguage = GetBestLanguage (
|
---|
170 | ComponentName->SupportedLanguages,
|
---|
171 | (BOOLEAN)(ProtocolGuid == &gEfiComponentNameProtocolGuid),
|
---|
172 | Language,
|
---|
173 | NULL
|
---|
174 | );
|
---|
175 |
|
---|
176 | DriverName = NULL;
|
---|
177 | if (BestLanguage != NULL) {
|
---|
178 | ComponentName->GetDriverName (
|
---|
179 | ComponentName,
|
---|
180 | BestLanguage,
|
---|
181 | &DriverName
|
---|
182 | );
|
---|
183 | FreePool (BestLanguage);
|
---|
184 | }
|
---|
185 |
|
---|
186 | if (Language != NULL) {
|
---|
187 | FreePool (Language);
|
---|
188 | }
|
---|
189 |
|
---|
190 | return DriverName;
|
---|
191 | }
|
---|
192 |
|
---|
193 | /**
|
---|
194 | Get the driver name by ComponentName or ComponentName2 protocol
|
---|
195 | according to the driver binding handle
|
---|
196 |
|
---|
197 | @param DriverBindingHandle The Handle of DriverBinding.
|
---|
198 |
|
---|
199 | @retval !NULL Pointer into the image name if the image name is found,
|
---|
200 | @retval NULL Pointer to NULL if the image name is not found.
|
---|
201 |
|
---|
202 | **/
|
---|
203 | CHAR16 *
|
---|
204 | GetComponentName (
|
---|
205 | IN EFI_HANDLE DriverBindingHandle
|
---|
206 | )
|
---|
207 | {
|
---|
208 | CHAR16 *DriverName;
|
---|
209 |
|
---|
210 | //
|
---|
211 | // Try RFC 4646 Component Name 2 protocol first.
|
---|
212 | //
|
---|
213 | DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentName2ProtocolGuid, L"PlatformLang");
|
---|
214 | if (DriverName == NULL) {
|
---|
215 | //
|
---|
216 | // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol.
|
---|
217 | //
|
---|
218 | DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentNameProtocolGuid, L"Lang");
|
---|
219 | }
|
---|
220 |
|
---|
221 | return DriverName;
|
---|
222 | }
|
---|
223 |
|
---|
224 | /**
|
---|
225 | Get the image name from EFI UI section.
|
---|
226 | Get FV protocol by its loaded image protocol to abstract EFI UI section.
|
---|
227 |
|
---|
228 | @param Image Pointer to the loaded image protocol
|
---|
229 |
|
---|
230 | @retval !NULL Pointer to the image name if the image name is found,
|
---|
231 | @retval NULL NULL if the image name is not found.
|
---|
232 |
|
---|
233 | **/
|
---|
234 | CHAR16 *
|
---|
235 | GetImageName (
|
---|
236 | IN EFI_LOADED_IMAGE_PROTOCOL *Image
|
---|
237 | )
|
---|
238 | {
|
---|
239 | EFI_STATUS Status;
|
---|
240 | EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
|
---|
241 | EFI_DEVICE_PATH_PROTOCOL *AlignedDevPathNode;
|
---|
242 | MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
|
---|
243 | VOID *Buffer;
|
---|
244 | UINTN BufferSize;
|
---|
245 | UINT32 AuthenticationStatus;
|
---|
246 | EFI_GUID *NameGuid;
|
---|
247 | EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;
|
---|
248 |
|
---|
249 | Fv2 = NULL;
|
---|
250 | Buffer = NULL;
|
---|
251 | BufferSize = 0;
|
---|
252 |
|
---|
253 | if (Image->FilePath == NULL) {
|
---|
254 | return NULL;
|
---|
255 | }
|
---|
256 |
|
---|
257 | DevPathNode = Image->FilePath;
|
---|
258 |
|
---|
259 | while (!IsDevicePathEnd (DevPathNode)) {
|
---|
260 | //
|
---|
261 | // Make sure device path node is aligned when accessing it's FV Name Guid field.
|
---|
262 | //
|
---|
263 | AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength (DevPathNode), DevPathNode);
|
---|
264 |
|
---|
265 | //
|
---|
266 | // Find the Fv File path
|
---|
267 | //
|
---|
268 | NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)AlignedDevPathNode);
|
---|
269 | if (NameGuid != NULL) {
|
---|
270 | FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)AlignedDevPathNode;
|
---|
271 | Status = gBS->HandleProtocol (
|
---|
272 | Image->DeviceHandle,
|
---|
273 | &gEfiFirmwareVolume2ProtocolGuid,
|
---|
274 | (VOID **)&Fv2
|
---|
275 | );
|
---|
276 | //
|
---|
277 | // Locate Image EFI UI section to get the image name.
|
---|
278 | //
|
---|
279 | if (!EFI_ERROR (Status)) {
|
---|
280 | Status = Fv2->ReadSection (
|
---|
281 | Fv2,
|
---|
282 | &FvFilePath->FvFileName,
|
---|
283 | EFI_SECTION_USER_INTERFACE,
|
---|
284 | 0,
|
---|
285 | &Buffer,
|
---|
286 | &BufferSize,
|
---|
287 | &AuthenticationStatus
|
---|
288 | );
|
---|
289 | if (!EFI_ERROR (Status)) {
|
---|
290 | FreePool (AlignedDevPathNode);
|
---|
291 | break;
|
---|
292 | }
|
---|
293 |
|
---|
294 | Buffer = NULL;
|
---|
295 | }
|
---|
296 | }
|
---|
297 |
|
---|
298 | FreePool (AlignedDevPathNode);
|
---|
299 |
|
---|
300 | //
|
---|
301 | // Next device path node
|
---|
302 | //
|
---|
303 | DevPathNode = NextDevicePathNode (DevPathNode);
|
---|
304 | }
|
---|
305 |
|
---|
306 | return Buffer;
|
---|
307 | }
|
---|
308 |
|
---|
309 | /**
|
---|
310 | Prepare the first page to let user select the device controller which need to
|
---|
311 | add mapping drivers if user select 'Refresh' in first page.
|
---|
312 | During first page, user will see all currnet controller device path in system,
|
---|
313 | select any device path will go to second page to select its overrides drivers.
|
---|
314 |
|
---|
315 | @param Private Pointer to EFI_CALLBACK_INFO.
|
---|
316 | @param KeyValue The callback key value of device controller item in first page.
|
---|
317 | @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
|
---|
318 |
|
---|
319 | @retval EFI_SUCCESS Always returned.
|
---|
320 |
|
---|
321 | **/
|
---|
322 | EFI_STATUS
|
---|
323 | UpdateDeviceSelectPage (
|
---|
324 | IN EFI_CALLBACK_INFO *Private,
|
---|
325 | IN UINT16 KeyValue,
|
---|
326 | IN PLAT_OVER_MNGR_DATA *FakeNvData
|
---|
327 | )
|
---|
328 | {
|
---|
329 | EFI_STATUS Status;
|
---|
330 | UINTN Index;
|
---|
331 | UINTN DevicePathHandleCount;
|
---|
332 | UINTN NewStrSize;
|
---|
333 | CHAR16 *NewString;
|
---|
334 | EFI_STRING_ID NewStringToken;
|
---|
335 | CHAR16 *ControllerName;
|
---|
336 | EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;
|
---|
337 | EFI_PCI_IO_PROTOCOL *PciIo;
|
---|
338 | EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
|
---|
339 | UINTN Len;
|
---|
340 | VOID *StartOpCodeHandle;
|
---|
341 | VOID *EndOpCodeHandle;
|
---|
342 | EFI_IFR_GUID_LABEL *StartLabel;
|
---|
343 | EFI_IFR_GUID_LABEL *EndLabel;
|
---|
344 |
|
---|
345 | //
|
---|
346 | // Set current page form ID.
|
---|
347 | //
|
---|
348 | mCurrentPage = FORM_ID_DEVICE;
|
---|
349 |
|
---|
350 | //
|
---|
351 | // Initial the mapping database in memory
|
---|
352 | //
|
---|
353 | FreeMappingDatabase (&mMappingDataBase);
|
---|
354 | InitOverridesMapping (&mMappingDataBase);
|
---|
355 |
|
---|
356 | //
|
---|
357 | // Init OpCode Handle
|
---|
358 | //
|
---|
359 | StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
---|
360 | ASSERT (StartOpCodeHandle != NULL);
|
---|
361 |
|
---|
362 | EndOpCodeHandle = HiiAllocateOpCodeHandle ();
|
---|
363 | ASSERT (EndOpCodeHandle != NULL);
|
---|
364 |
|
---|
365 | //
|
---|
366 | // Create Hii Extend Label OpCode as the start opcode
|
---|
367 | //
|
---|
368 | StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
---|
369 | StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
---|
370 | StartLabel->Number = FORM_ID_DEVICE;
|
---|
371 |
|
---|
372 | //
|
---|
373 | // Create Hii Extend Label OpCode as the end opcode
|
---|
374 | //
|
---|
375 | EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
---|
376 | EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
---|
377 | EndLabel->Number = LABEL_END;
|
---|
378 |
|
---|
379 | //
|
---|
380 | // Clear first page form
|
---|
381 | //
|
---|
382 | HiiUpdateForm (
|
---|
383 | Private->RegisteredHandle,
|
---|
384 | &gPlatformOverridesManagerGuid,
|
---|
385 | FORM_ID_DEVICE,
|
---|
386 | StartOpCodeHandle, // Label FORM_ID_DEVICE
|
---|
387 | EndOpCodeHandle // LABEL_END
|
---|
388 | );
|
---|
389 |
|
---|
390 | //
|
---|
391 | // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,
|
---|
392 | // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement
|
---|
393 | //
|
---|
394 | NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);
|
---|
395 | NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), NULL);
|
---|
396 | ASSERT (NewString != NULL);
|
---|
397 | if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {
|
---|
398 | ASSERT (FALSE);
|
---|
399 | }
|
---|
400 |
|
---|
401 | FreePool (NewString);
|
---|
402 |
|
---|
403 | NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);
|
---|
404 | NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), NULL);
|
---|
405 | ASSERT (NewString != NULL);
|
---|
406 | if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {
|
---|
407 | ASSERT (FALSE);
|
---|
408 | }
|
---|
409 |
|
---|
410 | FreePool (NewString);
|
---|
411 |
|
---|
412 | //
|
---|
413 | // created needed controller device item in first page
|
---|
414 | //
|
---|
415 | DevicePathHandleCount = 0;
|
---|
416 | Status = gBS->LocateHandleBuffer (
|
---|
417 | ByProtocol,
|
---|
418 | &gEfiDevicePathProtocolGuid,
|
---|
419 | NULL,
|
---|
420 | &DevicePathHandleCount,
|
---|
421 | &mDevicePathHandleBuffer
|
---|
422 | );
|
---|
423 | if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {
|
---|
424 | return EFI_SUCCESS;
|
---|
425 | }
|
---|
426 |
|
---|
427 | mMaxDeviceCount = DevicePathHandleCount;
|
---|
428 | mControllerDevicePathProtocol = AllocateZeroPool (DevicePathHandleCount * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
|
---|
429 | ASSERT (mControllerDevicePathProtocol != NULL);
|
---|
430 | mControllerToken = AllocateZeroPool (DevicePathHandleCount * sizeof (EFI_STRING_ID));
|
---|
431 | ASSERT (mControllerToken != NULL);
|
---|
432 |
|
---|
433 | for (Index = 0; Index < DevicePathHandleCount; Index++) {
|
---|
434 | if (FakeNvData->PciDeviceFilter == 0x01) {
|
---|
435 | //
|
---|
436 | // Only care PCI device which contain efi driver in its option rom.
|
---|
437 | //
|
---|
438 |
|
---|
439 | //
|
---|
440 | // Check whether it is a pci device
|
---|
441 | //
|
---|
442 | ControllerDevicePath = NULL;
|
---|
443 | Status = gBS->OpenProtocol (
|
---|
444 | mDevicePathHandleBuffer[Index],
|
---|
445 | &gEfiPciIoProtocolGuid,
|
---|
446 | (VOID **)&PciIo,
|
---|
447 | NULL,
|
---|
448 | NULL,
|
---|
449 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
450 | );
|
---|
451 | if (EFI_ERROR (Status)) {
|
---|
452 | continue;
|
---|
453 | }
|
---|
454 |
|
---|
455 | //
|
---|
456 | // Check whether it contain efi driver in its option rom
|
---|
457 | //
|
---|
458 | Status = gBS->HandleProtocol (
|
---|
459 | mDevicePathHandleBuffer[Index],
|
---|
460 | &gEfiBusSpecificDriverOverrideProtocolGuid,
|
---|
461 | (VOID **)&BusSpecificDriverOverride
|
---|
462 | );
|
---|
463 | if (EFI_ERROR (Status) || (BusSpecificDriverOverride == NULL)) {
|
---|
464 | continue;
|
---|
465 | }
|
---|
466 | }
|
---|
467 |
|
---|
468 | ControllerDevicePath = NULL;
|
---|
469 | Status = gBS->OpenProtocol (
|
---|
470 | mDevicePathHandleBuffer[Index],
|
---|
471 | &gEfiDevicePathProtocolGuid,
|
---|
472 | (VOID **)&ControllerDevicePath,
|
---|
473 | NULL,
|
---|
474 | NULL,
|
---|
475 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
476 | );
|
---|
477 | ASSERT_EFI_ERROR (Status);
|
---|
478 | //
|
---|
479 | // Save the device path protocol interface
|
---|
480 | //
|
---|
481 | mControllerDevicePathProtocol[Index] = ControllerDevicePath;
|
---|
482 |
|
---|
483 | //
|
---|
484 | // Get the driver name
|
---|
485 | //
|
---|
486 | ControllerName = DevicePathToStr (ControllerDevicePath);
|
---|
487 |
|
---|
488 | //
|
---|
489 | // Export the driver name string and create item in set options page
|
---|
490 | //
|
---|
491 | Len = StrSize (ControllerName);
|
---|
492 | NewStrSize = Len + StrSize (L"--");
|
---|
493 | NewString = AllocateZeroPool (NewStrSize);
|
---|
494 | ASSERT (NewString != NULL);
|
---|
495 | if (EFI_ERROR (CheckMapping (ControllerDevicePath, NULL, &mMappingDataBase, NULL, NULL))) {
|
---|
496 | StrCatS (NewString, NewStrSize/sizeof (CHAR16), L"--");
|
---|
497 | } else {
|
---|
498 | StrCatS (NewString, NewStrSize/sizeof (CHAR16), L"**");
|
---|
499 | }
|
---|
500 |
|
---|
501 | StrCatS (NewString, NewStrSize/sizeof (CHAR16), ControllerName);
|
---|
502 |
|
---|
503 | NewStringToken = HiiSetString (Private->RegisteredHandle, mControllerToken[Index], NewString, NULL);
|
---|
504 | ASSERT (NewStringToken != 0);
|
---|
505 | FreePool (NewString);
|
---|
506 | //
|
---|
507 | // Save the device path string toke for next access use
|
---|
508 | //
|
---|
509 | mControllerToken[Index] = NewStringToken;
|
---|
510 |
|
---|
511 | HiiCreateGotoOpCode (
|
---|
512 | StartOpCodeHandle,
|
---|
513 | FORM_ID_DRIVER,
|
---|
514 | NewStringToken,
|
---|
515 | STRING_TOKEN (STR_GOTO_HELP_DRIVER),
|
---|
516 | EFI_IFR_FLAG_CALLBACK,
|
---|
517 | (UINT16)(Index + KEY_VALUE_DEVICE_OFFSET)
|
---|
518 | );
|
---|
519 | }
|
---|
520 |
|
---|
521 | //
|
---|
522 | // Update first page form
|
---|
523 | //
|
---|
524 | HiiUpdateForm (
|
---|
525 | Private->RegisteredHandle,
|
---|
526 | &gPlatformOverridesManagerGuid,
|
---|
527 | FORM_ID_DEVICE,
|
---|
528 | StartOpCodeHandle, // Label FORM_ID_DEVICE
|
---|
529 | EndOpCodeHandle // LABEL_END
|
---|
530 | );
|
---|
531 |
|
---|
532 | HiiFreeOpCodeHandle (StartOpCodeHandle);
|
---|
533 | HiiFreeOpCodeHandle (EndOpCodeHandle);
|
---|
534 |
|
---|
535 | return EFI_SUCCESS;
|
---|
536 | }
|
---|
537 |
|
---|
538 | /**
|
---|
539 | Get the first Driver Binding handle which has the specific image handle.
|
---|
540 |
|
---|
541 | @param ImageHandle The Image handle
|
---|
542 |
|
---|
543 | @return Handle to Driver binding
|
---|
544 | @retval NULL The parameter is not valid or the driver binding handle is not found.
|
---|
545 |
|
---|
546 | **/
|
---|
547 | EFI_HANDLE
|
---|
548 | GetDriverBindingHandleFromImageHandle (
|
---|
549 | IN EFI_HANDLE ImageHandle
|
---|
550 | )
|
---|
551 | {
|
---|
552 | EFI_STATUS Status;
|
---|
553 | UINTN Index;
|
---|
554 | UINTN DriverBindingHandleCount;
|
---|
555 | EFI_HANDLE *DriverBindingHandleBuffer;
|
---|
556 | EFI_DRIVER_BINDING_PROTOCOL *DriverBindingInterface;
|
---|
557 | EFI_HANDLE DriverBindingHandle;
|
---|
558 |
|
---|
559 | DriverBindingHandle = NULL;
|
---|
560 |
|
---|
561 | if (ImageHandle == NULL) {
|
---|
562 | return NULL;
|
---|
563 | }
|
---|
564 |
|
---|
565 | //
|
---|
566 | // Get all drivers which support driver binding protocol
|
---|
567 | //
|
---|
568 | DriverBindingHandleCount = 0;
|
---|
569 | Status = gBS->LocateHandleBuffer (
|
---|
570 | ByProtocol,
|
---|
571 | &gEfiDriverBindingProtocolGuid,
|
---|
572 | NULL,
|
---|
573 | &DriverBindingHandleCount,
|
---|
574 | &DriverBindingHandleBuffer
|
---|
575 | );
|
---|
576 | if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
|
---|
577 | return NULL;
|
---|
578 | }
|
---|
579 |
|
---|
580 | //
|
---|
581 | // Get the first Driver Binding handle which has the specific image handle.
|
---|
582 | //
|
---|
583 | for (Index = 0; Index < DriverBindingHandleCount; Index++) {
|
---|
584 | DriverBindingInterface = NULL;
|
---|
585 | Status = gBS->OpenProtocol (
|
---|
586 | DriverBindingHandleBuffer[Index],
|
---|
587 | &gEfiDriverBindingProtocolGuid,
|
---|
588 | (VOID **)&DriverBindingInterface,
|
---|
589 | NULL,
|
---|
590 | NULL,
|
---|
591 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
592 | );
|
---|
593 | if (EFI_ERROR (Status)) {
|
---|
594 | continue;
|
---|
595 | }
|
---|
596 |
|
---|
597 | if (DriverBindingInterface->ImageHandle == ImageHandle) {
|
---|
598 | DriverBindingHandle = DriverBindingHandleBuffer[Index];
|
---|
599 | break;
|
---|
600 | }
|
---|
601 | }
|
---|
602 |
|
---|
603 | FreePool (DriverBindingHandleBuffer);
|
---|
604 | return DriverBindingHandle;
|
---|
605 | }
|
---|
606 |
|
---|
607 | /**
|
---|
608 | Prepare to let user select the drivers which need mapping with the device controller
|
---|
609 | selected in first page.
|
---|
610 |
|
---|
611 | @param Private Pointer to EFI_CALLBACK_INFO.
|
---|
612 | @param KeyValue The callback key value of device controller item in first page.
|
---|
613 | KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.
|
---|
614 | @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
|
---|
615 |
|
---|
616 | @retval EFI_SUCCESS Always returned.
|
---|
617 |
|
---|
618 | **/
|
---|
619 | EFI_STATUS
|
---|
620 | UpdateBindingDriverSelectPage (
|
---|
621 | IN EFI_CALLBACK_INFO *Private,
|
---|
622 | IN UINT16 KeyValue,
|
---|
623 | IN PLAT_OVER_MNGR_DATA *FakeNvData
|
---|
624 | )
|
---|
625 | {
|
---|
626 | EFI_STATUS Status;
|
---|
627 | UINTN Index;
|
---|
628 | UINTN NewStrSize;
|
---|
629 | CHAR16 *NewString;
|
---|
630 | EFI_STRING_ID NewStringToken;
|
---|
631 | EFI_STRING_ID NewStringHelpToken;
|
---|
632 | UINTN DriverImageHandleCount;
|
---|
633 | EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
---|
634 | CHAR16 *DriverName;
|
---|
635 | BOOLEAN FreeDriverName;
|
---|
636 | EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
|
---|
637 | EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
|
---|
638 | EFI_HANDLE DriverBindingHandle;
|
---|
639 | VOID *StartOpCodeHandle;
|
---|
640 | VOID *EndOpCodeHandle;
|
---|
641 | EFI_IFR_GUID_LABEL *StartLabel;
|
---|
642 | EFI_IFR_GUID_LABEL *EndLabel;
|
---|
643 | EFI_LOADED_IMAGE_PROTOCOL **DriverImageProtocol;
|
---|
644 | EFI_STRING_ID *DriverImageFilePathToken;
|
---|
645 | UINT8 CheckFlags;
|
---|
646 |
|
---|
647 | //
|
---|
648 | // If user select a controller item in the first page the following code will be run.
|
---|
649 | // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown
|
---|
650 | //
|
---|
651 | // First acquire the list of Loaded Image Protocols, and then when want the name of the driver, look up all the Driver Binding Protocols
|
---|
652 | // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.
|
---|
653 | // then use the Component Name Protocol on the same handle as the first matching Driver Binding Protocol to look up the name of the driver.
|
---|
654 | //
|
---|
655 |
|
---|
656 | mCurrentPage = FORM_ID_DRIVER;
|
---|
657 | //
|
---|
658 | // Switch the item callback key value to its NO. in mDevicePathHandleBuffer
|
---|
659 | //
|
---|
660 | mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET;
|
---|
661 | ASSERT (mSelectedCtrIndex >= 0 && mSelectedCtrIndex < MAX_CHOICE_NUM);
|
---|
662 |
|
---|
663 | mLastSavedDriverImageNum = 0;
|
---|
664 |
|
---|
665 | //
|
---|
666 | // Init OpCode Handle
|
---|
667 | //
|
---|
668 | StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
---|
669 | ASSERT (StartOpCodeHandle != NULL);
|
---|
670 |
|
---|
671 | EndOpCodeHandle = HiiAllocateOpCodeHandle ();
|
---|
672 | ASSERT (EndOpCodeHandle != NULL);
|
---|
673 |
|
---|
674 | //
|
---|
675 | // Create Hii Extend Label OpCode as the start opcode
|
---|
676 | //
|
---|
677 | StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
---|
678 | StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
---|
679 | StartLabel->Number = FORM_ID_DRIVER;
|
---|
680 |
|
---|
681 | //
|
---|
682 | // Create Hii Extend Label OpCode as the end opcode
|
---|
683 | //
|
---|
684 | EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
---|
685 | EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
---|
686 | EndLabel->Number = LABEL_END;
|
---|
687 |
|
---|
688 | //
|
---|
689 | // Clear second page form
|
---|
690 | //
|
---|
691 | HiiUpdateForm (
|
---|
692 | Private->RegisteredHandle,
|
---|
693 | &gPlatformOverridesManagerGuid,
|
---|
694 | FORM_ID_DRIVER,
|
---|
695 | StartOpCodeHandle,
|
---|
696 | EndOpCodeHandle
|
---|
697 | );
|
---|
698 |
|
---|
699 | //
|
---|
700 | // Show all driver which support loaded image protocol in second page
|
---|
701 | //
|
---|
702 | DriverImageHandleCount = 0;
|
---|
703 | Status = gBS->LocateHandleBuffer (
|
---|
704 | ByProtocol,
|
---|
705 | &gEfiLoadedImageProtocolGuid,
|
---|
706 | NULL,
|
---|
707 | &DriverImageHandleCount,
|
---|
708 | &mDriverImageHandleBuffer
|
---|
709 | );
|
---|
710 | if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {
|
---|
711 | return EFI_NOT_FOUND;
|
---|
712 | }
|
---|
713 |
|
---|
714 | mDriverImageToken = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_STRING_ID));
|
---|
715 | ASSERT (mDriverImageToken != NULL);
|
---|
716 | mDriSelection = AllocateZeroPool (DriverImageHandleCount * sizeof (BOOLEAN));
|
---|
717 | ASSERT (mDriSelection != NULL);
|
---|
718 |
|
---|
719 | DriverImageProtocol = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));
|
---|
720 | ASSERT (DriverImageProtocol != NULL);
|
---|
721 | DriverImageFilePathToken = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_STRING_ID));
|
---|
722 | ASSERT (DriverImageFilePathToken != NULL);
|
---|
723 |
|
---|
724 | mDriverImageHandleCount = DriverImageHandleCount;
|
---|
725 | for (Index = 0; Index < DriverImageHandleCount; Index++) {
|
---|
726 | //
|
---|
727 | // Step1: Get the driver image total file path for help string and the driver name.
|
---|
728 | //
|
---|
729 |
|
---|
730 | //
|
---|
731 | // Find driver's Loaded Image protocol
|
---|
732 | //
|
---|
733 | LoadedImage = NULL;
|
---|
734 |
|
---|
735 | Status = gBS->OpenProtocol (
|
---|
736 | mDriverImageHandleBuffer[Index],
|
---|
737 | &gEfiLoadedImageProtocolGuid,
|
---|
738 | (VOID **)&LoadedImage,
|
---|
739 | NULL,
|
---|
740 | NULL,
|
---|
741 | EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
---|
742 | );
|
---|
743 | if (EFI_ERROR (Status)) {
|
---|
744 | mDriSelection[Index] = FALSE;
|
---|
745 | continue;
|
---|
746 | }
|
---|
747 |
|
---|
748 | DriverImageProtocol[Index] = LoadedImage;
|
---|
749 | //
|
---|
750 | // Find its related driver binding protocol
|
---|
751 | //
|
---|
752 | DriverBindingHandle = GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer[Index]);
|
---|
753 | if (DriverBindingHandle == NULL) {
|
---|
754 | mDriSelection[Index] = FALSE;
|
---|
755 | continue;
|
---|
756 | }
|
---|
757 |
|
---|
758 | //
|
---|
759 | // Get the EFI Loaded Image Device Path Protocol
|
---|
760 | //
|
---|
761 | LoadedImageDevicePath = NULL;
|
---|
762 | Status = gBS->HandleProtocol (
|
---|
763 | mDriverImageHandleBuffer[Index],
|
---|
764 | &gEfiLoadedImageDevicePathProtocolGuid,
|
---|
765 | (VOID **)&LoadedImageDevicePath
|
---|
766 | );
|
---|
767 | if (LoadedImageDevicePath == NULL) {
|
---|
768 | mDriSelection[Index] = FALSE;
|
---|
769 | continue;
|
---|
770 | }
|
---|
771 |
|
---|
772 | if (FakeNvData->PciDeviceFilter == 0x01) {
|
---|
773 | //
|
---|
774 | // only care the driver which is in a Pci device option rom,
|
---|
775 | // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom
|
---|
776 | //
|
---|
777 | if (!EFI_ERROR (Status)) {
|
---|
778 | Status = gBS->HandleProtocol (
|
---|
779 | LoadedImage->DeviceHandle,
|
---|
780 | &gEfiBusSpecificDriverOverrideProtocolGuid,
|
---|
781 | (VOID **)&BusSpecificDriverOverride
|
---|
782 | );
|
---|
783 | if (EFI_ERROR (Status) || (BusSpecificDriverOverride == NULL)) {
|
---|
784 | mDriSelection[Index] = FALSE;
|
---|
785 | continue;
|
---|
786 | }
|
---|
787 | } else {
|
---|
788 | mDriSelection[Index] = FALSE;
|
---|
789 | continue;
|
---|
790 | }
|
---|
791 | }
|
---|
792 |
|
---|
793 | //
|
---|
794 | // For driver name, try to get its component name, if fail, get its image name,
|
---|
795 | // if also fail, give a default name.
|
---|
796 | //
|
---|
797 | FreeDriverName = FALSE;
|
---|
798 | DriverName = GetComponentName (DriverBindingHandle);
|
---|
799 | if (DriverName == NULL) {
|
---|
800 | //
|
---|
801 | // get its image name
|
---|
802 | //
|
---|
803 | DriverName = GetImageName (LoadedImage);
|
---|
804 | }
|
---|
805 |
|
---|
806 | if (DriverName == NULL) {
|
---|
807 | //
|
---|
808 | // give a default name
|
---|
809 | //
|
---|
810 | DriverName = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME), NULL);
|
---|
811 | ASSERT (DriverName != NULL);
|
---|
812 | FreeDriverName = TRUE; // the DriverName string need to free pool
|
---|
813 | }
|
---|
814 |
|
---|
815 | //
|
---|
816 | // Step2 Export the driver name string and create check box item in second page
|
---|
817 | //
|
---|
818 |
|
---|
819 | //
|
---|
820 | // First create the driver image name
|
---|
821 | //
|
---|
822 | NewStrSize = StrSize (DriverName);
|
---|
823 | NewString = AllocateZeroPool (NewStrSize);
|
---|
824 | ASSERT (NewString != NULL);
|
---|
825 | if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {
|
---|
826 | mDriSelection[Index] = FALSE;
|
---|
827 | } else {
|
---|
828 | mDriSelection[Index] = TRUE;
|
---|
829 | mLastSavedDriverImageNum++;
|
---|
830 | }
|
---|
831 |
|
---|
832 | StrCatS (NewString, NewStrSize/sizeof (CHAR16), DriverName);
|
---|
833 | NewStringToken = HiiSetString (Private->RegisteredHandle, mDriverImageToken[Index], NewString, NULL);
|
---|
834 | ASSERT (NewStringToken != 0);
|
---|
835 | mDriverImageToken[Index] = NewStringToken;
|
---|
836 | FreePool (NewString);
|
---|
837 | if (FreeDriverName) {
|
---|
838 | FreePool (DriverName);
|
---|
839 | }
|
---|
840 |
|
---|
841 | //
|
---|
842 | // Second create the driver image device path as item help string
|
---|
843 | //
|
---|
844 | DriverName = DevicePathToStr (LoadedImageDevicePath);
|
---|
845 |
|
---|
846 | NewStrSize = StrSize (DriverName);
|
---|
847 | NewString = AllocateZeroPool (NewStrSize);
|
---|
848 | ASSERT (NewString != NULL);
|
---|
849 | StrCatS (NewString, NewStrSize/sizeof (CHAR16), DriverName);
|
---|
850 | NewStringHelpToken = HiiSetString (Private->RegisteredHandle, DriverImageFilePathToken[Index], NewString, NULL);
|
---|
851 | ASSERT (NewStringHelpToken != 0);
|
---|
852 | DriverImageFilePathToken[Index] = NewStringHelpToken;
|
---|
853 | FreePool (NewString);
|
---|
854 | FreePool (DriverName);
|
---|
855 |
|
---|
856 | CheckFlags = 0;
|
---|
857 | if (mDriSelection[Index]) {
|
---|
858 | CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
|
---|
859 | }
|
---|
860 |
|
---|
861 | HiiCreateCheckBoxOpCode (
|
---|
862 | StartOpCodeHandle,
|
---|
863 | (UINT16)(KEY_VALUE_DRIVER_OFFSET + Index),
|
---|
864 | 0,
|
---|
865 | 0,
|
---|
866 | NewStringToken,
|
---|
867 | NewStringHelpToken,
|
---|
868 | EFI_IFR_FLAG_CALLBACK,
|
---|
869 | CheckFlags,
|
---|
870 | NULL
|
---|
871 | );
|
---|
872 | }
|
---|
873 |
|
---|
874 | //
|
---|
875 | // Update second page form
|
---|
876 | //
|
---|
877 | HiiUpdateForm (
|
---|
878 | Private->RegisteredHandle,
|
---|
879 | &gPlatformOverridesManagerGuid,
|
---|
880 | FORM_ID_DRIVER,
|
---|
881 | StartOpCodeHandle, // Label FORM_ID_DRIVER
|
---|
882 | EndOpCodeHandle // LABEL_END
|
---|
883 | );
|
---|
884 |
|
---|
885 | HiiFreeOpCodeHandle (StartOpCodeHandle);
|
---|
886 | HiiFreeOpCodeHandle (EndOpCodeHandle);
|
---|
887 |
|
---|
888 | if (DriverImageProtocol != NULL) {
|
---|
889 | FreePool (DriverImageProtocol);
|
---|
890 | }
|
---|
891 |
|
---|
892 | if (DriverImageFilePathToken != NULL) {
|
---|
893 | FreePool (DriverImageFilePathToken);
|
---|
894 | }
|
---|
895 |
|
---|
896 | return EFI_SUCCESS;
|
---|
897 | }
|
---|
898 |
|
---|
899 | /**
|
---|
900 | Prepare to let user select the priority order of the drivers which are
|
---|
901 | selected in second page.
|
---|
902 |
|
---|
903 | @param Private Pointer to EFI_CALLBACK_INFO.
|
---|
904 | @param KeyValue The callback key value of device controller item in first page.
|
---|
905 | @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
|
---|
906 |
|
---|
907 | @retval EFI_SUCCESS Always returned.
|
---|
908 |
|
---|
909 | **/
|
---|
910 | EFI_STATUS
|
---|
911 | UpdatePrioritySelectPage (
|
---|
912 | IN EFI_CALLBACK_INFO *Private,
|
---|
913 | IN UINT16 KeyValue,
|
---|
914 | IN PLAT_OVER_MNGR_DATA *FakeNvData
|
---|
915 | )
|
---|
916 | {
|
---|
917 | UINTN Index;
|
---|
918 | EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
|
---|
919 | UINTN SelectedDriverImageNum;
|
---|
920 | UINT32 DriverImageNO;
|
---|
921 | UINTN MinNO;
|
---|
922 | UINTN Index1;
|
---|
923 | UINTN TempNO[100];
|
---|
924 | UINTN OrderNO[100];
|
---|
925 | VOID *StartOpCodeHandle;
|
---|
926 | VOID *EndOpCodeHandle;
|
---|
927 | VOID *OptionsOpCodeHandle;
|
---|
928 | EFI_IFR_GUID_LABEL *StartLabel;
|
---|
929 | EFI_IFR_GUID_LABEL *EndLabel;
|
---|
930 |
|
---|
931 | //
|
---|
932 | // Following code will be run if user select 'order ... priority' item in second page
|
---|
933 | // Prepare third page. In third page, user will order the drivers priority which are selected in second page
|
---|
934 | //
|
---|
935 | mCurrentPage = FORM_ID_ORDER;
|
---|
936 |
|
---|
937 | //
|
---|
938 | // Init OpCode Handle
|
---|
939 | //
|
---|
940 | StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
---|
941 | ASSERT (StartOpCodeHandle != NULL);
|
---|
942 |
|
---|
943 | EndOpCodeHandle = HiiAllocateOpCodeHandle ();
|
---|
944 | ASSERT (EndOpCodeHandle != NULL);
|
---|
945 |
|
---|
946 | //
|
---|
947 | // Create Hii Extend Label OpCode as the start opcode
|
---|
948 | //
|
---|
949 | StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
---|
950 | StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
---|
951 | StartLabel->Number = FORM_ID_ORDER;
|
---|
952 |
|
---|
953 | //
|
---|
954 | // Create Hii Extend Label OpCode as the end opcode
|
---|
955 | //
|
---|
956 | EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
---|
957 | EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
---|
958 | EndLabel->Number = LABEL_END;
|
---|
959 |
|
---|
960 | //
|
---|
961 | // Clear third page form
|
---|
962 | //
|
---|
963 | HiiUpdateForm (
|
---|
964 | Private->RegisteredHandle,
|
---|
965 | &gPlatformOverridesManagerGuid,
|
---|
966 | FORM_ID_ORDER,
|
---|
967 | StartOpCodeHandle,
|
---|
968 | EndOpCodeHandle
|
---|
969 | );
|
---|
970 |
|
---|
971 | //
|
---|
972 | // Check how many drivers have been selected
|
---|
973 | //
|
---|
974 | SelectedDriverImageNum = 0;
|
---|
975 | for (Index = 0; Index < mDriverImageHandleCount; Index++) {
|
---|
976 | if (mDriSelection[Index]) {
|
---|
977 | SelectedDriverImageNum++;
|
---|
978 | }
|
---|
979 | }
|
---|
980 |
|
---|
981 | mSelectedDriverImageNum = SelectedDriverImageNum;
|
---|
982 | if (SelectedDriverImageNum == 0) {
|
---|
983 | return EFI_SUCCESS;
|
---|
984 | }
|
---|
985 |
|
---|
986 | OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
---|
987 | ASSERT (OptionsOpCodeHandle != NULL);
|
---|
988 |
|
---|
989 | //
|
---|
990 | // Create order list for those selected drivers
|
---|
991 | //
|
---|
992 | SelectedDriverImageNum = 0;
|
---|
993 | for (Index = 0; Index < mDriverImageHandleCount; Index++) {
|
---|
994 | if (mDriSelection[Index]) {
|
---|
995 | //
|
---|
996 | // Use the NO. in driver binding buffer as value, will use it later
|
---|
997 | //
|
---|
998 | HiiCreateOneOfOptionOpCode (
|
---|
999 | OptionsOpCodeHandle,
|
---|
1000 | mDriverImageToken[Index],
|
---|
1001 | 0,
|
---|
1002 | EFI_IFR_NUMERIC_SIZE_1,
|
---|
1003 | Index + 1
|
---|
1004 | );
|
---|
1005 |
|
---|
1006 | //
|
---|
1007 | // Get the EFI Loaded Image Device Path Protocol
|
---|
1008 | //
|
---|
1009 | LoadedImageDevicePath = NULL;
|
---|
1010 | gBS->HandleProtocol (
|
---|
1011 | mDriverImageHandleBuffer[Index],
|
---|
1012 | &gEfiLoadedImageDevicePathProtocolGuid,
|
---|
1013 | (VOID **)&LoadedImageDevicePath
|
---|
1014 | );
|
---|
1015 | ASSERT (LoadedImageDevicePath != NULL);
|
---|
1016 |
|
---|
1017 | //
|
---|
1018 | // Check the driver DriverImage's order number in mapping database
|
---|
1019 | //
|
---|
1020 | DriverImageNO = 0;
|
---|
1021 | CheckMapping (
|
---|
1022 | mControllerDevicePathProtocol[mSelectedCtrIndex],
|
---|
1023 | LoadedImageDevicePath,
|
---|
1024 | &mMappingDataBase,
|
---|
1025 | NULL,
|
---|
1026 | &DriverImageNO
|
---|
1027 | );
|
---|
1028 | if (DriverImageNO == 0) {
|
---|
1029 | DriverImageNO = (UINT32)mLastSavedDriverImageNum + 1;
|
---|
1030 | mLastSavedDriverImageNum++;
|
---|
1031 | }
|
---|
1032 |
|
---|
1033 | TempNO[SelectedDriverImageNum] = DriverImageNO;
|
---|
1034 | OrderNO[SelectedDriverImageNum] = Index + 1;
|
---|
1035 | SelectedDriverImageNum++;
|
---|
1036 | }
|
---|
1037 | }
|
---|
1038 |
|
---|
1039 | ASSERT (SelectedDriverImageNum == mSelectedDriverImageNum);
|
---|
1040 | //
|
---|
1041 | // NvRamMap Must be clear firstly
|
---|
1042 | //
|
---|
1043 | ZeroMem (FakeNvData->DriOrder, sizeof (FakeNvData->DriOrder));
|
---|
1044 |
|
---|
1045 | //
|
---|
1046 | // Order the selected drivers according to the info already in mapping database
|
---|
1047 | // the less order number in mapping database the less order number in NvRamMap
|
---|
1048 | //
|
---|
1049 | for (Index = 0; Index < SelectedDriverImageNum; Index++) {
|
---|
1050 | //
|
---|
1051 | // Find the minimal order number in TempNO array, its index in TempNO is same as IfrOptionList array
|
---|
1052 | //
|
---|
1053 | MinNO = 0;
|
---|
1054 | for (Index1 = 0; Index1 < SelectedDriverImageNum; Index1++) {
|
---|
1055 | if (TempNO[Index1] < TempNO[MinNO]) {
|
---|
1056 | MinNO = Index1;
|
---|
1057 | }
|
---|
1058 | }
|
---|
1059 |
|
---|
1060 | //
|
---|
1061 | // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer
|
---|
1062 | //
|
---|
1063 | FakeNvData->DriOrder[Index] = (UINT8)OrderNO[MinNO];
|
---|
1064 | TempNO[MinNO] = MAX_CHOICE_NUM + 1;
|
---|
1065 | }
|
---|
1066 |
|
---|
1067 | //
|
---|
1068 | // Create Order List OpCode
|
---|
1069 | //
|
---|
1070 | HiiCreateOrderedListOpCode (
|
---|
1071 | StartOpCodeHandle,
|
---|
1072 | (UINT16)DRIVER_ORDER_QUESTION_ID,
|
---|
1073 | VARSTORE_ID_PLAT_OVER_MNGR,
|
---|
1074 | (UINT16)DRIVER_ORDER_VAR_OFFSET,
|
---|
1075 | mControllerToken[mSelectedCtrIndex],
|
---|
1076 | mControllerToken[mSelectedCtrIndex],
|
---|
1077 | EFI_IFR_FLAG_RESET_REQUIRED,
|
---|
1078 | 0,
|
---|
1079 | EFI_IFR_NUMERIC_SIZE_1,
|
---|
1080 | (UINT8)MAX_CHOICE_NUM,
|
---|
1081 | OptionsOpCodeHandle,
|
---|
1082 | NULL
|
---|
1083 | );
|
---|
1084 |
|
---|
1085 | //
|
---|
1086 | // Update third page form
|
---|
1087 | //
|
---|
1088 | HiiUpdateForm (
|
---|
1089 | Private->RegisteredHandle,
|
---|
1090 | &gPlatformOverridesManagerGuid,
|
---|
1091 | FORM_ID_ORDER,
|
---|
1092 | StartOpCodeHandle, // Label FORM_ID_ORDER
|
---|
1093 | EndOpCodeHandle // LABEL_END
|
---|
1094 | );
|
---|
1095 |
|
---|
1096 | HiiFreeOpCodeHandle (StartOpCodeHandle);
|
---|
1097 | HiiFreeOpCodeHandle (EndOpCodeHandle);
|
---|
1098 | HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
---|
1099 |
|
---|
1100 | return EFI_SUCCESS;
|
---|
1101 | }
|
---|
1102 |
|
---|
1103 | /**
|
---|
1104 | Save the save the mapping database to NV variable.
|
---|
1105 |
|
---|
1106 | @param Private Pointer to EFI_CALLBACK_INFO.
|
---|
1107 | @param KeyValue The callback key value of device controller item in first page.
|
---|
1108 | @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
|
---|
1109 |
|
---|
1110 | @retval EFI_SUCCESS Always returned.
|
---|
1111 |
|
---|
1112 | **/
|
---|
1113 | EFI_STATUS
|
---|
1114 | CommitChanges (
|
---|
1115 | IN EFI_CALLBACK_INFO *Private,
|
---|
1116 | IN UINT16 KeyValue,
|
---|
1117 | IN PLAT_OVER_MNGR_DATA *FakeNvData
|
---|
1118 | )
|
---|
1119 | {
|
---|
1120 | EFI_STATUS Status;
|
---|
1121 | UINTN Index;
|
---|
1122 | UINTN SelectedDriverImageNum;
|
---|
1123 | EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
|
---|
1124 |
|
---|
1125 | //
|
---|
1126 | // Following code will be run if user select 'commint changes' in third page
|
---|
1127 | // user enter 'Commit Changes' to save the mapping database
|
---|
1128 | //
|
---|
1129 | DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);
|
---|
1130 | for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {
|
---|
1131 | //
|
---|
1132 | // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer
|
---|
1133 | //
|
---|
1134 | Index = FakeNvData->DriOrder[SelectedDriverImageNum] - 1;
|
---|
1135 |
|
---|
1136 | //
|
---|
1137 | // Get the EFI Loaded Image Device Path Protocol
|
---|
1138 | //
|
---|
1139 | LoadedImageDevicePath = NULL;
|
---|
1140 | Status = gBS->HandleProtocol (
|
---|
1141 | mDriverImageHandleBuffer[Index],
|
---|
1142 | &gEfiLoadedImageDevicePathProtocolGuid,
|
---|
1143 | (VOID **)&LoadedImageDevicePath
|
---|
1144 | );
|
---|
1145 | ASSERT (LoadedImageDevicePath != NULL);
|
---|
1146 |
|
---|
1147 | InsertDriverImage (
|
---|
1148 | mControllerDevicePathProtocol[mSelectedCtrIndex],
|
---|
1149 | LoadedImageDevicePath,
|
---|
1150 | &mMappingDataBase,
|
---|
1151 | (UINT32)SelectedDriverImageNum + 1
|
---|
1152 | );
|
---|
1153 | }
|
---|
1154 |
|
---|
1155 | Status = SaveOverridesMapping (&mMappingDataBase);
|
---|
1156 |
|
---|
1157 | return Status;
|
---|
1158 | }
|
---|
1159 |
|
---|
1160 | /**
|
---|
1161 | This function allows a caller to extract the current configuration for one
|
---|
1162 | or more named elements from the target driver.
|
---|
1163 |
|
---|
1164 | @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
---|
1165 | @param Request A null-terminated Unicode string in <ConfigRequest> format.
|
---|
1166 | @param Progress On return, points to a character in the Request string.
|
---|
1167 | Points to the string's null terminator if request was successful.
|
---|
1168 | Points to the most recent '&' before the first failing name/value
|
---|
1169 | pair (or the beginning of the string if the failure is in the
|
---|
1170 | first name/value pair) if the request was not successful.
|
---|
1171 | @param Results A null-terminated Unicode string in <ConfigAltResp> format which
|
---|
1172 | has all values filled in for the names in the Request string.
|
---|
1173 | String to be allocated by the called function.
|
---|
1174 |
|
---|
1175 | @retval EFI_SUCCESS The Results is filled with the requested values.
|
---|
1176 | @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
|
---|
1177 | @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
|
---|
1178 | @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
|
---|
1179 |
|
---|
1180 | **/
|
---|
1181 | EFI_STATUS
|
---|
1182 | EFIAPI
|
---|
1183 | PlatOverMngrExtractConfig (
|
---|
1184 | IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
---|
1185 | IN CONST EFI_STRING Request,
|
---|
1186 | OUT EFI_STRING *Progress,
|
---|
1187 | OUT EFI_STRING *Results
|
---|
1188 | )
|
---|
1189 | {
|
---|
1190 | EFI_STATUS Status;
|
---|
1191 | EFI_CALLBACK_INFO *Private;
|
---|
1192 | EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
|
---|
1193 | EFI_STRING ConfigRequestHdr;
|
---|
1194 | EFI_STRING ConfigRequest;
|
---|
1195 | BOOLEAN AllocatedRequest;
|
---|
1196 | UINTN Size;
|
---|
1197 | UINTN BufferSize;
|
---|
1198 |
|
---|
1199 | if ((Progress == NULL) || (Results == NULL)) {
|
---|
1200 | return EFI_INVALID_PARAMETER;
|
---|
1201 | }
|
---|
1202 |
|
---|
1203 | *Progress = Request;
|
---|
1204 | if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gPlatformOverridesManagerGuid, mVariableName)) {
|
---|
1205 | return EFI_NOT_FOUND;
|
---|
1206 | }
|
---|
1207 |
|
---|
1208 | ConfigRequestHdr = NULL;
|
---|
1209 | ConfigRequest = NULL;
|
---|
1210 | Size = 0;
|
---|
1211 | AllocatedRequest = FALSE;
|
---|
1212 |
|
---|
1213 | Private = EFI_CALLBACK_INFO_FROM_THIS (This);
|
---|
1214 | HiiConfigRouting = Private->HiiConfigRouting;
|
---|
1215 | ConfigRequest = Request;
|
---|
1216 | if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
|
---|
1217 | //
|
---|
1218 | // Request has no request element, construct full request string.
|
---|
1219 | // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
|
---|
1220 | // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
|
---|
1221 | //
|
---|
1222 | ConfigRequestHdr = HiiConstructConfigHdr (&gPlatformOverridesManagerGuid, mVariableName, Private->DriverHandle);
|
---|
1223 | Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
|
---|
1224 | ConfigRequest = AllocateZeroPool (Size);
|
---|
1225 | ASSERT (ConfigRequest != NULL);
|
---|
1226 | AllocatedRequest = TRUE;
|
---|
1227 | BufferSize = sizeof (PLAT_OVER_MNGR_DATA);
|
---|
1228 | UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
|
---|
1229 | FreePool (ConfigRequestHdr);
|
---|
1230 | }
|
---|
1231 |
|
---|
1232 | //
|
---|
1233 | // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
|
---|
1234 | //
|
---|
1235 | Status = HiiConfigRouting->BlockToConfig (
|
---|
1236 | HiiConfigRouting,
|
---|
1237 | ConfigRequest,
|
---|
1238 | (UINT8 *)&Private->FakeNvData,
|
---|
1239 | sizeof (PLAT_OVER_MNGR_DATA),
|
---|
1240 | Results,
|
---|
1241 | Progress
|
---|
1242 | );
|
---|
1243 |
|
---|
1244 | //
|
---|
1245 | // Free the allocated config request string.
|
---|
1246 | //
|
---|
1247 | if (AllocatedRequest) {
|
---|
1248 | FreePool (ConfigRequest);
|
---|
1249 | ConfigRequest = NULL;
|
---|
1250 | }
|
---|
1251 |
|
---|
1252 | //
|
---|
1253 | // Set Progress string to the original request string.
|
---|
1254 | //
|
---|
1255 | if (Request == NULL) {
|
---|
1256 | *Progress = NULL;
|
---|
1257 | } else if (StrStr (Request, L"OFFSET") == NULL) {
|
---|
1258 | *Progress = Request + StrLen (Request);
|
---|
1259 | }
|
---|
1260 |
|
---|
1261 | return Status;
|
---|
1262 | }
|
---|
1263 |
|
---|
1264 | /**
|
---|
1265 | This function processes the results of changes in configuration.
|
---|
1266 |
|
---|
1267 | @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
---|
1268 | @param Configuration A null-terminated Unicode string in <ConfigRequest> format.
|
---|
1269 | @param Progress A pointer to a string filled in with the offset of the most
|
---|
1270 | recent '&' before the first failing name/value pair (or the
|
---|
1271 | beginning of the string if the failure is in the first
|
---|
1272 | name/value pair) or the terminating NULL if all was successful.
|
---|
1273 |
|
---|
1274 | @retval EFI_SUCCESS The Results is processed successfully.
|
---|
1275 | @retval EFI_INVALID_PARAMETER Configuration is NULL.
|
---|
1276 | @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
|
---|
1277 |
|
---|
1278 | **/
|
---|
1279 | EFI_STATUS
|
---|
1280 | EFIAPI
|
---|
1281 | PlatOverMngrRouteConfig (
|
---|
1282 | IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
---|
1283 | IN CONST EFI_STRING Configuration,
|
---|
1284 | OUT EFI_STRING *Progress
|
---|
1285 | )
|
---|
1286 | {
|
---|
1287 | EFI_CALLBACK_INFO *Private;
|
---|
1288 | UINT16 KeyValue;
|
---|
1289 | PLAT_OVER_MNGR_DATA *FakeNvData;
|
---|
1290 | EFI_STATUS Status;
|
---|
1291 |
|
---|
1292 | if ((Configuration == NULL) || (Progress == NULL)) {
|
---|
1293 | return EFI_INVALID_PARAMETER;
|
---|
1294 | }
|
---|
1295 |
|
---|
1296 | *Progress = Configuration;
|
---|
1297 |
|
---|
1298 | if (!HiiIsConfigHdrMatch (Configuration, &gPlatformOverridesManagerGuid, mVariableName)) {
|
---|
1299 | return EFI_NOT_FOUND;
|
---|
1300 | }
|
---|
1301 |
|
---|
1302 | *Progress = Configuration + StrLen (Configuration);
|
---|
1303 | Private = EFI_CALLBACK_INFO_FROM_THIS (This);
|
---|
1304 | FakeNvData = &Private->FakeNvData;
|
---|
1305 | if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *)FakeNvData)) {
|
---|
1306 | //
|
---|
1307 | // FakeNvData can't be got from SetupBrowser, which doesn't need to be set.
|
---|
1308 | //
|
---|
1309 | return EFI_SUCCESS;
|
---|
1310 | }
|
---|
1311 |
|
---|
1312 | Status = EFI_SUCCESS;
|
---|
1313 |
|
---|
1314 | if (mCurrentPage == FORM_ID_ORDER) {
|
---|
1315 | KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;
|
---|
1316 | Status = CommitChanges (Private, KeyValue, FakeNvData);
|
---|
1317 | }
|
---|
1318 |
|
---|
1319 | return Status;
|
---|
1320 | }
|
---|
1321 |
|
---|
1322 | /**
|
---|
1323 | This is the function that is called to provide results data to the driver. This data
|
---|
1324 | consists of a unique key which is used to identify what data is either being passed back
|
---|
1325 | or being asked for.
|
---|
1326 |
|
---|
1327 | @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
---|
1328 | @param Action A null-terminated Unicode string in <ConfigRequest> format.
|
---|
1329 | @param KeyValue A unique Goto OpCode callback value which record user's selection.
|
---|
1330 | 0x100 <= KeyValue <0x500 : user select a controller item in the first page;
|
---|
1331 | KeyValue == 0x1234 : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page
|
---|
1332 | KeyValue == 0x1235 : user select 'Pci device filter' in first page
|
---|
1333 | KeyValue == 0x1500 : user select 'order ... priority' item in second page
|
---|
1334 | KeyValue == 0x1800 : user select 'commint changes' in third page
|
---|
1335 | KeyValue == 0x2000 : user select 'Go to Previous Menu' in third page
|
---|
1336 | @param Type The type of value for the question.
|
---|
1337 | @param Value A pointer to the data being sent to the original exporting driver.
|
---|
1338 | @param ActionRequest On return, points to the action requested by the callback function.
|
---|
1339 |
|
---|
1340 | @retval EFI_SUCCESS Always returned.
|
---|
1341 |
|
---|
1342 | **/
|
---|
1343 | EFI_STATUS
|
---|
1344 | EFIAPI
|
---|
1345 | PlatOverMngrCallback (
|
---|
1346 | IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
---|
1347 | IN EFI_BROWSER_ACTION Action,
|
---|
1348 | IN EFI_QUESTION_ID KeyValue,
|
---|
1349 | IN UINT8 Type,
|
---|
1350 | IN EFI_IFR_TYPE_VALUE *Value,
|
---|
1351 | OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
---|
1352 | )
|
---|
1353 | {
|
---|
1354 | EFI_CALLBACK_INFO *Private;
|
---|
1355 | EFI_STATUS Status;
|
---|
1356 | EFI_STRING_ID NewStringToken;
|
---|
1357 | EFI_INPUT_KEY Key;
|
---|
1358 | PLAT_OVER_MNGR_DATA *FakeNvData;
|
---|
1359 |
|
---|
1360 | if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
|
---|
1361 | //
|
---|
1362 | // All other action return unsupported.
|
---|
1363 | //
|
---|
1364 | return EFI_UNSUPPORTED;
|
---|
1365 | }
|
---|
1366 |
|
---|
1367 | Private = EFI_CALLBACK_INFO_FROM_THIS (This);
|
---|
1368 | FakeNvData = &Private->FakeNvData;
|
---|
1369 | if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *)FakeNvData)) {
|
---|
1370 | return EFI_NOT_FOUND;
|
---|
1371 | }
|
---|
1372 |
|
---|
1373 | if (Action == EFI_BROWSER_ACTION_CHANGING) {
|
---|
1374 | if (Value == NULL) {
|
---|
1375 | return EFI_INVALID_PARAMETER;
|
---|
1376 | }
|
---|
1377 |
|
---|
1378 | if (KeyValue == KEY_VALUE_DRIVER_GOTO_PREVIOUS) {
|
---|
1379 | UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
|
---|
1380 | //
|
---|
1381 | // Update page title string
|
---|
1382 | //
|
---|
1383 | NewStringToken = STRING_TOKEN (STR_TITLE);
|
---|
1384 | if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {
|
---|
1385 | ASSERT (FALSE);
|
---|
1386 | }
|
---|
1387 | }
|
---|
1388 |
|
---|
1389 | if (((KeyValue >= KEY_VALUE_DEVICE_OFFSET) && (KeyValue < KEY_VALUE_DEVICE_OFFSET + mMaxDeviceCount)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {
|
---|
1390 | if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {
|
---|
1391 | KeyValue = (EFI_QUESTION_ID)(mSelectedCtrIndex + KEY_VALUE_DEVICE_OFFSET);
|
---|
1392 | }
|
---|
1393 |
|
---|
1394 | UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);
|
---|
1395 | //
|
---|
1396 | // Update page title string
|
---|
1397 | //
|
---|
1398 | NewStringToken = STRING_TOKEN (STR_TITLE);
|
---|
1399 | if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Second, Select drivers for the previous selected controller", NULL) == 0) {
|
---|
1400 | ASSERT (FALSE);
|
---|
1401 | }
|
---|
1402 | }
|
---|
1403 |
|
---|
1404 | if (KeyValue == KEY_VALUE_DRIVER_GOTO_ORDER) {
|
---|
1405 | UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);
|
---|
1406 | //
|
---|
1407 | // Update page title string
|
---|
1408 | //
|
---|
1409 | NewStringToken = STRING_TOKEN (STR_TITLE);
|
---|
1410 | if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Finally, Set the priority order for the drivers and save them", NULL) == 0) {
|
---|
1411 | ASSERT (FALSE);
|
---|
1412 | }
|
---|
1413 | }
|
---|
1414 |
|
---|
1415 | if (KeyValue == KEY_VALUE_DEVICE_CLEAR) {
|
---|
1416 | //
|
---|
1417 | // Deletes all environment variable(s) that contain the override mappings info
|
---|
1418 | //
|
---|
1419 | FreeMappingDatabase (&mMappingDataBase);
|
---|
1420 | Status = SaveOverridesMapping (&mMappingDataBase);
|
---|
1421 | UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
|
---|
1422 | }
|
---|
1423 | } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
|
---|
1424 | if ((KeyValue >= KEY_VALUE_DRIVER_OFFSET) && (KeyValue < KEY_VALUE_DRIVER_OFFSET + mDriverImageHandleCount)) {
|
---|
1425 | mDriSelection[KeyValue - KEY_VALUE_DRIVER_OFFSET] = Value->b;
|
---|
1426 | } else {
|
---|
1427 | switch (KeyValue) {
|
---|
1428 | case KEY_VALUE_DEVICE_REFRESH:
|
---|
1429 | case KEY_VALUE_DEVICE_FILTER:
|
---|
1430 | UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
|
---|
1431 | //
|
---|
1432 | // Update page title string
|
---|
1433 | //
|
---|
1434 | NewStringToken = STRING_TOKEN (STR_TITLE);
|
---|
1435 | if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {
|
---|
1436 | ASSERT (FALSE);
|
---|
1437 | }
|
---|
1438 |
|
---|
1439 | break;
|
---|
1440 |
|
---|
1441 | case KEY_VALUE_ORDER_SAVE_AND_EXIT:
|
---|
1442 | Status = CommitChanges (Private, KeyValue, FakeNvData);
|
---|
1443 | *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
|
---|
1444 | if (EFI_ERROR (Status)) {
|
---|
1445 | CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Single Override Info too large, Saving Error!", NULL);
|
---|
1446 | return EFI_DEVICE_ERROR;
|
---|
1447 | }
|
---|
1448 |
|
---|
1449 | break;
|
---|
1450 |
|
---|
1451 | default:
|
---|
1452 | break;
|
---|
1453 | }
|
---|
1454 | }
|
---|
1455 | }
|
---|
1456 |
|
---|
1457 | //
|
---|
1458 | // Pass changed uncommitted data back to Form Browser
|
---|
1459 | //
|
---|
1460 | HiiSetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *)FakeNvData, NULL);
|
---|
1461 |
|
---|
1462 | return EFI_SUCCESS;
|
---|
1463 | }
|
---|
1464 |
|
---|
1465 | /**
|
---|
1466 | Retrieves the image handle of the platform override driver for a controller in the system.
|
---|
1467 |
|
---|
1468 | @param This A pointer to the
|
---|
1469 | EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance.
|
---|
1470 | @param ControllerHandle The device handle of the controller to check if a
|
---|
1471 | driver override exists.
|
---|
1472 | @param DriverImageHandle On input, a pointer to the previous driver image
|
---|
1473 | handle returned by GetDriver(). On output, a
|
---|
1474 | pointer to the next driver image handle. Passing
|
---|
1475 | in a NULL, will return the first driver image
|
---|
1476 | handle for ControllerHandle.
|
---|
1477 |
|
---|
1478 | @retval EFI_SUCCESS The driver override for ControllerHandle was
|
---|
1479 | returned in DriverImageHandle.
|
---|
1480 | @retval EFI_NOT_FOUND A driver override for ControllerHandle was not
|
---|
1481 | found.
|
---|
1482 | @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is NULL.
|
---|
1483 | DriverImageHandle is not a handle that was returned
|
---|
1484 | on a previous call to GetDriver().
|
---|
1485 |
|
---|
1486 | **/
|
---|
1487 | EFI_STATUS
|
---|
1488 | EFIAPI
|
---|
1489 | GetDriver (
|
---|
1490 | IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
|
---|
1491 | IN EFI_HANDLE ControllerHandle,
|
---|
1492 | IN OUT EFI_HANDLE *DriverImageHandle
|
---|
1493 | )
|
---|
1494 | {
|
---|
1495 | EFI_STATUS Status;
|
---|
1496 |
|
---|
1497 | //
|
---|
1498 | // Check that ControllerHandle is a valid handle
|
---|
1499 | //
|
---|
1500 | if (ControllerHandle == NULL) {
|
---|
1501 | return EFI_INVALID_PARAMETER;
|
---|
1502 | }
|
---|
1503 |
|
---|
1504 | //
|
---|
1505 | // Read the environment variable(s) that contain the override mappings from Controller Device Path to
|
---|
1506 | // a set of Driver Device Paths, and initialize in memory database of the overrides that map Controller
|
---|
1507 | // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed
|
---|
1508 | // once and finished in first call.
|
---|
1509 | //
|
---|
1510 | if (!mEnvironmentVariableRead) {
|
---|
1511 | mEnvironmentVariableRead = TRUE;
|
---|
1512 |
|
---|
1513 | Status = InitOverridesMapping (&mMappingDataBase);
|
---|
1514 | if (EFI_ERROR (Status)) {
|
---|
1515 | DEBUG ((DEBUG_INFO, "The status to Get Platform Driver Override Variable is %r\n", Status));
|
---|
1516 | InitializeListHead (&mMappingDataBase);
|
---|
1517 | return EFI_NOT_FOUND;
|
---|
1518 | }
|
---|
1519 | }
|
---|
1520 |
|
---|
1521 | //
|
---|
1522 | // if the environment variable does not exist, just return not found
|
---|
1523 | //
|
---|
1524 | if (IsListEmpty (&mMappingDataBase)) {
|
---|
1525 | return EFI_NOT_FOUND;
|
---|
1526 | }
|
---|
1527 |
|
---|
1528 | return GetDriverFromMapping (
|
---|
1529 | ControllerHandle,
|
---|
1530 | DriverImageHandle,
|
---|
1531 | &mMappingDataBase,
|
---|
1532 | mCallerImageHandle
|
---|
1533 | );
|
---|
1534 | }
|
---|
1535 |
|
---|
1536 | /**
|
---|
1537 | Retrieves the device path of the platform override driver for a controller in the system.
|
---|
1538 | This driver doesn't support this API.
|
---|
1539 |
|
---|
1540 | @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
|
---|
1541 | PROTOCOL instance.
|
---|
1542 | @param ControllerHandle The device handle of the controller to check if a driver override
|
---|
1543 | exists.
|
---|
1544 | @param DriverImagePath On input, a pointer to the previous driver device path returned by
|
---|
1545 | GetDriverPath(). On output, a pointer to the next driver
|
---|
1546 | device path. Passing in a pointer to NULL, will return the first
|
---|
1547 | driver device path for ControllerHandle.
|
---|
1548 |
|
---|
1549 | @retval EFI_UNSUPPORTED
|
---|
1550 | **/
|
---|
1551 | EFI_STATUS
|
---|
1552 | EFIAPI
|
---|
1553 | GetDriverPath (
|
---|
1554 | IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
|
---|
1555 | IN EFI_HANDLE ControllerHandle,
|
---|
1556 | IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath
|
---|
1557 | )
|
---|
1558 | {
|
---|
1559 | return EFI_UNSUPPORTED;
|
---|
1560 | }
|
---|
1561 |
|
---|
1562 | /**
|
---|
1563 | Used to associate a driver image handle with a device path that was returned on a prior call to the
|
---|
1564 | GetDriverPath() service. This driver image handle will then be available through the
|
---|
1565 | GetDriver() service. This driver doesn't support this API.
|
---|
1566 |
|
---|
1567 | @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
|
---|
1568 | PROTOCOL instance.
|
---|
1569 | @param ControllerHandle The device handle of the controller.
|
---|
1570 | @param DriverImagePath A pointer to the driver device path that was returned in a prior
|
---|
1571 | call to GetDriverPath().
|
---|
1572 | @param DriverImageHandle The driver image handle that was returned by LoadImage()
|
---|
1573 | when the driver specified by DriverImagePath was loaded
|
---|
1574 | into memory.
|
---|
1575 |
|
---|
1576 | @retval EFI_UNSUPPORTED
|
---|
1577 | **/
|
---|
1578 | EFI_STATUS
|
---|
1579 | EFIAPI
|
---|
1580 | DriverLoaded (
|
---|
1581 | IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
|
---|
1582 | IN EFI_HANDLE ControllerHandle,
|
---|
1583 | IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath,
|
---|
1584 | IN EFI_HANDLE DriverImageHandle
|
---|
1585 | )
|
---|
1586 | {
|
---|
1587 | return EFI_UNSUPPORTED;
|
---|
1588 | }
|
---|
1589 |
|
---|
1590 | /**
|
---|
1591 | The driver Entry Point. The function will export a disk device class formset and
|
---|
1592 | its callback function to hii database.
|
---|
1593 |
|
---|
1594 | @param ImageHandle The firmware allocated handle for the EFI image.
|
---|
1595 | @param SystemTable A pointer to the EFI System Table.
|
---|
1596 |
|
---|
1597 | @retval EFI_SUCCESS The entry point is executed successfully.
|
---|
1598 | @retval other Some error occurs when executing this entry point.
|
---|
1599 |
|
---|
1600 | **/
|
---|
1601 | EFI_STATUS
|
---|
1602 | EFIAPI
|
---|
1603 | PlatDriOverrideDxeInit (
|
---|
1604 | IN EFI_HANDLE ImageHandle,
|
---|
1605 | IN EFI_SYSTEM_TABLE *SystemTable
|
---|
1606 | )
|
---|
1607 | {
|
---|
1608 | EFI_STATUS Status;
|
---|
1609 | EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
|
---|
1610 | VOID *Instance;
|
---|
1611 |
|
---|
1612 | //
|
---|
1613 | // There should only be one Form Configuration protocol
|
---|
1614 | //
|
---|
1615 | Status = gBS->LocateProtocol (
|
---|
1616 | &gEfiFormBrowser2ProtocolGuid,
|
---|
1617 | NULL,
|
---|
1618 | (VOID **)&FormBrowser2
|
---|
1619 | );
|
---|
1620 | if (EFI_ERROR (Status)) {
|
---|
1621 | return Status;
|
---|
1622 | }
|
---|
1623 |
|
---|
1624 | //
|
---|
1625 | // According to UEFI spec, there can be at most a single instance
|
---|
1626 | // in the system of the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
|
---|
1627 | // So here we check the existence.
|
---|
1628 | //
|
---|
1629 | Status = gBS->LocateProtocol (
|
---|
1630 | &gEfiPlatformDriverOverrideProtocolGuid,
|
---|
1631 | NULL,
|
---|
1632 | &Instance
|
---|
1633 | );
|
---|
1634 | //
|
---|
1635 | // If there was no error, assume there is an installation and return error
|
---|
1636 | //
|
---|
1637 | if (!EFI_ERROR (Status)) {
|
---|
1638 | return EFI_ALREADY_STARTED;
|
---|
1639 | }
|
---|
1640 |
|
---|
1641 | mCallerImageHandle = ImageHandle;
|
---|
1642 | mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));
|
---|
1643 | if (mCallbackInfo == NULL) {
|
---|
1644 | return EFI_BAD_BUFFER_SIZE;
|
---|
1645 | }
|
---|
1646 |
|
---|
1647 | mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
|
---|
1648 | mCallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;
|
---|
1649 | mCallbackInfo->ConfigAccess.RouteConfig = PlatOverMngrRouteConfig;
|
---|
1650 | mCallbackInfo->ConfigAccess.Callback = PlatOverMngrCallback;
|
---|
1651 | mCallbackInfo->PlatformDriverOverride.GetDriver = GetDriver;
|
---|
1652 | mCallbackInfo->PlatformDriverOverride.GetDriverPath = GetDriverPath;
|
---|
1653 | mCallbackInfo->PlatformDriverOverride.DriverLoaded = DriverLoaded;
|
---|
1654 |
|
---|
1655 | //
|
---|
1656 | // Locate ConfigRouting protocol
|
---|
1657 | //
|
---|
1658 | Status = gBS->LocateProtocol (
|
---|
1659 | &gEfiHiiConfigRoutingProtocolGuid,
|
---|
1660 | NULL,
|
---|
1661 | (VOID **)&mCallbackInfo->HiiConfigRouting
|
---|
1662 | );
|
---|
1663 | if (EFI_ERROR (Status)) {
|
---|
1664 | goto Finish;
|
---|
1665 | }
|
---|
1666 |
|
---|
1667 | //
|
---|
1668 | // Install Device Path Protocol and Config Access protocol to driver handle
|
---|
1669 | // Install Platform Driver Override Protocol to driver handle
|
---|
1670 | //
|
---|
1671 | Status = gBS->InstallMultipleProtocolInterfaces (
|
---|
1672 | &mCallbackInfo->DriverHandle,
|
---|
1673 | &gEfiDevicePathProtocolGuid,
|
---|
1674 | &mHiiVendorDevicePath,
|
---|
1675 | &gEfiHiiConfigAccessProtocolGuid,
|
---|
1676 | &mCallbackInfo->ConfigAccess,
|
---|
1677 | &gEfiPlatformDriverOverrideProtocolGuid,
|
---|
1678 | &mCallbackInfo->PlatformDriverOverride,
|
---|
1679 | NULL
|
---|
1680 | );
|
---|
1681 | if (EFI_ERROR (Status)) {
|
---|
1682 | goto Finish;
|
---|
1683 | }
|
---|
1684 |
|
---|
1685 | //
|
---|
1686 | // Publish our HII data
|
---|
1687 | //
|
---|
1688 | mCallbackInfo->RegisteredHandle = HiiAddPackages (
|
---|
1689 | &gPlatformOverridesManagerGuid,
|
---|
1690 | mCallbackInfo->DriverHandle,
|
---|
1691 | VfrBin,
|
---|
1692 | PlatDriOverrideDxeStrings,
|
---|
1693 | NULL
|
---|
1694 | );
|
---|
1695 | if (mCallbackInfo->RegisteredHandle == NULL) {
|
---|
1696 | Status = EFI_OUT_OF_RESOURCES;
|
---|
1697 | goto Finish;
|
---|
1698 | }
|
---|
1699 |
|
---|
1700 | //
|
---|
1701 | // Clear all the globle variable
|
---|
1702 | //
|
---|
1703 | mDriverImageHandleCount = 0;
|
---|
1704 | mCurrentPage = 0;
|
---|
1705 |
|
---|
1706 | return EFI_SUCCESS;
|
---|
1707 |
|
---|
1708 | Finish:
|
---|
1709 | PlatDriOverrideDxeUnload (ImageHandle);
|
---|
1710 |
|
---|
1711 | return Status;
|
---|
1712 | }
|
---|
1713 |
|
---|
1714 | /**
|
---|
1715 | Unload its installed protocol.
|
---|
1716 |
|
---|
1717 | @param[in] ImageHandle Handle that identifies the image to be unloaded.
|
---|
1718 |
|
---|
1719 | @retval EFI_SUCCESS The image has been unloaded.
|
---|
1720 | **/
|
---|
1721 | EFI_STATUS
|
---|
1722 | EFIAPI
|
---|
1723 | PlatDriOverrideDxeUnload (
|
---|
1724 | IN EFI_HANDLE ImageHandle
|
---|
1725 | )
|
---|
1726 | {
|
---|
1727 | ASSERT (mCallbackInfo != NULL);
|
---|
1728 |
|
---|
1729 | if (mCallbackInfo->DriverHandle != NULL) {
|
---|
1730 | gBS->UninstallMultipleProtocolInterfaces (
|
---|
1731 | mCallbackInfo->DriverHandle,
|
---|
1732 | &gEfiDevicePathProtocolGuid,
|
---|
1733 | &mHiiVendorDevicePath,
|
---|
1734 | &gEfiHiiConfigAccessProtocolGuid,
|
---|
1735 | &mCallbackInfo->ConfigAccess,
|
---|
1736 | &gEfiPlatformDriverOverrideProtocolGuid,
|
---|
1737 | &mCallbackInfo->PlatformDriverOverride,
|
---|
1738 | NULL
|
---|
1739 | );
|
---|
1740 | }
|
---|
1741 |
|
---|
1742 | if (mCallbackInfo->RegisteredHandle != NULL) {
|
---|
1743 | HiiRemovePackages (mCallbackInfo->RegisteredHandle);
|
---|
1744 | }
|
---|
1745 |
|
---|
1746 | FreePool (mCallbackInfo);
|
---|
1747 |
|
---|
1748 | if (mControllerToken != NULL) {
|
---|
1749 | FreePool (mControllerToken);
|
---|
1750 | }
|
---|
1751 |
|
---|
1752 | if (mControllerDevicePathProtocol != NULL) {
|
---|
1753 | FreePool (mControllerDevicePathProtocol);
|
---|
1754 | }
|
---|
1755 |
|
---|
1756 | if (mDriverImageToken != NULL) {
|
---|
1757 | FreePool (mDriverImageToken);
|
---|
1758 | }
|
---|
1759 |
|
---|
1760 | return EFI_SUCCESS;
|
---|
1761 | }
|
---|