]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/Opal/OpalPassword/OpalHii.c
SecurityPkg OpalPasswordPei: Go next when AhciModeInitialize is failed
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPassword / OpalHii.c
1 /** @file
2 Implementation of the HII for the Opal UEFI Driver.
3
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "OpalHii.h"
16
17 //
18 // This is the generated IFR binary Data for each formset defined in VFR.
19 // This Data array is ready to be used as input of HiiAddPackages() to
20 // create a packagelist (which contains Form packages, String packages, etc).
21 //
22 extern UINT8 OpalPasswordFormBin[];
23
24 //
25 // This is the generated String package Data for all .UNI files.
26 // This Data array is ready to be used as input of HiiAddPackages() to
27 // create a packagelist (which contains Form packages, String packages, etc).
28 //
29 extern UINT8 OpalPasswordDxeStrings[];
30
31 CHAR16 OpalPasswordStorageName[] = L"OpalHiiConfig";
32
33 EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;
34
35 //
36 // Handle to the list of HII packages (forms and strings) for this driver
37 //
38 EFI_HII_HANDLE gHiiPackageListHandle = NULL;
39
40 //
41 // Package List GUID containing all form and string packages
42 //
43 const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;
44 const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;
45
46 //
47 // Structure that contains state of the HII
48 // This structure is updated by Hii.cpp and its contents
49 // is rendered in the HII.
50 //
51 OPAL_HII_CONFIGURATION gHiiConfiguration;
52
53 //
54 // The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
55 //
56 HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {
57 {
58 {
59 HARDWARE_DEVICE_PATH,
60 HW_VENDOR_DP,
61 {
62 (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
63 (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)
64 }
65 },
66 OPAL_PASSWORD_CONFIG_GUID
67 },
68 {
69 END_DEVICE_PATH_TYPE,
70 END_ENTIRE_DEVICE_PATH_SUBTYPE,
71 {
72 (UINT8)(END_DEVICE_PATH_LENGTH),
73 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
74 }
75 }
76 };
77
78 /**
79 Get saved OPAL request.
80
81 @param[in] OpalDisk The disk needs to get the saved OPAL request.
82 @param[out] OpalRequest OPAL request got.
83
84 **/
85 VOID
86 GetSavedOpalRequest (
87 IN OPAL_DISK *OpalDisk,
88 OUT OPAL_REQUEST *OpalRequest
89 )
90 {
91 EFI_STATUS Status;
92 OPAL_REQUEST_VARIABLE *TempVariable;
93 OPAL_REQUEST_VARIABLE *Variable;
94 UINTN VariableSize;
95 EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;
96 UINTN DevicePathSizeInVariable;
97 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
98 UINTN DevicePathSize;
99
100 DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
101
102 Variable = NULL;
103 VariableSize = 0;
104
105 Status = GetVariable2 (
106 OPAL_REQUEST_VARIABLE_NAME,
107 &gHiiSetupVariableGuid,
108 (VOID **) &Variable,
109 &VariableSize
110 );
111 if (EFI_ERROR (Status) || (Variable == NULL)) {
112 return;
113 }
114
115 TempVariable = Variable;
116 while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
117 (VariableSize >= TempVariable->Length) &&
118 (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) {
119 DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
120 DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
121 DevicePath = OpalDisk->OpalDevicePath;
122 DevicePathSize = GetDevicePathSize (DevicePath);
123 if ((DevicePathSize == DevicePathSizeInVariable) &&
124 (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) {
125 //
126 // Found the node for the OPAL device.
127 // Get the OPAL request.
128 //
129 CopyMem (OpalRequest, &TempVariable->OpalRequest, sizeof (OPAL_REQUEST));
130 DEBUG ((
131 DEBUG_INFO,
132 "OpalRequest got: 0x%x\n",
133 *OpalRequest
134 ));
135 break;
136 }
137 VariableSize -= TempVariable->Length;
138 TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length);
139 }
140
141 FreePool (Variable);
142
143 DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
144 }
145
146 /**
147 Save OPAL request.
148
149 @param[in] OpalDisk The disk has OPAL request to save.
150 @param[in] OpalRequest OPAL request to save.
151
152 **/
153 VOID
154 SaveOpalRequest (
155 IN OPAL_DISK *OpalDisk,
156 IN OPAL_REQUEST OpalRequest
157 )
158 {
159 EFI_STATUS Status;
160 OPAL_REQUEST_VARIABLE *TempVariable;
161 UINTN TempVariableSize;
162 OPAL_REQUEST_VARIABLE *Variable;
163 UINTN VariableSize;
164 OPAL_REQUEST_VARIABLE *NewVariable;
165 UINTN NewVariableSize;
166 EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable;
167 UINTN DevicePathSizeInVariable;
168 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
169 UINTN DevicePathSize;
170
171 DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__));
172
173 DEBUG ((
174 DEBUG_INFO,
175 "OpalRequest to save: 0x%x\n",
176 OpalRequest
177 ));
178
179 Variable = NULL;
180 VariableSize = 0;
181 NewVariable = NULL;
182 NewVariableSize = 0;
183
184 Status = GetVariable2 (
185 OPAL_REQUEST_VARIABLE_NAME,
186 &gHiiSetupVariableGuid,
187 (VOID **) &Variable,
188 &VariableSize
189 );
190 if (!EFI_ERROR (Status) && (Variable != NULL)) {
191 TempVariable = Variable;
192 TempVariableSize = VariableSize;
193 while ((TempVariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
194 (TempVariableSize >= TempVariable->Length) &&
195 (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) {
196 DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
197 DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
198 DevicePath = OpalDisk->OpalDevicePath;
199 DevicePathSize = GetDevicePathSize (DevicePath);
200 if ((DevicePathSize == DevicePathSizeInVariable) &&
201 (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) {
202 //
203 // Found the node for the OPAL device.
204 // Update the OPAL request.
205 //
206 CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
207 NewVariable = Variable;
208 NewVariableSize = VariableSize;
209 break;
210 }
211 TempVariableSize -= TempVariable->Length;
212 TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length);
213 }
214 if (NewVariable == NULL) {
215 //
216 // The node for the OPAL device is not found.
217 // Create node for the OPAL device.
218 //
219 DevicePath = OpalDisk->OpalDevicePath;
220 DevicePathSize = GetDevicePathSize (DevicePath);
221 NewVariableSize = VariableSize + sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize;
222 NewVariable = AllocatePool (NewVariableSize);
223 ASSERT (NewVariable != NULL);
224 CopyMem (NewVariable, Variable, VariableSize);
225 TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) NewVariable + VariableSize);
226 TempVariable->Length = (UINT32) (sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize);
227 CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
228 DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
229 CopyMem (DevicePathInVariable, DevicePath, DevicePathSize);
230 }
231 } else {
232 DevicePath = OpalDisk->OpalDevicePath;
233 DevicePathSize = GetDevicePathSize (DevicePath);
234 NewVariableSize = sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize;
235 NewVariable = AllocatePool (NewVariableSize);
236 ASSERT (NewVariable != NULL);
237 NewVariable->Length = (UINT32) (sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize);
238 CopyMem (&NewVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
239 DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) NewVariable + sizeof (OPAL_REQUEST_VARIABLE));
240 CopyMem (DevicePathInVariable, DevicePath, DevicePathSize);
241 }
242 Status = gRT->SetVariable (
243 OPAL_REQUEST_VARIABLE_NAME,
244 (EFI_GUID *) &gHiiSetupVariableGuid,
245 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
246 NewVariableSize,
247 NewVariable
248 );
249 if (EFI_ERROR (Status)) {
250 DEBUG ((DEBUG_INFO, "OpalRequest variable set failed (%r)\n", Status));
251 }
252 if (NewVariable != Variable) {
253 FreePool (NewVariable);
254 }
255 if (Variable != NULL) {
256 FreePool (Variable);
257 }
258
259 DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__));
260 }
261
262 /**
263 Sets the current system state of global config variables.
264
265 **/
266 VOID
267 HiiSetCurrentConfiguration(
268 VOID
269 )
270 {
271 UINT32 PpStorageFlag;
272 EFI_STRING NewString;
273
274 gHiiConfiguration.NumDisks = GetDeviceCount();
275
276 //
277 // Update the BlockSID status string.
278 //
279 PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();
280
281 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
282 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_ENABLED), NULL);
283 if (NewString == NULL) {
284 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
285 return;
286 }
287 } else {
288 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISABLED), NULL);
289 if (NewString == NULL) {
290 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
291 return;
292 }
293 }
294 HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS1), NewString, NULL);
295 FreePool (NewString);
296
297 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) {
298 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL);
299 if (NewString == NULL) {
300 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
301 return;
302 }
303 } else {
304 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL);
305 if (NewString == NULL) {
306 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
307 return;
308 }
309 }
310 HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS2), NewString, NULL);
311 FreePool (NewString);
312
313 if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) {
314 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL);
315 if (NewString == NULL) {
316 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
317 return;
318 }
319 } else {
320 NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL);
321 if (NewString == NULL) {
322 DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
323 return;
324 }
325 }
326 HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS3), NewString, NULL);
327 FreePool (NewString);
328 }
329
330 /**
331 Install the HII related resources.
332
333 @retval EFI_SUCCESS Install all the resources success.
334 @retval other Error occur when install the resources.
335 **/
336 EFI_STATUS
337 HiiInstall(
338 VOID
339 )
340 {
341 EFI_STATUS Status;
342 EFI_HANDLE DriverHandle;
343
344 //
345 // Clear the global configuration.
346 //
347 ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));
348
349 //
350 // Obtain the driver handle that the BIOS assigned us
351 //
352 DriverHandle = HiiGetDriverImageHandleCB();
353
354 //
355 // Populate the config access protocol with the three functions we are publishing
356 //
357 gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;
358 gHiiConfigAccessProtocol.RouteConfig = RouteConfig;
359 gHiiConfigAccessProtocol.Callback = DriverCallback;
360
361 //
362 // Associate the required protocols with our driver handle
363 //
364 Status = gBS->InstallMultipleProtocolInterfaces(
365 &DriverHandle,
366 &gEfiHiiConfigAccessProtocolGuid,
367 &gHiiConfigAccessProtocol, // HII callback
368 &gEfiDevicePathProtocolGuid,
369 &gHiiVendorDevicePath, // required for HII callback allow all disks to be shown in same hii
370 NULL
371 );
372
373 if (EFI_ERROR(Status)) {
374 return Status;
375 }
376
377 return OpalHiiAddPackages();
378 }
379
380 /**
381 Install the HII form and string packages.
382
383 @retval EFI_SUCCESS Install all the resources success.
384 @retval EFI_OUT_OF_RESOURCES Out of resource error.
385 **/
386 EFI_STATUS
387 OpalHiiAddPackages(
388 VOID
389 )
390 {
391 EFI_HANDLE DriverHandle;
392 CHAR16 *NewString;
393
394 DriverHandle = HiiGetDriverImageHandleCB();
395
396 //
397 // Publish the HII form and HII string packages
398 //
399 gHiiPackageListHandle = HiiAddPackages(
400 &gHiiPackageListGuid,
401 DriverHandle,
402 OpalPasswordDxeStrings,
403 OpalPasswordFormBin,
404 (VOID*)NULL
405 );
406
407 //
408 // Make sure the packages installed successfully
409 //
410 if (gHiiPackageListHandle == NULL) {
411 DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));
412 return EFI_OUT_OF_RESOURCES;
413 }
414
415 //
416 // Update Version String in main window
417 //
418 NewString = HiiGetDriverNameCB ();
419 if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {
420 DEBUG ((DEBUG_INFO, "OpalHiiAddPackages: HiiSetString( ) failed\n"));
421 return EFI_OUT_OF_RESOURCES;
422 }
423
424 return EFI_SUCCESS;
425 }
426
427 /**
428 Uninstall the HII capability.
429
430 @retval EFI_SUCCESS Uninstall all the resources success.
431 @retval others Other errors occur when unistall the hii resource.
432 **/
433 EFI_STATUS
434 HiiUninstall(
435 VOID
436 )
437 {
438 EFI_STATUS Status;
439
440 //
441 // Remove the packages we've provided to the BIOS
442 //
443 HiiRemovePackages(gHiiPackageListHandle);
444
445 //
446 // Remove the protocols from our driver handle
447 //
448 Status = gBS->UninstallMultipleProtocolInterfaces(
449 HiiGetDriverImageHandleCB(),
450 &gEfiHiiConfigAccessProtocolGuid,
451 &gHiiConfigAccessProtocol, // HII callback
452 &gEfiDevicePathProtocolGuid,
453 &gHiiVendorDevicePath, // required for HII callback
454 NULL
455 );
456 if (EFI_ERROR(Status)) {
457 DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));
458 }
459
460 return Status;
461 }
462
463 /**
464 Updates the main menu form.
465
466 @retval EFI_SUCCESS update the main form success.
467 **/
468 EFI_STATUS
469 HiiPopulateMainMenuForm (
470 VOID
471 )
472 {
473 UINT8 Index;
474 CHAR8 *DiskName;
475 EFI_STRING_ID DiskNameId;
476 OPAL_DISK *OpalDisk;
477
478 HiiSetCurrentConfiguration();
479
480 gHiiConfiguration.SupportedDisks = 0;
481
482 for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {
483 OpalDisk = HiiGetOpalDiskCB (Index);
484 if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {
485 gHiiConfiguration.SupportedDisks |= (1 << Index);
486 DiskNameId = GetDiskNameStringId (Index);
487 DiskName = HiiDiskGetNameCB (Index);
488 if ((DiskName == NULL) || (DiskNameId == 0)) {
489 return EFI_UNSUPPORTED;
490 }
491 HiiSetFormString(DiskNameId, DiskName);
492 }
493 }
494
495 OpalHiiSetBrowserData ();
496 return EFI_SUCCESS;
497 }
498
499 /**
500 Get disk name string id.
501
502 @param DiskIndex The input disk index info.
503
504 @retval The disk name string id.
505
506 **/
507 EFI_STRING_ID
508 GetDiskNameStringId(
509 UINT8 DiskIndex
510 )
511 {
512 switch (DiskIndex) {
513 case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);
514 case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);
515 case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);
516 case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);
517 case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);
518 case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);
519 }
520 return 0;
521 }
522
523 /**
524 This function processes the results of changes in configuration.
525
526 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
527 @param Action Specifies the type of action taken by the browser.
528 @param QuestionId A unique value which is sent to the original
529 exporting driver so that it can identify the type
530 of data to expect.
531 @param Type The type of value for the question.
532 @param Value A pointer to the data being sent to the original
533 exporting driver.
534 @param ActionRequest On return, points to the action requested by the
535 callback function.
536
537 @retval EFI_SUCCESS The callback successfully handled the action.
538 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
539 variable and its data.
540 @retval EFI_DEVICE_ERROR The variable could not be saved.
541 @retval EFI_UNSUPPORTED The specified Action is not supported by the
542 callback.
543
544 **/
545 EFI_STATUS
546 EFIAPI
547 DriverCallback(
548 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
549 EFI_BROWSER_ACTION Action,
550 EFI_QUESTION_ID QuestionId,
551 UINT8 Type,
552 EFI_IFR_TYPE_VALUE *Value,
553 EFI_BROWSER_ACTION_REQUEST *ActionRequest
554 )
555 {
556 HII_KEY HiiKey;
557 UINT8 HiiKeyId;
558 UINT32 PpRequest;
559 OPAL_DISK *OpalDisk;
560
561 if (ActionRequest != NULL) {
562 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
563 } else {
564 return EFI_INVALID_PARAMETER;
565 }
566
567 //
568 // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
569 //
570 if ((QuestionId & HII_KEY_FLAG) == 0) {
571 return EFI_SUCCESS;
572 }
573
574 HiiKey.Raw = QuestionId;
575 HiiKeyId = (UINT8) HiiKey.KeyBits.Id;
576
577 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
578 switch (HiiKeyId) {
579 case HII_KEY_ID_VAR_SUPPORTED_DISKS:
580 DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
581 return HiiPopulateMainMenuForm ();
582
583 case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
584 DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS\n"));
585 return HiiPopulateDiskInfoForm();
586 }
587 } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
588 switch (HiiKeyId) {
589 case HII_KEY_ID_GOTO_DISK_INFO:
590 return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);
591 }
592 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
593 switch (HiiKeyId) {
594 case HII_KEY_ID_BLOCKSID:
595 switch (Value->u8) {
596 case 0:
597 PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
598 break;
599
600 case 1:
601 PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID;
602 break;
603
604 case 2:
605 PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID;
606 break;
607
608 case 3:
609 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE;
610 break;
611
612 case 4:
613 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE;
614 break;
615
616 case 5:
617 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE;
618 break;
619
620 case 6:
621 PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE;
622 break;
623
624 default:
625 PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
626 DEBUG ((DEBUG_ERROR, "Invalid value input!\n"));
627 break;
628 }
629 HiiSetBlockSidAction(PpRequest);
630
631 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
632 return EFI_SUCCESS;
633
634 case HII_KEY_ID_SET_ADMIN_PWD:
635 DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_ADMIN_PWD\n"));
636 gHiiConfiguration.OpalRequest.SetAdminPwd = Value->b;
637 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
638 if (OpalDisk != NULL) {
639 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
640 }
641 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
642 return EFI_SUCCESS;
643
644 case HII_KEY_ID_SET_USER_PWD:
645 DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_USER_PWD\n"));
646 gHiiConfiguration.OpalRequest.SetUserPwd = Value->b;
647 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
648 if (OpalDisk != NULL) {
649 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
650 }
651 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
652 return EFI_SUCCESS;
653
654 case HII_KEY_ID_SECURE_ERASE:
655 DEBUG ((DEBUG_INFO, "HII_KEY_ID_SECURE_ERASE\n"));
656 gHiiConfiguration.OpalRequest.SecureErase = Value->b;
657 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
658 if (OpalDisk != NULL) {
659 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
660 }
661 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
662 return EFI_SUCCESS;
663
664 case HII_KEY_ID_REVERT:
665 DEBUG ((DEBUG_INFO, "HII_KEY_ID_REVERT\n"));
666 gHiiConfiguration.OpalRequest.Revert = Value->b;
667 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
668 if (OpalDisk != NULL) {
669 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
670 }
671 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
672 return EFI_SUCCESS;
673 case HII_KEY_ID_KEEP_USER_DATA:
674 DEBUG ((DEBUG_INFO, "HII_KEY_ID_KEEP_USER_DATA\n"));
675 gHiiConfiguration.OpalRequest.KeepUserData = Value->b;
676 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
677 if (OpalDisk != NULL) {
678 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
679 }
680 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
681 return EFI_SUCCESS;
682
683 case HII_KEY_ID_PSID_REVERT:
684 DEBUG ((DEBUG_INFO, "HII_KEY_ID_PSID_REVERT\n"));
685 gHiiConfiguration.OpalRequest.PsidRevert = Value->b;
686 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
687 if (OpalDisk != NULL) {
688 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
689 }
690 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
691 return EFI_SUCCESS;
692
693 case HII_KEY_ID_DISABLE_USER:
694 DEBUG ((DEBUG_INFO, "HII_KEY_ID_DISABLE_USER\n"));
695 gHiiConfiguration.OpalRequest.DisableUser = Value->b;
696 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
697 if (OpalDisk != NULL) {
698 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
699 }
700 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
701 return EFI_SUCCESS;
702
703 case HII_KEY_ID_ENABLE_FEATURE:
704 DEBUG ((DEBUG_INFO, "HII_KEY_ID_ENABLE_FEATURE\n"));
705 gHiiConfiguration.OpalRequest.EnableFeature = Value->b;
706 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
707 if (OpalDisk != NULL) {
708 SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
709 }
710 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
711 return EFI_SUCCESS;
712
713 default:
714 break;
715 }
716 }
717
718 return EFI_UNSUPPORTED;
719 }
720
721 /**
722 Update the global Disk index info.
723
724 @param Index The input disk index info.
725
726 @retval EFI_SUCCESS Update the disk index info success.
727
728 **/
729 EFI_STATUS
730 HiiSelectDisk(
731 UINT8 Index
732 )
733 {
734 OpalHiiGetBrowserData();
735 gHiiConfiguration.SelectedDiskIndex = Index;
736 OpalHiiSetBrowserData ();
737
738 return EFI_SUCCESS;
739 }
740
741 /**
742 Draws the disk info form.
743
744 @retval EFI_SUCCESS Draw the disk info success.
745
746 **/
747 EFI_STATUS
748 HiiPopulateDiskInfoForm(
749 VOID
750 )
751 {
752 OPAL_DISK* OpalDisk;
753 OPAL_DISK_ACTIONS AvailActions;
754 TCG_RESULT Ret;
755 CHAR8 *DiskName;
756
757 OpalHiiGetBrowserData();
758
759 DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);
760 if (DiskName == NULL) {
761 return EFI_UNSUPPORTED;
762 }
763 HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);
764
765 gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;
766 ZeroMem (&gHiiConfiguration.OpalRequest, sizeof (OPAL_REQUEST));
767 gHiiConfiguration.KeepUserDataForced = FALSE;
768
769 OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
770
771 if (OpalDisk != NULL) {
772 OpalDiskUpdateStatus (OpalDisk);
773 Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);
774 if (Ret == TcgResultSuccess) {
775 //
776 // Update actions, always allow PSID Revert
777 //
778 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;
779
780 //
781 // Always allow unlock to handle device migration
782 //
783 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;
784
785 if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {
786 if (OpalDisk->Owner == OpalOwnershipNobody) {
787 gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;
788
789 //
790 // Update strings
791 //
792 HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");
793 } else {
794 DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));
795 }
796 } else {
797 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;
798 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;
799 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;
800 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;
801 gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;
802
803 HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");
804
805 //
806 // Determine revert options for disk
807 // Default initialize keep user Data to be true
808 //
809 gHiiConfiguration.OpalRequest.KeepUserData = 1;
810 if (AvailActions.RevertKeepDataForced) {
811 gHiiConfiguration.KeepUserDataForced = TRUE;
812 }
813 }
814 }
815
816 GetSavedOpalRequest (OpalDisk, &gHiiConfiguration.OpalRequest);
817 }
818
819 //
820 // Pass the current configuration to the BIOS
821 //
822 OpalHiiSetBrowserData ();
823
824 return EFI_SUCCESS;
825 }
826
827 /**
828 Send BlockSid request through TPM physical presence module.
829
830 @param PpRequest TPM physical presence operation request.
831
832 @retval EFI_SUCCESS Do the required action success.
833 @retval Others Other error occur.
834
835 **/
836 EFI_STATUS
837 HiiSetBlockSidAction (
838 IN UINT32 PpRequest
839 )
840 {
841 UINT32 ReturnCode;
842 EFI_STATUS Status;
843
844 ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);
845 if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
846 Status = EFI_SUCCESS;
847 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
848 Status = EFI_OUT_OF_RESOURCES;
849 } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
850 Status = EFI_UNSUPPORTED;
851 } else {
852 Status = EFI_DEVICE_ERROR;
853 }
854
855 return Status;
856 }
857
858 /**
859 This function processes the results of changes in configuration.
860
861 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
862 @param Configuration A null-terminated Unicode string in <ConfigResp>
863 format.
864 @param Progress A pointer to a string filled in with the offset of
865 the most recent '&' before the first failing
866 name/value pair (or the beginning of the string if
867 the failure is in the first name/value pair) or
868 the terminating NULL if all was successful.
869
870 @retval EFI_SUCCESS The Results is processed successfully.
871 @retval EFI_INVALID_PARAMETER Configuration is NULL.
872 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
873 driver.
874
875 **/
876 EFI_STATUS
877 EFIAPI
878 RouteConfig(
879 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
880 CONST EFI_STRING Configuration,
881 EFI_STRING *Progress
882 )
883 {
884 if (Configuration == NULL || Progress == NULL) {
885 return (EFI_INVALID_PARAMETER);
886 }
887
888 *Progress = Configuration;
889 if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
890 return EFI_NOT_FOUND;
891 }
892
893 *Progress = Configuration + StrLen (Configuration);
894
895 return EFI_SUCCESS;
896 }
897
898 /**
899 This function allows a caller to extract the current configuration for one
900 or more named elements from the target driver.
901
902 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
903 @param Request A null-terminated Unicode string in
904 <ConfigRequest> format.
905 @param Progress On return, points to a character in the Request
906 string. Points to the string's null terminator if
907 request was successful. Points to the most recent
908 '&' before the first failing name/value pair (or
909 the beginning of the string if the failure is in
910 the first name/value pair) if the request was not
911 successful.
912 @param Results A null-terminated Unicode string in
913 <ConfigAltResp> format which has all values filled
914 in for the names in the Request string. String to
915 be allocated by the called function.
916
917 @retval EFI_SUCCESS The Results is filled with the requested values.
918 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
919 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
920 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
921 driver.
922
923 **/
924 EFI_STATUS
925 EFIAPI
926 ExtractConfig(
927 CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
928 CONST EFI_STRING Request,
929 EFI_STRING *Progress,
930 EFI_STRING *Results
931 )
932 {
933 EFI_STATUS Status;
934 EFI_STRING ConfigRequest;
935 EFI_STRING ConfigRequestHdr;
936 UINTN BufferSize;
937 UINTN Size;
938 BOOLEAN AllocatedRequest;
939 EFI_HANDLE DriverHandle;
940
941 //
942 // Check for valid parameters
943 //
944 if (Progress == NULL || Results == NULL) {
945 return (EFI_INVALID_PARAMETER);
946 }
947
948 *Progress = Request;
949 if ((Request != NULL) &&
950 !HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
951 return EFI_NOT_FOUND;
952 }
953
954 AllocatedRequest = FALSE;
955 BufferSize = sizeof (OPAL_HII_CONFIGURATION);
956 ConfigRequest = Request;
957 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
958 //
959 // Request has no request element, construct full request string.
960 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
961 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
962 //
963 DriverHandle = HiiGetDriverImageHandleCB();
964 ConfigRequestHdr = HiiConstructConfigHdr (&gHiiSetupVariableGuid, OpalPasswordStorageName, DriverHandle);
965 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
966 ConfigRequest = AllocateZeroPool (Size);
967 if (ConfigRequest == NULL) {
968 return EFI_OUT_OF_RESOURCES;
969 }
970 AllocatedRequest = TRUE;
971 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
972 FreePool (ConfigRequestHdr);
973 }
974
975 //
976 // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
977 //
978 Status = gHiiConfigRouting->BlockToConfig(
979 gHiiConfigRouting,
980 ConfigRequest,
981 (UINT8*)&gHiiConfiguration,
982 sizeof(OPAL_HII_CONFIGURATION),
983 Results,
984 Progress
985 );
986
987 //
988 // Free the allocated config request string.
989 //
990 if (AllocatedRequest) {
991 FreePool (ConfigRequest);
992 ConfigRequest = NULL;
993 }
994
995 //
996 // Set Progress string to the original request string.
997 //
998 if (Request == NULL) {
999 *Progress = NULL;
1000 } else if (StrStr (Request, L"OFFSET") == NULL) {
1001 *Progress = Request + StrLen (Request);
1002 }
1003
1004 return (Status);
1005 }
1006
1007
1008 /**
1009
1010 Pass the current system state to the bios via the hii_G_Configuration.
1011
1012 **/
1013 VOID
1014 OpalHiiSetBrowserData (
1015 VOID
1016 )
1017 {
1018 HiiSetBrowserData(
1019 &gHiiSetupVariableGuid,
1020 (CHAR16*)L"OpalHiiConfig",
1021 sizeof(gHiiConfiguration),
1022 (UINT8*)&gHiiConfiguration,
1023 NULL
1024 );
1025 }
1026
1027
1028 /**
1029
1030 Populate the hii_g_Configuraton with the browser Data.
1031
1032 **/
1033 VOID
1034 OpalHiiGetBrowserData (
1035 VOID
1036 )
1037 {
1038 HiiGetBrowserData(
1039 &gHiiSetupVariableGuid,
1040 (CHAR16*)L"OpalHiiConfig",
1041 sizeof(gHiiConfiguration),
1042 (UINT8*)&gHiiConfiguration
1043 );
1044 }
1045
1046 /**
1047 Set a string Value in a form.
1048
1049 @param DestStringId The stringid which need to update.
1050 @param SrcAsciiStr The string nned to update.
1051
1052 @retval EFI_SUCCESS Do the required action success.
1053 @retval Others Other error occur.
1054
1055 **/
1056 EFI_STATUS
1057 HiiSetFormString(
1058 EFI_STRING_ID DestStringId,
1059 CHAR8 *SrcAsciiStr
1060 )
1061 {
1062 UINT32 Len;
1063 UINT32 UniSize;
1064 CHAR16* UniStr;
1065
1066 //
1067 // Determine the Length of the sting
1068 //
1069 Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );
1070
1071 //
1072 // Allocate space for the unicode string, including terminator
1073 //
1074 UniSize = (Len + 1) * sizeof(CHAR16);
1075 UniStr = (CHAR16*)AllocateZeroPool(UniSize);
1076
1077 //
1078 // Copy into unicode string, then copy into string id
1079 //
1080 AsciiStrToUnicodeStrS ( SrcAsciiStr, UniStr, Len + 1);
1081
1082 //
1083 // Update the string in the form
1084 //
1085 if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {
1086 DEBUG ((DEBUG_INFO, "HiiSetFormString( ) failed\n"));
1087 FreePool(UniStr);
1088 return (EFI_OUT_OF_RESOURCES);
1089 }
1090
1091 //
1092 // Free the memory
1093 //
1094 FreePool(UniStr);
1095
1096 return (EFI_SUCCESS);
1097 }
1098
1099 /**
1100 Initialize the Opal disk base on the hardware info get from device.
1101
1102 @param Dev The Opal device.
1103
1104 @retval EFI_SUCESS Initialize the device success.
1105 @retval EFI_DEVICE_ERROR Get info from device failed.
1106
1107 **/
1108 EFI_STATUS
1109 OpalDiskInitialize (
1110 IN OPAL_DRIVER_DEVICE *Dev
1111 )
1112 {
1113 TCG_RESULT TcgResult;
1114 OPAL_SESSION Session;
1115
1116 ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));
1117 Dev->OpalDisk.Sscp = Dev->Sscp;
1118 Dev->OpalDisk.MediaId = Dev->MediaId;
1119 Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;
1120
1121 ZeroMem(&Session, sizeof(Session));
1122 Session.Sscp = Dev->Sscp;
1123 Session.MediaId = Dev->MediaId;
1124
1125 TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);
1126 if (TcgResult != TcgResultSuccess) {
1127 return EFI_DEVICE_ERROR;
1128 }
1129 Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
1130
1131 TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);
1132 if (TcgResult != TcgResultSuccess) {
1133 return EFI_DEVICE_ERROR;
1134 }
1135
1136 return OpalDiskUpdateStatus (&Dev->OpalDisk);
1137 }
1138
1139 /**
1140 Update the device info.
1141
1142 @param OpalDisk The Opal device.
1143
1144 @retval EFI_SUCESS Initialize the device success.
1145 @retval EFI_DEVICE_ERROR Get info from device failed.
1146 @retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.
1147
1148 **/
1149 EFI_STATUS
1150 OpalDiskUpdateStatus (
1151 OPAL_DISK *OpalDisk
1152 )
1153 {
1154 TCG_RESULT TcgResult;
1155 OPAL_SESSION Session;
1156
1157 ZeroMem(&Session, sizeof(Session));
1158 Session.Sscp = OpalDisk->Sscp;
1159 Session.MediaId = OpalDisk->MediaId;
1160 Session.OpalBaseComId = OpalDisk->OpalBaseComId;
1161
1162 TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);
1163 if (TcgResult != TcgResultSuccess) {
1164 return EFI_DEVICE_ERROR;
1165 }
1166
1167 if (OpalDisk->MsidLength == 0) {
1168 return EFI_INVALID_PARAMETER;
1169 } else {
1170 //
1171 // Base on the Msid info to get the ownership, so Msid info must get first.
1172 //
1173 OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);
1174 }
1175
1176 return EFI_SUCCESS;
1177 }
1178